Sfoglia il codice sorgente

Merge branch 'master' of http://49.4.53.36:3000/hotel/hotel-saas-tenant-frontend

qh 2 anni fa
parent
commit
fb8528b71a
33 ha cambiato i file con 3940 aggiunte e 105 eliminazioni
  1. 13 0
      src/api/good.js
  2. 37 14
      src/api/roomBuildingApi.js
  3. 14 5
      src/views/markets/mealcouponsverify.vue
  4. 15 6
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsForm.vue
  5. 20 12
      src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleConfirm.vue
  6. 1 1
      src/views/markets/modules/meetingRoomScheduleOrder/BusMeetingRoomScheduleEditForm.vue
  7. 993 0
      src/views/room/fangtailive.vue
  8. 137 0
      src/views/room/modules/upkeep/UpkeepRoomForm.vue
  9. 60 0
      src/views/room/modules/upkeep/UpkeepRoomModal.vue
  10. 246 0
      src/views/settings/components/doorLockList.vue
  11. 140 0
      src/views/settings/components/modules/doorLockBatchForm.vue
  12. 61 0
      src/views/settings/components/modules/doorLockBatchModal.vue
  13. 220 0
      src/views/settings/components/modules/doorLockForm.vue
  14. 84 0
      src/views/settings/components/modules/doorLockModal.Style#Drawer.vue
  15. 60 0
      src/views/settings/components/modules/doorLockModal.vue
  16. 138 0
      src/views/settings/components/modules/orderSoundForm.vue
  17. 84 0
      src/views/settings/components/modules/orderSoundModal.Style#Drawer.vue
  18. 60 0
      src/views/settings/components/modules/orderSoundModal.vue
  19. 209 0
      src/views/settings/components/orderSoundList.vue
  20. 15 10
      src/views/settings/components/roomModules/goodList.vue
  21. 234 0
      src/views/settings/components/roomModules/mealCouponList.vue
  22. 179 0
      src/views/settings/components/roomModules/modules/mealCouponForm.vue
  23. 84 0
      src/views/settings/components/roomModules/modules/mealCouponModal.Style#Drawer.vue
  24. 60 0
      src/views/settings/components/roomModules/modules/mealCouponModal.vue
  25. 24 13
      src/views/settings/components/roomModules/moreSet/commodity.vue
  26. 133 0
      src/views/settings/components/roomModules/moreSet/foodSet.vue
  27. 163 37
      src/views/settings/components/roomModules/moreSet/goodImg.vue
  28. 101 0
      src/views/settings/components/roomModules/moreSet/materialTable.vue
  29. 107 0
      src/views/settings/components/roomModules/moreSet/moreModal.vue
  30. 111 0
      src/views/settings/components/roomModules/moreSet/tastaTable.vue
  31. 39 0
      src/views/settings/components/roomModules/roomLayoutDetailForm/roomLayoutImage.vue
  32. 35 2
      src/views/settings/roomSettings.vue
  33. 63 5
      src/views/settings/systemInfo.vue

+ 13 - 0
src/api/good.js

@@ -119,6 +119,19 @@ export function goodBatchDel(parameter){
 }
 
 /**
+ * 修改商品
+ * @param {*} parameter 
+ * @returns 
+ */
+export function editGood(parameter){
+    return axios({
+        url:'/rooms/cesGoods/modify',
+        method:'put',
+        data:parameter
+    })
+}
+
+/**
  * 进退货
  * @param {*} parameter 
  * @returns 

+ 37 - 14
src/api/roomBuildingApi.js

@@ -42,7 +42,7 @@ export function save(parameter) {
 
 /**
  * 获取楼栋楼层树
- * @param {Object} param 
+ * @param {Object} param
  * @returns Axios Promise
  */
 export function buildingTree (param) {
@@ -54,10 +54,10 @@ export function buildingTree (param) {
 }
 /**
  * 批量添加房间
- * @param {Object} param 
- * @returns 
+ * @param {Object} param
+ * @returns
  */
-export function saveBatch(param) { 
+export function saveBatch(param) {
     return axios({
         url: '/rooms/cesRooms/saveBatchRoom',
         method: 'post',
@@ -68,10 +68,10 @@ export function saveBatch(param) {
 
  /**
  * 批量删除房间
- * @param {Object} param 
- * @returns 
+ * @param {Object} param
+ * @returns
  */
-export function delBatch(param) { 
+export function delBatch(param) {
     return axios({
         url: '/rooms/cesRooms/delete',
         method: 'delete',
@@ -81,10 +81,10 @@ export function delBatch(param) {
 
   /**
  * 删除所有
- * @param {Object} param 
- * @returns 
+ * @param {Object} param
+ * @returns
  */
-export function delAll(param) { 
+export function delAll(param) {
     return axios({
         url: '/rooms/cesRooms/removeAll',
         method: 'delete',
@@ -94,15 +94,38 @@ export function delAll(param) {
 
    /**
  * 编辑房间
- * @param {Object} param 
- * @returns 
+ * @param {Object} param
+ * @returns
  */
-export function roomEdit(param) { 
+export function roomEdit(param) {
     return axios({
         url: '/rooms/cesRooms/modify',
         method: 'put',
         data: param
     })
  }
+/**
+ * 通过上级Id获取楼栋楼层
+ * @param {Object} param
+ * @returns Axios Promise
+ */
+export function queryFloorByParentId (param) {
+    return axios({
+        url: '/rooms/cesRoomBuildingFloor/queryByParentId',
+        method: 'get',
+        params: param
+    })
+}
 
- 
+/**
+ * 通过楼层获取房间列表
+ * @param {Object} param
+ * @returns
+ */
+export function queryRoomByFloorId(param) {
+    return axios({
+        url: '/rooms/cesRooms/queryByFloorId',
+        method: 'get',
+        params: param
+    })
+}

+ 14 - 5
src/views/markets/mealcouponsverify.vue

@@ -5,9 +5,9 @@
         <span slot="tab"> 全部 </span>
         <!-- <member-list></member-list> -->
       </a-tab-pane>
-      <a-tab-pane v-for="(item, index) in mealCouponTypeList" :key="item.value">
+      <a-tab-pane v-for="(item, index) in mealCouponTypeList" :key="item.id">
         <span slot="tab">
-          {{ item.label }}
+          {{ item.name }}
         </span>
         <!-- <market-recharge-list></market-recharge-list> -->
       </a-tab-pane>
@@ -191,10 +191,19 @@ export default {
     };
   },
   created() {
+    // httpAction(
+    //   "/rooms/cesMealCoupon/fetch",
+    //   { hotelId: hotelInfo.id },
+    //   "get"
+    // ).then((res) => {
+    //   if (res.success) {
+    //     this.mealCouponTypeList = res.result;
+    //   }
+    // });
     httpAction(
-      "/rooms/cesMealCoupon/fetch",
-      { hotelId: hotelInfo.id },
-      "get"
+            "/business/busMealCoupon/queryList",
+            { },
+            "get"
     ).then((res) => {
       if (res.success) {
         this.mealCouponTypeList = res.result;

+ 15 - 6
src/views/markets/modules/mealCoupons/BusMarketMealCouponsForm.vue

@@ -34,8 +34,8 @@
                 <a-select-option
                   v-for="(item, index) in mealCouponTypeList"
                   :key="index"
-                  :value="item.value"
-                  >{{ item.label }}</a-select-option
+                  :value="item.id"
+                  >{{ item.name }}</a-select-option
                 >
               </a-select>
             </a-form-model-item>
@@ -157,10 +157,19 @@ export default {
         this.stockTypeList = res.result;
       }
     });
+    // httpAction(
+    //   "/rooms/cesMealCoupon/fetch",
+    //   { hotelId: hotelInfo.id },
+    //   "get"
+    // ).then((res) => {
+    //   if (res.success) {
+    //     this.mealCouponTypeList = res.result;
+    //   }
+    // });
     httpAction(
-      "/rooms/cesMealCoupon/fetch",
-      { hotelId: hotelInfo.id },
-      "get"
+            "/business/busMealCoupon/queryList",
+            { hotelId: hotelInfo.id },
+            "get"
     ).then((res) => {
       if (res.success) {
         this.mealCouponTypeList = res.result;
@@ -209,4 +218,4 @@ export default {
     },
   },
 };
-</script>
+</script>

+ 20 - 12
src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleConfirm.vue

@@ -57,7 +57,7 @@
               style="float: left; overflow: hidden"
               class="table-page-search-submitButtons"
             >
-            <!--先不实现增加预定功能-->
+              <!--先不实现增加预定功能-->
               <!-- <a-button v-if="model.roomSchedule.billStatus==0"
                 @click="handleAdd"
                 type="danger"
@@ -123,8 +123,9 @@
             <a-divider type="vertical"
           /></template>
           <template v-if="record.status == 0">
-          <a @click="handleEdit(record)">修改</a>
-          <a-divider type="vertical" /></template>
+            <a @click="handleEdit(record)">修改</a>
+            <a-divider type="vertical"
+          /></template>
           <template v-if="record.status == 0">
             <a @click="batchConfirm(record)">确认</a>
             <a-divider type="vertical" />
@@ -142,6 +143,10 @@
       :meetingRoomScheduleId="meetingRoomScheduleId"
       @ok="modalFormOk"
     ></meeting-room-schedule-detail-modal>
+    <bus-meeting-room-schedule-edit-modal-2
+      ref="modalForm2"
+      @ok="modalFormOk3"
+    ></bus-meeting-room-schedule-edit-modal-2>
   </a-card>
 </template>
 
@@ -151,7 +156,7 @@ import { mixinDevice } from "@/utils/mixin";
 import { JeecgListMixin } from "@/mixins/JeecgListMixin";
 import BusMeetingRoomScheduleEditModal from "./BusMeetingRoomScheduleEditModal";
 import meetingRoomScheduleDetailModal from "./meetingRoomScheduleDetail/meetingRoomScheduleDetailModal";
-
+import BusMeetingRoomScheduleEditModal2 from "@/views/markets/modules/meetingRoomScheduleOrder/BusMeetingRoomScheduleEditModal";
 import { httpAction, getAction, postAction } from "@/api/manage";
 
 export default {
@@ -160,6 +165,7 @@ export default {
   components: {
     BusMeetingRoomScheduleEditModal,
     meetingRoomScheduleDetailModal,
+    BusMeetingRoomScheduleEditModal2,
   },
   props: {
     couponsId: {
@@ -227,7 +233,8 @@ export default {
         },
       ],
       url: {
-        confirmBatch: "/business/busMeetingRoomScheduleDetail/confirmBatchByMeetingRoomScheduleId",
+        confirmBatch:
+          "/business/busMeetingRoomScheduleDetail/confirmBatchByMeetingRoomScheduleId",
       },
       dictOptions: {},
       superFieldList: [],
@@ -258,12 +265,12 @@ export default {
     },
   },
   methods: {
-    handleSettle(){
-      this.$message.error("结账功能暂无实现");
-    },
-    handleAdd(){
-
+    handleSettle(record) {
+      this.$refs.modalForm2.edit(record);
+      this.$refs.modalForm2.title = "结账";
+      this.$refs.modalForm2.disableSubmit = false;
     },
+    handleAdd() {},
     batchConfirm(record) {
       if (!this.url.confirmBatch) {
         this.$message.error("请设置url.confirmBatch!");
@@ -297,9 +304,10 @@ export default {
       this.dataSource = [Object.assign({}, record)];
       this.$emit("ok");
     },
-    modalFormOk(){
-
+    modalFormOk3() {
+      this.dataSource = this.dataSource[0].billStatus = 1;
     },
+    modalFormOk() {},
     add() {
       this.edit(this.modelDefault);
     },

+ 1 - 1
src/views/markets/modules/meetingRoomScheduleOrder/BusMeetingRoomScheduleEditForm.vue

@@ -74,7 +74,7 @@
                 v-model="model.amount"
                 placeholder="请输入金额"
                 style="width: 100%"
-                :min="1"
+                :min="0"
               />
             </a-form-model-item>
           </a-col>

+ 993 - 0
src/views/room/fangtailive.vue

@@ -0,0 +1,993 @@
+<template>
+  <a-card :bordered="false">
+    <a-tabs type="card" @change="tabsClick">
+      <a-tab-pane key="1" tab="全部房型"> </a-tab-pane>
+      <a-tab-pane key="2" tab="大床房"> </a-tab-pane>
+      <a-tab-pane key="3" tab="麻将房"> </a-tab-pane>
+    </a-tabs>
+    <div style="display: flex">
+      <div class="course-week">
+        <div class="week-top">
+          <!-- <div class="week-btn-wrap">
+          <span @click="getLastWeek">上周</span>
+          <span @click="getCurWeek">本周</span>
+          <span @click="getNextWeek">下周</span>
+        </div>
+        <span class="w-today-date"> {{ todayDate }}</span> -->
+          <div class="w-choose-status">
+            <div v-for="sta in cardStatus">
+              <span class="square" :style="{ background: sta.color }"></span>
+              <span class="title">{{ sta.title }}</span>
+            </div>
+          </div>
+          <div class="w-choose-status">
+            <a-input-search
+              style="width: 300px; margin-left: 8px"
+              placeholder="房间号/姓名/手机号/身份证号"
+              enter-button="搜索"
+              v-model="keyWord"
+              type="danger"
+              @search="handleAdd"
+            />
+          </div>
+        </div>
+        <div class="week-table">
+          <div id="components-grid-demo-playground" class="w-time-period-list">
+            <template v-for="(i, iIndex) in planList2">
+              <!--循环时段,看时段有多少个-->
+              <div
+                v-for="(period, cIndex) in i.child"
+                :key="`i${iIndex}-period${cIndex}`"
+                style="padding: 5px"
+              >
+                <p>
+                  <span style="color: rgba(0, 186, 173, 1); font-weight: 600">
+                    {{ i.meetingRoomName }}{{ period.timePeriod }}
+                  </span>
+                  <a-divider type="vertical" />
+                  <span style="padding-right: 5px"
+                    >{{ period.count }}间:在住{{
+                      period.checkInCount
+                    }}间/空置{{ period.vacantCount }}间</span
+                  >
+                  <a-icon
+                    type="right"
+                    v-if="period.collapse == 0"
+                    @click="collapseClick(period, 1)"
+                  />
+                  <a-icon
+                    type="down"
+                    v-else
+                    @click="collapseClick(period, 0)"
+                  />
+                </p>
+
+                <a-row :gutter="[5, 5]" v-show="period.collapse == 1">
+                  <a-col
+                    v-for="(roomLive, roomLiveIndex) in period.schedule"
+                    :key="`i${iIndex}-period${cIndex}roomLive${roomLiveIndex}`"
+                    :span="3"
+                  >
+                    <div
+                      :style="{
+                        background: cardStatus[roomLive.detail.status].color,
+                      }"
+                    >
+                      <a-popover placement="rightTop">
+                        <template
+                          slot="content"
+                          v-if="roomLive.detail.status == 1"
+                        >
+                          <p>入住:{{ roomLive.detail.startDate }}</p>
+                          <p>预离:{{ roomLive.detail.endDate }}</p>
+                          <p>已住:{{ roomLive.detail.day }}晚 已付:600元</p>
+                          <p>来源:{{ roomLive.detail.mobile }} 消费:300元</p>
+                          <p>
+                            房价:{{ roomLive.detail.amout }}/晚 余额:{{
+                              roomLive.detail.balance
+                            }}
+                          </p>
+                          <p>注:{{ roomLive.detail.remark }}</p>
+                        </template>
+                        <template
+                          slot="title"
+                          v-if="roomLive.detail.status == 1"
+                        >
+                          <p>
+                            客人姓名:{{ roomLive.detail.occupant }} 性别:男
+                          </p>
+                          <p>手机号:{{ roomLive.detail.mobile }}</p>
+                          <p>同住人:{{ roomLive.detail.mobile }} 性别:女</p>
+                        </template>
+                        <template
+                          slot="content"
+                          v-if="roomLive.detail.status == 0"
+                        >
+                          <p>房态:{{ roomLive.detail.roomStatusName }}</p>
+                          <p>备注:{{ roomLive.detail.remark }}</p>
+                        </template>
+                        <template
+                          slot="title"
+                          v-if="roomLive.detail.status == 0"
+                        >
+                          <span>{{ roomLive.detail.roomType }}</span
+                          ><span>¥{{ roomLive.detail.amout }}/晚</span>
+                        </template>
+                        <a-dropdown :trigger="['contextmenu']">
+                          <div>
+                            <div
+                              style="
+                                text-overflow: ellipsis;
+                                white-space: nowrap;
+                                overflow: hidden;
+                              "
+                            >
+                              <span
+                                style="
+                                  font-size: 20px;
+                                  font-weight: 600;
+                                  margin-right: 2px;
+                                "
+                                >{{ roomLive.roomNo }}</span
+                              >
+                              {{ roomLive.detail.roomType }}
+                            </div>
+                            <template v-if="roomLive.detail.status == 1">
+                              <div>
+                                <span style="margin-right: 5px">{{
+                                  roomLive.detail.occupant
+                                }}</span
+                                ><a-tag
+                                  :style="{
+                                    color:
+                                      sourceType[roomLive.detail.source || 1]
+                                        .color,
+                                  }"
+                                  >携</a-tag
+                                >
+                              </div>
+                              <div>
+                                <span
+                                  >{{ roomLive.detail.day }}天/{{
+                                    roomLive.detail.date
+                                  }}</span
+                                >
+                              </div>
+                              <div
+                                style="
+                                  text-overflow: ellipsis;
+                                  white-space: nowrap;
+                                  overflow: hidden;
+                                "
+                              >
+                                <span
+                                  >¥{{ roomLive.detail.amout }}/付{{
+                                    roomLive.detail.payAmount
+                                  }}/余{{ roomLive.detail.balance }}</span
+                                >
+                              </div>
+                              <a-tag>订</a-tag
+                              ><a-tag v-if="roomLive.detail.isGroup">团</a-tag>
+                            </template>
+                            <template v-else>
+                              <div>
+                                <span>¥{{ roomLive.detail.amout }}/晚</span>
+                              </div>
+                              <div
+                                style="
+                                  margin-top: 22px;
+                                  text-overflow: ellipsis;
+                                  white-space: nowrap;
+                                  overflow: hidden;
+                                "
+                              >
+                                <span>注:{{ roomLive.detail.remark }}</span>
+                              </div>
+                              <a-tag>订</a-tag>
+                            </template>
+                          </div>
+                          <a-menu slot="overlay" @click="onMenuClick">
+                            <a-menu-item key="1"> 入住 </a-menu-item>
+                            <a-menu-item key="2"> 预定</a-menu-item>
+                            <a-menu-item key="3"> 置脏 </a-menu-item>
+                            <a-menu-item key="4"> 置维修 </a-menu-item>
+                            <a-menu-item key="5"> 锁房 </a-menu-item>
+                            <!-- <a-menu-item key="3"> 日志 </a-menu-item> -->
+                          </a-menu>
+                        </a-dropdown>
+                      </a-popover>
+                    </div>
+                  </a-col>
+                </a-row>
+              </div>
+            </template>
+          </div>
+        </div>
+      </div>
+      <div style="width: 1%"></div>
+      <div style="width: 19%">
+        <a-button style="margin-bottom: 10px" @click="handleAdd" type="danger"
+          >批量制卡</a-button
+        >
+        <p style="font-size: 16px; font-weight: 600; color: rgb(0, 186, 173)">
+          按楼层
+        </p>
+        <a-tree-select
+          v-model="value"
+          style="width: 100%"
+          :tree-data="treeData"
+          tree-checkable
+          :show-checked-strategy="SHOW_PARENT"
+          search-placeholder="Please select"
+        />
+        <p
+          style="
+            font-size: 16px;
+            font-weight: 600;
+            color: rgb(0, 186, 173);
+            margin-top: 10px;
+          "
+        >
+          按房态
+        </p>
+        <a-checkbox-group @change="onChange">
+          <a-row>
+            <a-col :span="8">
+              <a-checkbox value="A"> 空净 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="B"> 空脏 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="C"> 住净 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="D"> 住脏 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="E"> 维修 </a-checkbox>
+            </a-col>
+          </a-row>
+        </a-checkbox-group>
+        <p
+          style="
+            font-size: 16px;
+            font-weight: 600;
+            color: rgb(0, 186, 173);
+            margin-top: 10px;
+          "
+        >
+          按来源
+        </p>
+        <a-checkbox-group @change="onChange">
+          <a-row>
+            <a-col :span="8">
+              <a-checkbox value="A"> 空净 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="B"> 空脏 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="C"> 住净 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="D"> 住脏 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="E"> 维修 </a-checkbox>
+            </a-col>
+          </a-row>
+        </a-checkbox-group>
+        <p
+          style="
+            font-size: 16px;
+            font-weight: 600;
+            color: rgb(0, 186, 173);
+            margin-top: 10px;
+          "
+        >
+          按房型
+        </p>
+        <a-checkbox-group @change="onChange">
+          <a-row>
+            <a-col :span="8">
+              <a-checkbox value="A"> 空净 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="B"> 空脏 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="C"> 住净 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="D"> 住脏 </a-checkbox>
+            </a-col>
+            <a-col :span="8">
+              <a-checkbox value="E"> 维修 </a-checkbox>
+            </a-col>
+          </a-row>
+        </a-checkbox-group>
+      </div>
+    </div>
+    <upkeep-room-modal ref="modalForm" @ok="modalFormOk"></upkeep-room-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+// import { mixinDevice } from "@/utils/mixin";
+// import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import { httpAction, getAction } from "@/api/manage";
+import UpkeepRoomModal from "./modules/upkeep/UpkeepRoomModal.vue";
+import { TreeSelect } from "ant-design-vue";
+const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+const treeData = [
+  {
+    title: "1栋",
+    value: "0-0",
+    key: "0-0",
+    children: [
+      {
+        title: "1层",
+        value: "0-0-0",
+        key: "0-0-0",
+      },
+    ],
+  },
+  {
+    title: "2栋",
+    value: "0-1",
+    key: "0-1",
+    children: [
+      {
+        title: "1层",
+        value: "0-1-0",
+        key: "0-1-0",
+        // disabled: true,
+      },
+      {
+        title: "1层",
+        value: "0-1-1",
+        key: "0-1-1",
+      },
+      {
+        title: "1层",
+        value: "0-1-2",
+        key: "0-1-2",
+      },
+    ],
+  },
+];
+export default {
+  name: "BusMeetingRoomList",
+  // mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    UpkeepRoomModal,
+  },
+  data() {
+    const planList = [
+      {
+        timePeriod: "1层",
+        count: 12,
+        checkInCount: 5,
+        vacantCount: 7,
+        collapse: 1,
+        schedule: [
+          {
+            roomNo: "1001",
+            detail: {
+              status: 0,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1002",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1003",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1004",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1005",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1006",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1007",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1008",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1009",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1010",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+          {
+            roomNo: "1011",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+              remark: "靠马路,噪音大",
+              roomStatusName: "空净",
+              startDate: "2023-03-20 18:00",
+              endDate: "2023-03-21 18:00",
+              source: 1,
+            },
+          },
+        ],
+      },
+      {
+        timePeriod: "2层",
+        count: 12,
+        checkInCount: 5,
+        vacantCount: 7,
+        collapse: 1,
+        schedule: [
+          {
+            roomNo: "2001",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+            },
+          },
+          {
+            roomNo: "2002",
+            detail: {
+              status: 1,
+              roomType: "高级商务大床房",
+              occupant: "张三",
+              day: 1,
+              date: "03-20",
+              amout: 300,
+              payAmount: 500,
+              balance: 200,
+              isGroup: 1,
+            },
+          },
+        ],
+      },
+      {
+        timePeriod: "3层",
+        count: 0,
+        checkInCount: 0,
+        vacantCount: 0,
+        collapse: 1,
+        schedule: [],
+      },
+    ];
+    return {
+      keyWord:'',
+      value: ["0-0-0"],
+      treeData,
+      SHOW_PARENT,
+      cardStatus: {
+        0: {
+          title: "空净",
+          color: "rgba(67, 207, 124, 1)",
+        },
+        1: {
+          title: "在住",
+          color: "#00a0e9",
+        },
+        2: {
+          title: "今日预离",
+          color: "rgba(10, 122, 114, 1)",
+        },
+        3: {
+          title: "欠费",
+          color: "rgba(172, 51, 193, 1)",
+        },
+        4: {
+          title: "锁房/脏房",
+          color: "rgba(128, 128, 128, 1)",
+        },
+      },
+      sourceType: {
+        0: {
+          title: "美团",
+          color: "rgba(67, 207, 124, 1)",
+        },
+        1: {
+          title: "携程",
+          color: "#00a0e9",
+        },
+        2: {
+          title: "飞猪",
+          color: "rgba(10, 122, 114, 1)",
+        },
+        3: {
+          title: "去哪儿",
+          color: "rgba(172, 51, 193, 1)",
+        },
+        4: {
+          title: "同程艺龙",
+          color: "rgba(128, 128, 128, 1)",
+        },
+        5: {
+          title: "微信订房",
+          color: "rgba(128, 128, 128, 1)",
+        },
+      },
+      planList2: [
+        {
+          meetingRoomName: "A栋",
+          child: planList,
+        },
+      ],
+      startDate: "",
+      endDate: "",
+    };
+  },
+  watch: {
+    activeKey(key) {
+      console.log("activeKey", key);
+    },
+  },
+  created() {
+    // 禁用右键
+    // document.oncontextmenu = new Function("event.returnValue=false");
+  },
+  methods: {
+    onChange() {},
+    tabsClick() {},
+    collapseClick(row, value) {
+      this.$set(row, "collapse", value);
+    },
+    handleAdd(e) {
+      this.$refs.modalForm.add();
+      this.$refs.modalForm.title = "维修";
+      this.$refs.modalForm.disableSubmit = false;
+    },
+    onMenuClick(e) {
+      console.log(e);
+      this.$refs.modalForm.add();
+      this.$refs.modalForm.title = "维修";
+      this.$refs.modalForm.disableSubmit = false;
+    },
+    modalFormOk() {
+      this.loadData();
+    },
+    loadData() {
+      // var _info = JSON.parse(localStorage.getItem("storeInfo"));
+      // getAction("/business/busMeetingRoomSchedule/fetch", {
+      //   startDate: this.startDate,
+      //   endDate: this.endDate,
+      //   hotelId: _info.id,
+      // }).then((res) => {
+      //   if (res.success) {
+      //     this.planList2 = res.result;
+      //   }
+      // });
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>
+<style>
+ul {
+  list-style: none;
+}
+
+ul,
+li {
+  margin: 0;
+  padding: 0;
+}
+
+.course-week {
+  width: 80%;
+  /* border: 1px solid #ddd; */
+  /* padding: 1%; */
+  box-sizing: border-box;
+}
+
+.week-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+  height: 40px;
+  padding: 0 1%;
+  box-sizing: border-box;
+}
+
+.week-top .week-btn-wrap {
+  width: 200px;
+  display: flex;
+  justify-content: space-around;
+  color: #409eff;
+}
+
+.week-top .week-btn-wrap span {
+  cursor: pointer;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 15px;
+}
+
+.w-today-date {
+  font-weight: bold;
+  font-size: 16px;
+}
+
+.w-choose-status {
+  display: flex;
+  /* justify-content: flex-end;
+  width: 200px; */
+}
+
+.w-choose-status > div {
+  width: 100%;
+  flex: 1;
+  display: flex;
+  padding: 0 2%;
+  white-space: nowrap;
+  line-height: 20px;
+  box-sizing: border-box;
+}
+
+.w-choose-status > div .square {
+  display: flex;
+  width: 16px;
+  height: 16px;
+  border-radius: 4px;
+  box-sizing: border-box;
+}
+
+.w-choose-status > div .title {
+  display: flex;
+  align-items: center;
+  line-height: 16px;
+  padding-left: 4px;
+  font-size: 14px;
+  box-sizing: border-box;
+}
+
+.week-table {
+  display: flex;
+  flex-direction: column;
+}
+
+.week-table .table-header {
+  width: 100%;
+  height: 80px;
+  background: #eaedf2;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  border-bottom: 1px solid #eaedf2;
+  box-sizing: border-box;
+}
+
+.table-header .w-table-date,
+.table-week {
+  width: 100%;
+  height: 40px;
+  text-align: left;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.table-header .w-table-date > span,
+.table-week > span {
+  flex: 1;
+  color: #000;
+  height: 100%;
+  font-size: 14px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-weight: bold;
+}
+
+.w-table-date .w-day-item,
+.table-week .w-day-item {
+  color: #000;
+  font-size: 14px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.week-table .w-time-period-list {
+  width: 100%;
+}
+
+.w-time-period-list .w-time-period-row {
+  width: 100%;
+  min-height: 60px;
+}
+
+.w-time-period-col {
+  width: 100%;
+  min-height: 60px;
+  display: flex;
+}
+
+.w-time-period-col .w-time-period {
+  width: 12.5%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-left: 1px solid #eaedf2;
+  /* border-bottom: 1px solid #eaedf2; */
+  box-sizing: border-box;
+}
+.w-time-period-col:last-child {
+  border-bottom: 1px solid #eaedf2;
+}
+.meeting-room-center {
+  transform: translate(-200%, 0%);
+  width: 14px;
+  font-size: 14px;
+  word-wrap: break-word;
+  position: absolute;
+}
+
+.w-time-period-col .w-row-day {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+}
+
+.w-row-day .w-things {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  border-left: 1px solid #eaedf2;
+  border-bottom: 1px solid #eaedf2;
+  box-sizing: border-box;
+  cursor: pointer;
+}
+
+.w-row-day .w-things:last-child {
+  border-right: 1px solid #eaedf2;
+}
+
+.w-things .w-thing-item {
+  display: flex;
+  /* width: 80%; */
+  height: 135px;
+  font-size: 14px;
+  flex-direction: column;
+  justify-content: space-around;
+  min-height: 50px;
+  border-radius: 10px;
+  margin: 2% 1%;
+  padding: 1% 2%;
+  cursor: pointer;
+  color: #fff;
+  background: #ff6200;
+  box-sizing: border-box;
+  transition: all 1s linear 0.5s;
+}
+
+.w-isCurDate {
+  color: #ff2525 !important;
+}
+
+.w-noMore {
+  min-height: 200px;
+  padding: 2%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border: 1px solid rgba(156, 173, 173, 0.3);
+  color: #9cadadb7;
+  box-sizing: border-box;
+}
+
+.w_expand,
+.w_shrink {
+  color: #0a98d5;
+  cursor: pointer;
+  width: 100%;
+  padding: 2% 0;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+</style>
+
+<style scoped>
+#components-grid-demo-playground [class~="ant-col"] {
+  background: transparent;
+  border: 0;
+}
+#components-grid-demo-playground [class~="ant-col"] > div {
+  background: rgba(67, 207, 124, 1);
+  height: 125px;
+  /* line-height: 200px; */
+  font-size: 13px;
+  color: #f9f9f9;
+  padding: 2px;
+  border-radius: 5px;
+  cursor: pointer;
+}
+#components-grid-demo-playground pre {
+  background: #f9f9f9;
+  border-radius: 6px;
+  font-size: 13px;
+  padding: 8px 16px;
+}
+</style>

+ 137 - 0
src/views/room/modules/upkeep/UpkeepRoomForm.vue

@@ -0,0 +1,137 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+        slot="detail"
+      >
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item
+              label="维修时间"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="dateRange"
+            >
+              <a-range-picker v-model="model.dateRange" @change="onChange" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="维修原因"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="remark"
+            >
+              <a-textarea
+                v-model="model.remark"
+                rows="4"
+                placeholder="请输入维修原因"
+              />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+export default {
+  name: "BusMeetingRoomForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        dateRange: [{ required: true, message: "请选择维修时间!" }],
+        remark: [{ required: true, message: "请输入维修原因!" }],
+      },
+      url: {
+        add: "/business/busMeetingRoom/add",
+        edit: "/business/busMeetingRoom/edit",
+        queryById: "/business/busMeetingRoom/queryById",
+      },
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    onChange(date, dateString) {
+      console.log(date, dateString);
+    },
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+    submitForm() {
+      const that = this;
+      that.$message.warning('未实现');
+      return;
+      // 触发表单验证
+      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";
+          }
+          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>

+ 60 - 0
src/views/room/modules/upkeep/UpkeepRoomModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <upkeep-room-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></upkeep-room-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import UpkeepRoomForm from './UpkeepRoomForm'
+  export default {
+    name: 'UpkeepRoomFormModal',
+    components: {
+      UpkeepRoomForm
+    },
+    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>

+ 246 - 0
src/views/settings/components/doorLockList.vue

@@ -0,0 +1,246 @@
+<template>
+    <a-card :bordered="false">
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline" @keyup.enter.native="searchQuery">
+                <a-row :gutter="24">
+                    <a-col :md="4" :sm="6">
+                        <a-form-item>
+                            <j-input placeholder="关联号" v-model="queryParam.associationNumber"></j-input>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="4" :sm="6">
+                        <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+                          <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                        </span>
+                    </a-col>
+                </a-row>
+            </a-form>
+        </div>
+        <!-- 查询区域-END -->
+
+        <!-- 操作按钮区域 -->
+        <div class="table-operator">
+            <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+            <a-button @click="handleBatchAdd" type="primary" icon="plus">批量添加</a-button>
+<!--            <a-button type="primary" icon="download" @click="handleExportXls('门锁管理')">导出</a-button>-->
+<!--            <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">-->
+<!--                <a-button type="primary" icon="import">导入</a-button>-->
+<!--            </a-upload>-->
+            <!-- 高级查询区域 -->
+<!--            <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
+            <a-dropdown v-if="selectedRowKeys.length > 0">
+<!--                <a-menu slot="overlay">-->
+<!--                    <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>-->
+<!--                </a-menu>-->
+<!--                <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>-->
+                <a-button @click="batchDel" type="danger" icon="delete">批量删除</a-button>
+            </a-dropdown>
+        </div>
+
+        <!-- table区域-begin -->
+        <div>
+            <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+                <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+                <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+            </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="htmlSlot" slot-scope="text">
+                    <div v-html="text"></div>
+                </template>
+                <template slot="numberSlot" slot-scope="text,record">
+                    <div style="display: flex;align-items: center">
+                        <a-form :form="form" :rules="validatorRules" style="width: 90%">
+                            <a-form-item prop="associationNumber" style="margin-bottom: 0px">
+                                <a-input v-model="text" @blur="(e)=>handleNumber(e,record)" />
+                            </a-form-item>
+                        </a-form>
+                        <!--                    <a-input v-model="text" placeholder="请输入关联号" @change="(e)=>handleNumber(e,record)" ></a-input>-->
+                    </div>
+                </template>
+                <template slot="imgSlot" slot-scope="text,record">
+                    <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+                    <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+                </template>
+                <template slot="fileSlot" slot-scope="text">
+                    <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+                    <a-button
+                            v-else
+                            :ghost="true"
+                            type="primary"
+                            icon="download"
+                            size="small"
+                            @click="downloadFile(text)">
+                        下载
+                    </a-button>
+                </template>
+
+                <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+            </a-table>
+        </div>
+
+        <door-lock-modal ref="modalForm" @ok="modalFormOk"></door-lock-modal>
+        <door-lock-batch-modal ref="modalBatchForm" @ok="modalFormOk"></door-lock-batch-modal>
+    </a-card>
+</template>
+
+<script>
+
+    import '@/assets/less/TableExpand.less'
+    import { mixinDevice } from '@/utils/mixin'
+    import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+    import doorLockModal from './modules/doorLockModal'
+    import DoorLockBatchModal from "./modules/doorLockBatchModal";
+    import { httpAction, getAction } from '@/api/manage'
+
+    export default {
+        name: 'doorLockList',
+        mixins:[JeecgListMixin, mixinDevice],
+        components: {
+            DoorLockBatchModal,
+            doorLockModal
+        },
+        data () {
+            return {
+                description: '门锁管理管理页面',
+                // 表头
+                columns: [
+                    {
+                        title:'楼栋',
+                        align:"center",
+                        dataIndex: 'buildName',
+                        width: 300
+                    },
+                    {
+                        title:'楼层',
+                        align:"center",
+                        dataIndex: 'floorName',
+                        width: 300
+                    },
+                    {
+                        title:'房间号',
+                        align:"center",
+                        dataIndex: 'roomNumber',
+                        width: 300
+                    },
+                    {
+                        title:'关联号',
+                        align:"center",
+                        dataIndex: 'associationNumber',
+                        scopedSlots: { customRender: 'numberSlot' },
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align:"center",
+                        fixed:"right",
+                        width:147,
+                        scopedSlots: { customRender: 'action' }
+                    }
+                ],
+                url: {
+                    list: "/business/busDoorLock/list",
+                    delete: "/business/busDoorLock/delete",
+                    edit: "/business/busDoorLock/edit",
+                    deleteBatch: "/business/busDoorLock/deleteBatch",
+                    exportXlsUrl: "/business/busDoorLock/exportXls",
+                    importExcelUrl: "business/busDoorLock/importExcel",
+
+                },
+                dictOptions:{},
+                superFieldList:[],
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    associationNumber: [
+                        {required: true, message: '请输入关联号!'},
+                    ],
+                },
+            }
+        },
+        created() {
+            this.getSuperFieldList();
+        },
+        computed: {
+            importExcelUrl: function(){
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            },
+        },
+        methods: {
+            initDictConfig(){
+            },
+            getSuperFieldList(){
+                let fieldList=[];
+                fieldList.push({type:'string',value:'tenantId',text:'关联租户'})
+                fieldList.push({type:'string',value:'hotelId',text:'关联酒店'})
+                fieldList.push({type:'string',value:'buildId',text:'楼栋ID'})
+                fieldList.push({type:'string',value:'floorId',text:'楼层ID'})
+                fieldList.push({type:'string',value:'roomNumber',text:'房间号'})
+                fieldList.push({type:'string',value:'associationNumber',text:'关联号'})
+                fieldList.push({type:'int',value:'status',text:'状态(0-禁用;1-启用)'})
+                fieldList.push({type:'int',value:'delFlag',text:'删除状态(0-正常,1-已删除)'})
+                this.superFieldList = fieldList
+            },
+            handleBatchAdd: function () {
+                this.$refs.modalBatchForm.add();
+                this.$refs.modalBatchForm.title = "批量添加";
+                this.$refs.modalBatchForm.disableSubmit = false;
+            },
+            handleNumber(e,record){
+                console.log(e)
+                console.log(record)
+
+                var data = record;
+                data.associationNumber = e.target.value;
+                const that = this;
+                that.confirmLoading = true;
+                let httpurl = this.url.edit;
+                let method = 'put';
+                httpAction(httpurl, data, 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>
+    @import '~@assets/less/common.less';
+</style>

+ 140 - 0
src/views/settings/components/modules/doorLockBatchForm.vue

@@ -0,0 +1,140 @@
+<template>
+    <a-spin :spinning="confirmLoading">
+        <j-form-container :disabled="formDisabled">
+            <a-form-model ref="form" :rules="validatorRules" slot="detail">
+                <a-row>
+                    <a-col :span="24">
+                        <a-form-model-item label="" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="batchType">
+                            <a-radio-group v-model="batchType" @change="onChange">
+                                <a-radio :value="1" :style="radioStyle">
+                                    关联号与房间号相同
+                                </a-radio>
+                                <a-radio :value="2" :style="radioStyle">
+                                    关联号 =
+                                    <a-input style="width: 80px" @change="(e)=>handleFront(e)" ></a-input>
+                                    +房间号+
+                                    <a-input style="width: 80px" @change="(e)=>handleAfter(e)"></a-input>
+                                </a-radio>
+                                <a-radio :value="3" :style="radioStyle">
+                                    关联号 =
+                                    <a-input style="width: 80px" @change="(e)=>handleFront(e)"></a-input>
+                                    +缺少首位的房间号+
+                                    <a-input style="width: 80px" @change="(e)=>handleAfter(e)" ></a-input>
+                                </a-radio>
+                                <a-radio :value="4" :style="radioStyle">
+                                    关联号 = 由
+                                    <a-input style="width: 80px" @change="(e)=>handleFront(e)"></a-input>
+                                    +开始随房间号递增一位
+                                </a-radio>
+                            </a-radio-group>
+                        </a-form-model-item>
+                    </a-col>
+                </a-row>
+            </a-form-model>
+        </j-form-container>
+    </a-spin>
+</template>
+
+<script>
+    import { httpAction, getAction } from '@/api/manage'
+    import { validateDuplicateValue } from '@/utils/util'
+    import { buildingTree, queryFloorByParentId,queryRoomByFloorId } from "@/api/roomBuildingApi";
+
+    export default {
+        name: 'doorLockBatchForm',
+        components: {},
+        props: {
+            //表单禁用
+            disabled: {
+                type: Boolean,
+                default: false,
+                required: false
+            }
+        },
+        data() {
+            return {
+                batchType: '',
+                front:'',
+                after:'',
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+                confirmLoading: false,
+                validatorRules: {
+                    batchType: [
+                        // {required: true, message: '请选择!'},
+                    ],
+                },
+                url: {
+                    batchAdd: "/business/busDoorLock/batchAdd"
+                },
+                radioStyle: {
+                    display: 'block',
+                    height: '50px',
+                    lineHeight: '50px',
+                },
+            }
+        },
+        computed: {
+            formDisabled() {
+                return this.disabled
+            },
+        },
+        created() {
+            //备份model原始值
+        },
+        methods: {
+            add() {
+                this.visible = true;
+            },
+            submitForm() {
+                console.log(this.batchType)
+                const that = this;
+                if (this.batchType == ''){
+                    that.$message.error('请选择');
+                }
+
+                that.confirmLoading = true;
+                let httpurl = this.url.batchAdd;
+                let method = 'post';
+                var info = JSON.parse(localStorage.getItem("storeInfo"));
+                var data = {
+                    hotelId: info.id,
+                    radioType: this.batchType,
+                    front: this.front,
+                    after: this.after
+                }
+                httpAction(httpurl, data, method).then((res) => {
+                    if (res.success) {
+                        that.$message.success(res.message);
+                        that.$emit('ok');
+                    } else {
+                        that.$message.warning(res.message);
+                    }
+                }).finally(() => {
+                    that.confirmLoading = false;
+                })
+            },
+            onChange(e) {
+                console.log('radio checked', e.target.value);
+            },
+            handleFront(e){
+                console.log(e)
+                this.front = e.target.value
+            },
+            handleAfter(e){
+                console.log(e)
+                this.after = e.target.value
+            }
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 61 - 0
src/views/settings/components/modules/doorLockBatchModal.vue

@@ -0,0 +1,61 @@
+<template>
+    <j-modal
+            :title="title"
+            :width="width"
+            :visible="visible"
+            switchFullscreen
+            @ok="handleOk"
+            :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+            @cancel="handleCancel"
+            cancelText="关闭">
+        <door-lock-batch-form ref="realBatchForm" @ok="submitCallback" :disabled="disableSubmit"></door-lock-batch-form>
+    </j-modal>
+</template>
+
+<script>
+
+    import DoorLockBatchForm from "./doorLockBatchForm";
+    export default {
+        name: 'doorLockBatchModal',
+        components: {
+            DoorLockBatchForm,
+        },
+        data () {
+            return {
+                title:'',
+                width:800,
+                visible: false,
+                disableSubmit: false
+            }
+        },
+        methods: {
+            add () {
+                this.visible=true
+                console.log(this.$refs.realBatchForm)
+                this.$nextTick(()=>{
+                    this.$refs.realBatchForm.add();
+                })
+            },
+            edit (record) {
+                this.visible=true
+                this.$nextTick(()=>{
+                    this.$refs.realBatchForm.edit(record);
+                })
+            },
+            close () {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk () {
+                this.$refs.realBatchForm.submitForm();
+            },
+            submitCallback(){
+                this.$emit('ok');
+                this.visible = false;
+            },
+            handleCancel () {
+                this.close()
+            }
+        }
+    }
+</script>

+ 220 - 0
src/views/settings/components/modules/doorLockForm.vue

@@ -0,0 +1,220 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="楼栋" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="buildId">
+<!--              <a-input v-model="model.buildId" placeholder="请输入楼栋ID"  ></a-input>-->
+              <a-select
+                      show-search
+                      placeholder="请选择楼栋"
+                      v-model="model.buildId"
+                      option-filter-prop="children"
+                      @change="onBuildChange"
+              >
+                <a-select-option v-for="item in buildingTreeData" :key="item.id" >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="楼层" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="floorId">
+<!--              <a-input v-model="model.floorId" placeholder="请输入楼层ID"  ></a-input>-->
+              <a-select
+                      show-search
+                      placeholder="请选择楼层"
+                      v-model="model.floorId"
+                      option-filter-prop="children"
+                      @change="onFloorChange"
+              >
+                <a-select-option v-for="item in floorData" :key="item.id" >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="房间号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="roomId">
+<!--              <a-input v-model="model.roomNumber" placeholder="请输入房间号"  ></a-input>-->
+              <a-select
+                      show-search
+                      placeholder="请选择楼栋"
+                      v-model="model.roomId"
+                      option-filter-prop="children"
+              >
+                <a-select-option v-for="item in roomData" :key="item.id" >
+                  {{ item.prefix+item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="关联号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="associationNumber">
+              <a-input v-model="model.associationNumber" placeholder="请输入关联号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+  import { buildingTree, queryFloorByParentId,queryRoomByFloorId } from "@/api/roomBuildingApi";
+
+  export default {
+      name: 'doorLockForm',
+      components: {},
+      props: {
+          //表单禁用
+          disabled: {
+              type: Boolean,
+              default: false,
+              required: false
+          }
+      },
+      data() {
+          return {
+              model: {},
+              labelCol: {
+                  xs: {span: 24},
+                  sm: {span: 5},
+              },
+              wrapperCol: {
+                  xs: {span: 24},
+                  sm: {span: 16},
+              },
+              confirmLoading: false,
+              validatorRules: {
+                  buildId: [
+                      {required: true, message: '请选择楼栋!'},
+                  ],
+                  floorId: [
+                      {required: true, message: '请选择楼层!'},
+                  ],
+                  roomId: [
+                      {required: true, message: '请选择房间号!'},
+                  ],
+                  associationNumber: [
+                      {required: true, message: '请输入关联号!'},
+                  ],
+              },
+              url: {
+                  add: "/business/busDoorLock/add",
+                  edit: "/business/busDoorLock/edit",
+                  queryById: "/business/busDoorLock/queryById"
+              },
+              buildingTreeData: [],
+              floorData: [],
+              roomData: [],
+          }
+      },
+      computed: {
+          formDisabled() {
+              return this.disabled
+          },
+      },
+      created() {
+          //备份model原始值
+          this.modelDefault = JSON.parse(JSON.stringify(this.model));
+
+          buildingTree().then((res) => {
+              if (res.code == 200) {
+                  console.log(res.result)
+                  this.buildingTreeData = res.result;
+              }
+          });
+      },
+      methods: {
+          add() {
+              this.edit(this.modelDefault);
+          },
+          edit(record) {
+              this.model = Object.assign({}, record);
+              this.visible = true;
+              if (this.model.id){
+                  queryFloorByParentId(
+                      {
+                          parentId: this.model.buildId
+                      }
+                  ).then((res) => {
+                      if (res.code == 200) {
+                          this.floorData = res.result;
+                      }
+                  });
+                  queryRoomByFloorId(
+                      {
+                          floorId: this.model.floorId
+                      }
+                  ).then((res) => {
+                      if (res.code == 200) {
+                          this.roomData = 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;
+                          var info = JSON.parse(localStorage.getItem("storeInfo"));
+                          this.model.hotelId = info.id;
+                          method = 'post';
+                      } else {
+                          httpurl += this.url.edit;
+                          method = 'put';
+                      }
+                      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;
+                      })
+                  }
+
+              })
+          },
+          onBuildChange() {
+              console.log(this.buildingTreeData)
+              let bIndex = this.buildingTreeData.findIndex(s => s.id == this.model.buildId)
+              let currentFloorNames = (this.buildingTreeData[bIndex].children || []).map(s => s.name)
+              console.log(currentFloorNames)
+              // this.floorNames = currentFloorNames
+              // this.roomTree = JSON.parse(JSON.stringify(this.roomTree))
+              var param = {
+                  parentId: this.model.buildId
+              }
+              queryFloorByParentId(param).then((res) => {
+                  if (res.code == 200) {
+                      this.floorData = res.result;
+                  }
+              });
+          },
+          onFloorChange() {
+              var param = {
+                  floorId: this.model.floorId
+              }
+              queryRoomByFloorId(param).then((res) => {
+                  if (res.code == 200) {
+                      this.roomData = res.result;
+                  }
+              });
+          },
+      }
+  }
+</script>

+ 84 - 0
src/views/settings/components/modules/doorLockModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <door-lock-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></door-lock-form>
+    <div class="drawer-footer">
+      <a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
+      <a-button v-if="!disableSubmit"  @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
+    </div>
+  </a-drawer>
+</template>
+
+<script>
+
+  import doorLockForm from './doorLockForm'
+
+  export default {
+    name: 'doorLockModal',
+    components: {
+      doorLockForm
+    },
+    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;
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+/** Button按钮间距 */
+  .ant-btn {
+    margin-left: 30px;
+    margin-bottom: 30px;
+    float: right;
+  }
+  .drawer-footer{
+    position: absolute;
+    bottom: -8px;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+</style>

+ 60 - 0
src/views/settings/components/modules/doorLockModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <door-lock-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></door-lock-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import doorLockForm from './doorLockForm'
+  export default {
+    name: 'doorLockModal',
+    components: {
+      doorLockForm
+    },
+    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>

+ 138 - 0
src/views/settings/components/modules/orderSoundForm.vue

@@ -0,0 +1,138 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="铃声名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="name">
+              <a-input v-model="model.name" placeholder="请输入铃声名称"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+<!--            <a-form-model-item-->
+<!--                    label="类型"-->
+<!--                    :labelCol="labelCol"-->
+<!--                    :wrapperCol="wrapperCol"-->
+<!--                    prop="type"-->
+<!--            >-->
+<!--              <a-radio-group v-model="model.type">-->
+<!--                <a-radio :value="1">订单来了</a-radio>-->
+<!--                <a-radio :value="2">订单取消</a-radio>-->
+<!--                <a-radio :value="3">通用铃声</a-radio>-->
+<!--                <a-radio :value="4">自动接单</a-radio>-->
+<!--              </a-radio-group>-->
+<!--            </a-form-model-item>-->
+            <a-form-model-item label="类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="type">
+              <j-dict-select-tag type="radio" v-model="model.type" placeholder="请选择铃声类型" dictCode="order_sound_type"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="铃声" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="path">
+              <a-input v-model="model.path" placeholder="请输入铃声地址"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'BusOrderSoundForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        confirmLoading: false,
+        validatorRules: {
+           tenantId: [
+              { required: true, message: '请输入关联租户!'},
+           ],
+           hotelId: [
+              { required: true, message: '请输入关联酒店!'},
+           ],
+           name: [
+              { required: true, message: '请输入铃声名称!'},
+           ],
+        },
+        url: {
+          add: "/business/busOrderSound/add",
+          edit: "/business/busOrderSound/edit",
+          queryById: "/business/busOrderSound/queryById"
+        }
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      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';
+              var info = JSON.parse(localStorage.getItem("storeInfo"));
+              this.model.hotelId = info.id;
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            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>

+ 84 - 0
src/views/settings/components/modules/orderSoundModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <order-sound-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></order-sound-form>
+    <div class="drawer-footer">
+      <a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
+      <a-button v-if="!disableSubmit"  @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
+    </div>
+  </a-drawer>
+</template>
+
+<script>
+
+  import orderSoundForm from './orderSoundForm'
+
+  export default {
+    name: 'orderSoundModal',
+    components: {
+      orderSoundForm
+    },
+    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;
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+/** Button按钮间距 */
+  .ant-btn {
+    margin-left: 30px;
+    margin-bottom: 30px;
+    float: right;
+  }
+  .drawer-footer{
+    position: absolute;
+    bottom: -8px;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+</style>

+ 60 - 0
src/views/settings/components/modules/orderSoundModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <order-sound-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></order-sound-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import orderSoundForm from './orderSoundForm'
+  export default {
+    name: 'orderSoundModal',
+    components: {
+      orderSoundForm
+    },
+    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>

+ 209 - 0
src/views/settings/components/orderSoundList.vue

@@ -0,0 +1,209 @@
+<template>
+    <a-card :bordered="false">
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline" @keyup.enter.native="searchQuery">
+                <a-row :gutter="24">
+                    <a-col :md="4" :sm="6">
+                        <a-form-item>
+                            <j-input placeholder="名称" v-model="queryParam.name"></j-input>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="4" :sm="6">
+                        <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+                          <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                        </span>
+                    </a-col>
+                </a-row>
+            </a-form>
+        </div>
+        <!-- 查询区域-END -->
+
+        <!-- 操作按钮区域 -->
+        <div class="table-operator">
+            <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+<!--            <a-button type="primary" icon="download" @click="handleExportXls('订单铃声')">导出</a-button>-->
+<!--            <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">-->
+<!--                <a-button type="primary" icon="import">导入</a-button>-->
+<!--            </a-upload>-->
+<!--            &lt;!&ndash; 高级查询区域 &ndash;&gt;-->
+<!--            <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
+            <a-dropdown v-if="selectedRowKeys.length > 0">
+<!--                <a-menu slot="overlay">-->
+<!--                    <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>-->
+<!--                </a-menu>-->
+<!--                <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>-->
+                <a-button @click="batchDel" type="danger" icon="delete">批量删除</a-button>
+            </a-dropdown>
+        </div>
+
+        <!-- table区域-begin -->
+        <div>
+            <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+                <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+                <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+            </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="htmlSlot" slot-scope="text">
+                    <div v-html="text"></div>
+                </template>
+                <span slot="type" slot-scope="text,record">
+                    <a-tag color="green">{{text}}</a-tag>
+                </span>
+                <span slot="sound" slot-scope="text,record">
+                    <a-button icon="audio" @click="toAudition(text)" type="primary" size="small" ghost>
+                      试听
+                    </a-button>
+                </span>
+                <template slot="imgSlot" slot-scope="text,record">
+                    <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+                    <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+                </template>
+                <template slot="fileSlot" slot-scope="text">
+                    <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+                    <a-button
+                            v-else
+                            :ghost="true"
+                            type="primary"
+                            icon="download"
+                            size="small"
+                            @click="downloadFile(text)">
+                        下载
+                    </a-button>
+                </template>
+
+                <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">修改</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+<!--              <a-menu-item>-->
+<!--                <a @click="handleDetail(record)">详情</a>-->
+<!--              </a-menu-item>-->
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+                </span>
+            </a-table>
+        </div>
+        <audio ref="audition" ></audio>
+        <order-sound-modal ref="modalForm" @ok="modalFormOk"></order-sound-modal>
+    </a-card>
+</template>
+
+<script>
+
+    import '@/assets/less/TableExpand.less'
+    import { mixinDevice } from '@/utils/mixin'
+    import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+    import orderSoundModal from './modules/orderSoundModal'
+
+    export default {
+        name: 'orderSoundList',
+        mixins:[JeecgListMixin, mixinDevice],
+        components: {
+            orderSoundModal
+        },
+        data () {
+            return {
+                description: '订单铃声管理页面',
+                // 表头
+                columns: [
+                    {
+                        title:'名称',
+                        align:"center",
+                        dataIndex: 'name'
+                    },
+                    {
+                        title:'类型',
+                        align:"center",
+                        dataIndex: 'type_dictText',
+                        scopedSlots: { customRender: 'type' },
+                    },
+                    {
+                        title:'铃声',
+                        align:"center",
+                        dataIndex: 'path',
+                        scopedSlots: { customRender: 'sound' },
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align:"center",
+                        fixed:"right",
+                        width:147,
+                        scopedSlots: { customRender: 'action' }
+                    }
+                ],
+                url: {
+                    list: "/business/busOrderSound/list",
+                    delete: "/business/busOrderSound/delete",
+                    deleteBatch: "/business/busOrderSound/deleteBatch",
+                    exportXlsUrl: "/business/busOrderSound/exportXls",
+                    importExcelUrl: "business/busOrderSound/importExcel",
+
+                },
+                dictOptions:{},
+                superFieldList:[],
+            }
+        },
+        created() {
+            this.getSuperFieldList();
+        },
+        computed: {
+            importExcelUrl: function(){
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            },
+        },
+        methods: {
+            initDictConfig(){
+            },
+            getSuperFieldList(){
+                let fieldList=[];
+                fieldList.push({type:'string',value:'tenantId',text:'关联租户'})
+                fieldList.push({type:'string',value:'hotelId',text:'关联酒店'})
+                fieldList.push({type:'string',value:'name',text:'铃声名称'})
+                fieldList.push({type:'int',value:'type',text:'铃声类型'})
+                fieldList.push({type:'string',value:'path',text:'铃声地址'})
+                fieldList.push({type:'int',value:'status',text:'状态(0-禁用;1-启用)'})
+                fieldList.push({type:'int',value:'delFlag',text:'删除状态(0-正常,1-已删除)'})
+                this.superFieldList = fieldList
+            },
+            toAudition(e){
+                // this.$refs.audition.play();
+                if (e.indexOf('mp3') > 0){
+                    this.$refs.audition.src= e;
+                    var auto = this.$refs.audition
+                    if (auto.paused) {
+                        auto.play();
+                    } else {
+                        auto.pause();
+                    }
+                }
+            }
+        }
+    }
+</script>
+<style scoped>
+    @import '~@assets/less/common.less';
+</style>

+ 15 - 10
src/views/settings/components/roomModules/goodList.vue

@@ -107,7 +107,7 @@
                             数量
                         </a-col>
                         <a-col :span="4">
-                            <a-input-number v-model="goodsSetData.goodNum" :min="0" /> &nbsp;
+                            <a-input-number v-model="goodsSetData.goodNum" :min="0" /> &nbsp;{{goodsSetData.unitName}}
                         </a-col>
                     </a-row>
                     <a-row style="display:flex;justify-content:center;align-items:center;">
@@ -122,14 +122,15 @@
                 </a-modal>
                 <!-- 进退货区域END -->
                 <!-- 更多设置弹窗 -->
-                <a-modal destroyOnClose title="详细设置" closable :visible="moreSetVisible" @ok="handleMoreSetOk" @cancel="()=>{moreSetVisible=false}"
+                <moreSet ref='modalSet' @ok="onSave" />
+                <!-- <a-modal destroyOnClose title="详细设置" closable :visible="moreSetVisible" @ok="handleMoreSetOk" @cancel="()=>{moreSetVisible=false}"
                  width="70%" >
                     <a-card style="width:100%" :tab-list="tabListNoTitle" :active-tab-key="noTitleKey"
                      @tabChange="key => onTabChange(key, 'noTitleKey')">
                         <Commodity v-if="noTitleKey=='commodity'" />
                         <GoodImg v-if="noTitleKey=='goodImg'" />
                     </a-card>
-                </a-modal>
+                </a-modal> -->
                 <room-layout-form ref="modalForm" @ok="modalFormOk"></room-layout-form>
                 <stock-type-model ref="stockTypeModel" @ok="onSave"></stock-type-model>
             </a-card>
@@ -144,8 +145,9 @@ import { tree, delTree, goodBatchDel, goodSet } from '@/api/good'
 import { JeecgListMixin } from "@/mixins/JeecgListMixin";
 import roomLayoutForm from './goodStock/goods'
 import stockTypeModel from './stockTypeModel.vue'
-import Commodity from './moreSet/commodity.vue'
-import GoodImg from './moreSet/goodImg.vue';
+// import Commodity from './moreSet/commodity.vue'
+// import GoodImg from './moreSet/goodImg.vue';
+import moreSet from './moreSet/moreModal.vue'
 import { computed } from 'vue';
 import SetUnit from './setUnit/index.vue'
 
@@ -175,8 +177,9 @@ export default {
         stockTypeModel,
         roomLayoutForm,
         SetUnit,
-        Commodity,
-        GoodImg
+        moreSet
+        // Commodity,
+        // GoodImg
       },
     data() {
         return {
@@ -482,9 +485,11 @@ export default {
             this.goodsSetData.type = e.target.value
         },
         //更多设置
-        moreSet(e){
-            console.log(e);
-            this.moreSetVisible = true
+        moreSet(record){
+            console.log(this.$refs.modalSet);
+            this.$refs.modalSet.edit(record)
+            this.$refs.modalForm.disableSubmit = false;
+            // this.moreSetVisible = true
         },
         //更多设置确认
         handleMoreSetOk(){

+ 234 - 0
src/views/settings/components/roomModules/mealCouponList.vue

@@ -0,0 +1,234 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+<!--      <a-button type="primary" icon="download" @click="handleExportXls('餐券')">导出</a-button>-->
+<!--      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">-->
+<!--        <a-button type="primary" icon="import">导入</a-button>-->
+<!--      </a-upload>-->
+<!--      &lt;!&ndash; 高级查询区域 &ndash;&gt;-->
+<!--      <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
+<!--      <a-dropdown v-if="selectedRowKeys.length > 0">-->
+<!--        <a-menu slot="overlay">-->
+<!--          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>-->
+<!--        </a-menu>-->
+<!--        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>-->
+<!--      </a-dropdown>-->
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </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="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <span slot="switchSlot" slot-scope="text,record">
+          <a-switch checked-children="开启" un-checked-children="禁用"
+                    default-checked :checked="text == 0" @change="e=>onAutoChange(e)" />
+        </span>
+        <template slot="startSlot" slot-scope="text,record">
+          <div style="display: flex;align-items: center">
+            <a-form style="width: 90%">
+              <a-form-item prop="startTime" style="margin-bottom: 0px">
+                <a-time-picker format="HH:mm" :minuteStep="5" :default-value="moment(text, 'HH:mm')"
+                               :allowClear="false" @change="onChange" />
+              </a-form-item>
+            </a-form>
+            <!--                    <a-input v-model="text" placeholder="请输入关联号" @change="(e)=>handleNumber(e,record)" ></a-input>-->
+          </div>
+        </template>
+        <template slot="endSlot" slot-scope="text,record">
+          <div style="display: flex;align-items: center">
+            <a-form style="width: 90%">
+              <a-form-item prop="associationNumber" style="margin-bottom: 0px">
+                <a-form-item prop="startTime" style="margin-bottom: 0px">
+                  <a-time-picker format="HH:mm" :minuteStep="5" :default-value="moment(text, 'HH:mm')"
+                                 :allowClear="false" @change="onChange" />
+                </a-form-item>
+              </a-form-item>
+            </a-form>
+            <!--                    <a-input v-model="text" placeholder="请输入关联号" @change="(e)=>handleNumber(e,record)" ></a-input>-->
+          </div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+
+    <meal-coupon-modal ref="modalForm" @ok="modalFormOk"></meal-coupon-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import mealCouponModal from './modules/mealCouponModal'
+  import moment from 'moment';
+
+  export default {
+    name: 'mealCouponList',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+      mealCouponModal
+    },
+    data () {
+      return {
+        description: '餐券管理页面',
+        // 表头
+        columns: [
+          {
+            title:'餐券类型名称',
+            align:"center",
+            dataIndex: 'name'
+          },
+          {
+            title:'是否自动发放',
+            align:"center",
+            dataIndex: 'automaticGrant',
+            // customRender:function (text) {
+            //   return text==1?'true':'false'
+            // },
+            scopedSlots: { customRender: 'switchSlot' },
+          },
+          {
+            title:'是否启用',
+            align:"center",
+            dataIndex: 'status',
+            // customRender:function (text) {
+            //   return text==1?'true':'false'
+            // },
+            scopedSlots: { customRender: 'switchSlot' },
+          },
+          {
+            title:'开始时间',
+            align:"center",
+            dataIndex: 'startTime',
+            scopedSlots: { customRender: 'startSlot' },
+          },
+          {
+            title:'结束时间',
+            align:"center",
+            dataIndex: 'endTime',
+            scopedSlots: { customRender: 'endSlot' },
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: "/business/busMealCoupon/list",
+          delete: "/business/busMealCoupon/delete",
+          deleteBatch: "/business/busMealCoupon/deleteBatch",
+          exportXlsUrl: "/business/busMealCoupon/exportXls",
+          importExcelUrl: "business/busMealCoupon/importExcel",
+
+        },
+        dictOptions:{},
+        superFieldList:[],
+      }
+    },
+    created() {
+    this.getSuperFieldList();
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+    },
+    methods: {
+      moment,
+      initDictConfig(){
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'string',value:'tenantId',text:'关联租户'})
+        fieldList.push({type:'string',value:'hotelId',text:'关联酒店'})
+        fieldList.push({type:'string',value:'name',text:'餐券名称'})
+        fieldList.push({type:'int',value:'automaticGrant',text:'自动发放(0-开启;1-关闭)'})
+        fieldList.push({type:'date',value:'startTime',text:'开始时间'})
+        fieldList.push({type:'date',value:'endTime',text:'结束时间'})
+        fieldList.push({type:'int',value:'status',text:'状态(0-开启;1-关闭)'})
+        fieldList.push({type:'int',value:'delFlag',text:'删除状态(0-正常,1-已删除)'})
+        this.superFieldList = fieldList
+      },
+      onAutoChange(){
+
+      },
+      onChange(){
+
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>

+ 179 - 0
src/views/settings/components/roomModules/modules/mealCouponForm.vue

@@ -0,0 +1,179 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="餐券类型名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="name">
+              <a-input v-model="model.name" placeholder="请输入餐券类型名称"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+                    :labelCol="labelCol"
+                    :wrapperCol="wrapperCol"
+                    label="自动发放"
+                    prop="automaticGrant">
+              <a-switch checkedChildren="开启" unCheckedChildren="禁用" v-model="model.automaticGrant"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+                    :labelCol="labelCol"
+                    :wrapperCol="wrapperCol"
+                    label="启用"
+                    prop="status">
+              <a-switch checkedChildren="开启" unCheckedChildren="禁用" v-model="model.status"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="开始时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="startTime">
+<!--              <j-date placeholder="请选择开始时间" v-model="model.startTime"  style="width: 100%" />-->
+              <a-time-picker format="HH:mm" :minuteStep="5" v-model="model.startTime" @change="onChange" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="结束时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="endTime">
+<!--              <j-date placeholder="请选择结束时间" v-model="model.endTime"  style="width: 100%" />-->
+              <a-time-picker format="HH:mm" :minuteStep="5" v-model="model.endTime" @change="onChange" />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+  import moment from 'moment';
+
+  export default {
+      name: 'BusMealCouponForm',
+      components: {},
+      props: {
+          //表单禁用
+          disabled: {
+              type: Boolean,
+              default: false,
+              required: false
+          }
+      },
+      data() {
+          return {
+              model: {},
+              labelCol: {
+                  xs: {span: 24},
+                  sm: {span: 5},
+              },
+              wrapperCol: {
+                  xs: {span: 24},
+                  sm: {span: 16},
+              },
+              confirmLoading: false,
+              validatorRules: {
+                  name: [
+                      {required: true, message: '请输入餐券名称!'},
+                  ],
+              },
+              url: {
+                  add: "/business/busMealCoupon/add",
+                  edit: "/business/busMealCoupon/edit",
+                  queryById: "/business/busMealCoupon/queryById"
+              }
+          }
+      },
+      computed: {
+          formDisabled() {
+              return this.disabled
+          },
+      },
+      created() {
+          //备份model原始值
+          this.modelDefault = JSON.parse(JSON.stringify(this.model));
+      },
+      methods: {
+          moment,
+          add() {
+              this.edit(this.modelDefault);
+          },
+          edit(record) {
+              this.model = Object.assign({}, record);
+              this.visible = true;
+              console.log(record)
+              if (this.model.status == 0) {
+                  this.model.status = true;
+              } else {
+                  this.model.status = false;
+              }
+
+              if (this.model.automaticGrant == 0) {
+                  this.model.automaticGrant = true;
+              } else {
+                  this.model.automaticGrant = false;
+              }
+
+              if (!this.model.id) {
+                  // this.model.startTime = moment('06:00', "HH:mm")
+                  // this.model.endTime = moment("09:00", "HH:mm")
+              }else{
+                  this.model.startTime = moment(record.startTime, "HH:mm")
+                  this.model.endTime = moment(record.endTime, "HH:mm")
+              }
+
+
+              console.log(this.model)
+          },
+          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';
+                          var info = JSON.parse(localStorage.getItem("storeInfo"));
+                          this.model.hotelId = info.id;
+                      } else {
+                          httpurl += this.url.edit;
+                          method = 'put';
+                      }
+
+                      var data = this.model;
+                      if (this.model.status) {
+                          data.status = 0;
+                      } else {
+                          data.status = 1;
+                      }
+                      if (this.model.automaticGrant) {
+                          data.automaticGrant = 0;
+                      } else {
+                          data.automaticGrant = 1;
+                      }
+                      data.startTime = this.model.startTime.format("HH:mm:ss")
+                      data.endTime = this.model.endTime.format("HH:mm:ss")
+                      httpAction(httpurl, data, method).then((res) => {
+                          if (res.success) {
+                              that.$message.success(res.message);
+                              that.$emit('ok');
+                          } else {
+                              that.$message.warning(res.message);
+                          }
+                      }).finally(() => {
+                          that.confirmLoading = false;
+                      })
+                  }
+
+              })
+          },
+          onChange() {
+
+          }
+      }
+  }
+</script>

+ 84 - 0
src/views/settings/components/roomModules/modules/mealCouponModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <meal-coupon-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></meal-coupon-form>
+    <div class="drawer-footer">
+      <a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
+      <a-button v-if="!disableSubmit"  @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
+    </div>
+  </a-drawer>
+</template>
+
+<script>
+
+  import mealCouponForm from './mealCouponForm'
+
+  export default {
+    name: 'mealCouponModal',
+    components: {
+      mealCouponForm
+    },
+    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;
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+/** Button按钮间距 */
+  .ant-btn {
+    margin-left: 30px;
+    margin-bottom: 30px;
+    float: right;
+  }
+  .drawer-footer{
+    position: absolute;
+    bottom: -8px;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+</style>

+ 60 - 0
src/views/settings/components/roomModules/modules/mealCouponModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <meal-coupon-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></meal-coupon-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import mealCouponForm from './mealCouponForm'
+  export default {
+    name: 'mealCouponModal',
+    components: {
+      mealCouponForm
+    },
+    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>

+ 24 - 13
src/views/settings/components/roomModules/moreSet/commodity.vue

@@ -12,31 +12,32 @@
             <a-row>
                 <a-col :span="12" type='flex' justify="start">
                     <a-form-model-item style="width:100%" label="能否储值卡" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="">
-                        <a-switch :checked="model.appState" @change="switchState" ></a-switch>
+                        <a-switch :checked="model.canStoreCard" @change="storeChange" ></a-switch>
                     </a-form-model-item>
                 </a-col>
             </a-row>
             <a-row>
                 <a-col :span="12">
                     <a-form-model-item label="能否积分支付" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="">
-                        <a-switch :checked="model.appState" @change="switchState" ></a-switch>
+                        <a-switch :checked="model.canIntegralPay" @change="integralPayChange" ></a-switch>
                     </a-form-model-item>
                 </a-col>
             </a-row>
             <a-row>
                 <a-col :span="12">
                     <a-form-model-item label="积分支付价格" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="">
-                        <a-input-number v-model="model.bid" :min="0" />
+                        <a-input-number v-model="model.integralPrice" :min="0" />
                     </a-form-model-item>
                 </a-col>
             </a-row>
             <a-row>
                 <a-col :span="24">
                     <a-form-model-item label="描述" :labelCol="{span:'2',offset:'0'}" :wrapperCol="wrapperCol" prop="">
-                        <j-editor />
+                        <j-editor v-model="model.remark" />
                     </a-form-model-item>
                 </a-col>
             </a-row>
+            <a-button @click="submitForm">确认</a-button>
         </a-form-model>
 
     </j-form-container>
@@ -78,7 +79,9 @@ export default {
                 purchases:null,
                 salesVolume:null,
                 inventory:null,
-                appState:null
+                appState:false,
+                canStoreCard:false,
+                canIntegralPay:false
             },
             labelCol: {
                 xs: {
@@ -203,15 +206,15 @@ export default {
             this.model = JSON.parse(JSON.stringify(record))
             
             console.log(this.filterType(this.treeData, record.goodType));
-            console.log(this.arr);
+            console.log(this.model);
             this.visible = true;
-            getSelectList({
-                id: this.model.id
-            }).then((res) => {
-                if (res.success) {
-                    this.members = res.result;
-                }
-            });
+            // getSelectList({
+            //     id: this.model.id
+            // }).then((res) => {
+            //     if (res.success) {
+            //         this.members = res.result;
+            //     }
+            // });
         },
         submitForm() {
             const that = this;
@@ -258,6 +261,14 @@ export default {
         switchState(e){
             console.log('这是滑动按钮触发',e);
             this.model.appState = e
+        },
+        storeChange(e){
+            console.log(e);
+            this.model.canStoreCard = e
+        },
+        integralPayChange(e){
+            console.log(e);
+            this.model.canIntegralPay = e
         }
     },
 };

+ 133 - 0
src/views/settings/components/roomModules/moreSet/foodSet.vue

@@ -0,0 +1,133 @@
+<template>
+<a-space direction="vertical" style="width:100%">
+    <a-card title="商品规格" style="width: 100%">
+        <a-row :gutter="[6,38]" v-for="(item, index) in specsData" :key="item.id">
+            <a-col :span="4">
+                <a-input placeholder="商品规格" v-model="item.specs"></a-input>
+            </a-col>
+            <a-col :span="4">
+                <a-input-number :min="0.0" style="width:100%" v-model="item.number"></a-input-number>
+            </a-col>
+            <a-col :span="2">
+                <a-button @click="delSpecs(index)">删除</a-button>
+            </a-col>
+        </a-row>
+        <a-row>
+            <a-col>
+                <a-button @click="addSpecs">添加规格</a-button>
+            </a-col>
+        </a-row>
+    </a-card>
+    <a-card title="商品口味" style="width: 100%">
+        <a-row :gutter="[6,38]" v-for="(item, index) in specsData" :key="item.id">
+            <a-col :span="4">
+                <a-input placeholder="商品规格" v-model="item.specs"></a-input>
+            </a-col>
+            <a-col :span="4">
+                <a-input-number :min="0.0" style="width:100%" v-model="item.number"></a-input-number>
+            </a-col>
+            <a-col :span="2">
+                <a-button @click="delSpecs(index)">删除</a-button>
+            </a-col>
+        </a-row>
+        <a-row>
+            <a-col>
+                <a-button @click="addTasta">添加口味</a-button>
+            </a-col>
+        </a-row>
+    </a-card>
+    <a-card title="商品加料" style="width: 100%">
+        <a-row :gutter="[6,38]" v-for="(item, index) in specsData" :key="item.id">
+            <a-col :span="4">
+                <a-input placeholder="商品规格" v-model="item.specs"></a-input>
+            </a-col>
+            <a-col :span="4">
+                <a-input-number :min="0.0" style="width:100%" v-model="item.number"></a-input-number>
+            </a-col>
+            <a-col :span="2">
+                <a-button @click="delSpecs(index)">删除</a-button>
+            </a-col>
+        </a-row>
+        <a-row>
+            <a-col>
+                <a-button @click="addMaterial">选择加料</a-button>
+            </a-col>
+        </a-row>
+    </a-card>
+    <a-card style="width: 100%">
+        <a-row>
+            <a-col :span="2">是否启用厨打</a-col>
+            <a-col :span="22">
+                <a-switch checked-children="是" un-checked-children="否" v-model="modelData.beat" />
+            </a-col>
+        </a-row>
+        <a-row>
+            <a-col :span="2">是否计重</a-col>
+            <a-col :span="22">
+                <a-switch checked-children="是" un-checked-children="否" v-model="modelData.weighDown" />
+            </a-col>
+        </a-row>
+    </a-card>
+    <a-button>确认</a-button>
+    <j-modal :title="'口味选择'" :width="'70%'" :visible="tastaVisible" switchFullscreen @ok="handleOk" :okButtonProps="{ class:{'jee-hidden': disableSubmit} }" @cancel="tastaVisible=false" cancelText="关闭">
+        <tastaTable />
+    </j-modal>
+    <j-modal :title="'加料选择'" :width="'70%'" :visible="materialVisible" switchFullscreen @ok="handleMateriaOk" :okButtonProps="{ class:{'jee-hidden': disableSubmit} }" @cancel="materialVisible=false" cancelText="关闭">
+        <materialTableVue />
+    </j-modal>
+</a-space>
+</template>
+
+<script>
+import materialTableVue from './materialTable.vue';
+import tastaTable from './tastaTable.vue';
+export default {
+    components:{
+        tastaTable,
+        materialTableVue
+    },
+    data() {
+        return {
+            specsData: [],
+            tastaVisible:false,
+            materialVisible:false,
+            modelData:{
+                beat:true,
+                weighDown:false
+            }
+        }
+    },
+    methods: {
+        //删除规格
+        delSpecs(index) {
+            console.log(index);
+            this.specsData.splice(index, 1)
+        },
+        //添加规格
+        addSpecs() {
+            this.specsData.push({
+                specs: '',
+                number: null
+            })
+        },
+        addTasta() {
+            this.tastaVisible = true
+        },
+        handleOk(){
+            this.tastaVisible = false
+        },
+        handleCancel(){},
+        //加料
+        addMaterial(){
+            this.materialVisible = true
+        },
+        handleMateriaOk(){
+            this.materialVisible = false
+        }
+    }
+}
+</script>
+
+<style>
+
+</style>

+ 163 - 37
src/views/settings/components/roomModules/moreSet/goodImg.vue

@@ -1,62 +1,98 @@
 <template>
   <div class="clearfix">
-        <a-row>
-            <a-col>商品大图</a-col>
-            <a-col>
-                <a-upload action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
-                list-type="picture-card"
-                :file-list="fileList"
-                @preview="handlePreview"
-                @change="handleChange">
-                <div v-if="fileList.length < 8">
-                    <a-icon type="plus" />
-                    <div class="ant-upload-text">
-                    Upload
-                    </div>
-                </div>
-                </a-upload>
-            </a-col>
-        </a-row>
-        <a-row>
-            <a-col>图片</a-col>
-            <a-col>
-                <a-upload action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
-                list-type="picture-card"
-                :file-list="fileList"
-                @preview="handlePreview"
-                @change="handleChange">
-                <div v-if="fileList.length < 8">
-                    <a-icon type="plus" />
-                    <div class="ant-upload-text">
-                    Upload
-                    </div>
-                </div>
-                </a-upload>
-            </a-col>
-        </a-row>
+    <a-row>
+      <a-col>商品大图</a-col>
+      <a-col>
+        <a-upload
+          action="/rooms/cesGoods/modify"
+          list-type="picture-card"
+          :file-list="fileList"
+          @preview="handlePreview"
+          @change="handleChange"
+        >
+          <div v-if="fileList.length < 1">
+            <a-icon type="plus" />
+            <!-- <div class="ant-upload-text">Upload</div> -->
+          </div>
+        </a-upload>
+      </a-col>
+    </a-row>
+    <a-row>
+      <a-col>图片</a-col>
+      <a-col>
+        <a-upload
+          action="#"
+          list-type="picture-card"
+          :file-list="fileListImgs"
+          @preview="handlePreview"
+          @change="handleChangeImgs"
+        >
+          <div v-if="fileList.length < 8">
+            <a-icon type="plus" />
+            <!-- <div class="ant-upload-text">Upload</div> -->
+          </div>
+        </a-upload>
+      </a-col>
+    </a-row>
+    <a-button @click="submitImg">确认</a-button>
     <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
       <img alt="example" style="width: 100%" :src="previewImage" />
     </a-modal>
   </div>
 </template>
+
 <script>
 function getBase64(file) {
   return new Promise((resolve, reject) => {
     const reader = new FileReader();
     reader.readAsDataURL(file);
     reader.onload = () => resolve(reader.result);
-    reader.onerror = error => reject(error);
+    reader.onerror = (error) => reject(error);
   });
 }
+import { httpAction, getAction } from "@/api/manage";
 export default {
+  inject:['modelData'],
   data() {
     return {
       previewVisible: false,
-      previewImage: '',
+      previewImage: "",
       fileList: [],
+      fileListImgs: [],
+      model: {
+        id: "",
+        hotelId: 0,
+        goodType: "",
+        goodUnit: "",
+        barCode: "",
+        bid: null,
+        name: "",
+        sellingPrice: "",
+        purchases: null,
+        salesVolume: null,
+        inventory: null,
+        appState: false,
+        canStoreCard: false,
+        canIntegralPay: false,
+      },
+      url: {
+        edit: "/rooms/cesGoods/modify",
+      },
     };
   },
+  created(){
+    console.log(this.model);
+  },
   methods: {
+    getStartData(){
+      this.model = this.modelData
+      if (this.model.cover) {
+        this.fileList.push(this.model.cover);
+      }
+      if (this.model.images) {
+        this.fileListImgs = this.model.images.split(",");
+      }
+    },
     handleCancel() {
       this.previewVisible = false;
     },
@@ -68,11 +104,101 @@ export default {
       this.previewVisible = true;
     },
     handleChange({ fileList }) {
+      console.log(fileList);
       this.fileList = fileList;
     },
+    handleChangeImgs({ fileList }) {
+      console.log(fileList);
+      this.fileListImgs = fileList;
+    },
+    edit(record) {
+      console.log(22222222, record);
+      this.model = JSON.parse(JSON.stringify(record));
+      if (this.model.cover) {
+        this.fileList.push(this.model.cover);
+      }
+      if (this.model.images) {
+        this.fileListImgs = this.model.images.split(",");
+      }
+      // console.log(this.filterType(this.treeData, record.goodType));
+      // console.log(this.arr);
+      this.visible = true;
+      // getSelectList({
+      //   id: this.model.id,
+      // }).then((res) => {
+      //   if (res.success) {
+      //     this.members = res.result;
+      //   }
+      // });
+    },
+    //修改图片
+    submitImg() {
+      const that = this;
+      that.confirmLoading = true;
+      let httpurl = "";
+      let method = "";
+      httpurl += this.url.edit;
+      method = "put";
+      if (this.model.payFlag == 0) {
+        this.model.payAmount = 0;
+      }
+      this.model.cover = this.fileList[0].thumbUrl;
+      let arr=[] 
+      this.fileListImgs.forEach(ele=>{
+        arr.push(ele.thumbUrl)
+      })
+      this.model.images = arr.toString()
+      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;
+        });
+    },
+    submitForm() {
+      const that = this;
+      // 触发表单验证
+      debugger;
+      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>
 /* you can make up upload button and sample style by using stylesheets */
 .ant-upload-select-picture-card i {
@@ -84,4 +210,4 @@ export default {
   margin-top: 8px;
   color: #666;
 }
-</style>
+</style>

+ 101 - 0
src/views/settings/components/roomModules/moreSet/materialTable.vue

@@ -0,0 +1,101 @@
+<template>
+<div>
+    <a-row :gutter="[6,38]">
+        <a-col :span="4">
+            <j-input placeholder="商品名称" v-model="queryParam.name" style="width: 200px"></j-input>
+        </a-col>
+        <a-col :span="4">
+            <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+        </a-col>
+    </a-row>
+    <a-table ref="table" size="middle" bordered rowKey="id" :columns="columns" :dataSource="dataSource" :pagination="ipagination" :loading="loading" :rowSelection="{
+      selectedRowKeys: selectedRowKeys,
+      onChange: onSelectChange,
+    }" class="j-table-force-nowrap" @change="handleTableChange">
+        <span slot="state" slot-scope="record">
+            {{ record ? "启用" : "停用" }}
+            <!-- {{record}} -->
+        </span>
+        <!-- <span slot="action" slot-scope="text, record">
+        <a @click="handleEdit(record)">修改</a>
+        <a-divider type="vertical" />
+        <a @click="moreSet(record)">更多设置</a>
+        <a-divider type="vertical" />
+        <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+            <a>删除</a>
+        </a-popconfirm>
+    </span> -->
+    </a-table>
+</div>
+</template>
+
+<script>
+import {
+    JeecgListMixin
+} from "@/mixins/JeecgListMixin";
+export default {
+    mixins: [JeecgListMixin],
+    data() {
+        return {
+            // 表头
+            columns: [{
+                    title: "加料名称",
+                    align: "center",
+                    dataIndex: "hotelName",
+                    customCell: () => {
+                        return {
+                            style: {
+                                wordWrap: "break-word",
+                                wordBreak: "break-all",
+                                whiteSpace: "normal",
+                                minHeight: "50px",
+                                width: "50px",
+                            },
+                        };
+                    },
+                },
+                {
+                    title: "加料金额",
+                    align: "center",
+                    dataIndex: "typeName",
+                    customCell: () => {
+                        return {
+                            style: {
+                                wordWrap: "break-word",
+                                wordBreak: "break-all",
+                                whiteSpace: "normal",
+                                minHeight: "50px",
+                                width: "50px",
+                            },
+                        };
+                    },
+                },
+                {
+                    title: "状态",
+                    align: "center",
+                    dataIndex: "unitName",
+                    customCell: () => {
+                        return {
+                            style: {
+                                wordWrap: "break-word",
+                                wordBreak: "break-all",
+                                whiteSpace: "normal",
+                                minHeight: "50px",
+                                width: "50px",
+                            },
+                        };
+                    },
+                },
+                {
+                    title: "创建时间",
+                    align: "center",
+                    dataIndex: "bid",
+                },
+            ],
+        };
+    },
+};
+</script>
+
+<style>
+</style>

+ 107 - 0
src/views/settings/components/roomModules/moreSet/moreModal.vue

@@ -0,0 +1,107 @@
+<template>
+<!-- <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <bus-market-member-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-market-member-form>
+  </j-modal> -->
+<j-modal destroyOnClose title="详细设置" :width="'70%'" :footer="null" :visible="visible" :okButtonProps="{ class:{'jee-hidden': disableSubmit} }" @ok="handleOk" @cancel="handleCancel">
+    <a-card style="width:100%" :tab-list="tabListNoTitle" :active-tab-key="noTitleKey" @tabChange="key => onTabChange(key, 'noTitleKey')">
+        <BusMarketMemberForm ref="realForm" @ok="submitCallback" :disabled="disableSubmit" v-show="noTitleKey=='commodity'" />
+        <GoodImg @saveOk="handleCancel" ref="goodImg" v-show="noTitleKey=='goodImg'" />
+        <FoodSet v-show="noTitleKey=='foodSet'" />
+    </a-card>
+</j-modal>
+</template>
+
+<script>
+const tabListNoTitle=[
+        {
+          key: 'commodity',
+          tab: '商品小程序设置',
+        },
+        {
+          key: 'goodImg',
+          tab: '商品图片',
+        },
+        {
+          key: 'foodSet',
+          tab: '餐饮设置',
+        }
+      ]
+import BusMarketMemberForm from './commodity.vue'
+// import GoodImg from './goodImg.vue'
+import GoodImg from '../roomLayoutDetailForm/roomLayoutImage.vue'
+import FoodSet from './foodSet.vue'
+import { computed } from 'vue'
+export default {
+    name: 'BusMarketMemberModal',
+    components: {
+        BusMarketMemberForm,
+        GoodImg,
+        FoodSet
+    },
+    data() {
+        return {
+            title: '',
+            width: 800,
+            visible: false,
+            disableSubmit: false,
+            tabListNoTitle,
+            key: 'tab1',
+            noTitleKey: 'commodity',
+            model:{}
+        }
+    },
+    provide(){
+        return{
+            modelData:computed(()=> this.model)
+        }
+    },
+    methods: {
+        add() {
+            this.visible = true
+            this.$nextTick(() => {
+                this.$refs.realForm.add();
+            })
+        },
+        edit(record) {
+            console.log(record);
+            this.visible = true
+            this.$nextTick(() => {
+                this.model = record
+                this.$refs.realForm.edit(record);
+                console.log('refs.realForm',this.$refs.realForm);
+            })
+        },
+        close() {
+            this.$emit('close');
+            this.visible = false;
+        },
+        handleOk() {
+            this.$refs.realForm.submitForm();
+        },
+        submitCallback() {
+            this.$emit('ok');
+            this.visible = false;
+        },
+        handleCancel() {
+            this.close()
+        },
+        //更多设置切换卡片
+        onTabChange(key, type) {
+            console.log(key, type);
+            this[type] = key;
+            if (key = 'goodImg') {
+                this.model.url = true
+                this.$refs.goodImg.setData(this.model)
+            }
+        },
+    }
+}
+</script>

+ 111 - 0
src/views/settings/components/roomModules/moreSet/tastaTable.vue

@@ -0,0 +1,111 @@
+<template>
+<div>
+    <a-row :gutter="[6,38]">
+        <a-col :span="4">
+            <j-input placeholder="商品名称" v-model="queryParam.name" style="width: 200px"></j-input>
+        </a-col>
+        <a-col :span="4">
+            <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+        </a-col>
+    </a-row>
+    <a-table ref="table" size="middle" bordered rowKey="id" :columns="columns" :dataSource="dataSource" :pagination="ipagination" :loading="loading" :rowSelection="{
+      selectedRowKeys: selectedRowKeys,
+      onChange: onSelectChange,
+    }" class="j-table-force-nowrap" @change="handleTableChange">
+        <span slot="state" slot-scope="record">
+            {{ record ? "启用" : "停用" }}
+            <!-- {{record}} -->
+        </span>
+        <!-- <span slot="action" slot-scope="text, record">
+        <a @click="handleEdit(record)">修改</a>
+        <a-divider type="vertical" />
+        <a @click="moreSet(record)">更多设置</a>
+        <a-divider type="vertical" />
+        <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+            <a>删除</a>
+        </a-popconfirm>
+    </span> -->
+    </a-table>
+</div>
+</template>
+
+<script>
+import {
+    JeecgListMixin
+} from "@/mixins/JeecgListMixin";
+export default {
+    mixins: [JeecgListMixin],
+    data() {
+        return {
+            // 表头
+            columns: [{
+                    title: "口味名称",
+                    align: "center",
+                    dataIndex: "hotelName",
+                    customCell: () => {
+                        return {
+                            style: {
+                                wordWrap: "break-word",
+                                wordBreak: "break-all",
+                                whiteSpace: "normal",
+                                minHeight: "50px",
+                                width: "50px",
+                            },
+                        };
+                    },
+                },
+                {
+                    title: "加价金额",
+                    align: "center",
+                    dataIndex: "typeName",
+                    customCell: () => {
+                        return {
+                            style: {
+                                wordWrap: "break-word",
+                                wordBreak: "break-all",
+                                whiteSpace: "normal",
+                                minHeight: "50px",
+                                width: "50px",
+                            },
+                        };
+                    },
+                },
+                {
+                    title: "状态",
+                    align: "center",
+                    dataIndex: "unitName",
+                    customCell: () => {
+                        return {
+                            style: {
+                                wordWrap: "break-word",
+                                wordBreak: "break-all",
+                                whiteSpace: "normal",
+                                minHeight: "50px",
+                                width: "50px",
+                            },
+                        };
+                    },
+                },
+                {
+                    title: "应用范围",
+                    align: "center",
+                    dataIndex: "barCode",
+                },
+                {
+                    title: "备注",
+                    align: "center",
+                    dataIndex: "name",
+                },
+                {
+                    title: "创建时间",
+                    align: "center",
+                    dataIndex: "bid",
+                },
+            ],
+        };
+    },
+};
+</script>
+
+<style>
+</style>

+ 39 - 0
src/views/settings/components/roomModules/roomLayoutDetailForm/roomLayoutImage.vue

@@ -15,6 +15,7 @@
 
 <script>
 import { modify } from '@/api/roomLayout'
+import { editGood } from '@/api/good'
 export default {
     name: 'HotelSaasTenantFrontendRoomLayoutImage',
 
@@ -39,6 +40,9 @@ export default {
     methods: {
         setData(data) {
             this.model = JSON.parse(JSON.stringify(data))
+            if (!data.picture) {
+                this.model.picture = data.images
+            }
         },
         submitForm() {
             const that = this;
@@ -47,6 +51,41 @@ export default {
                 if (valid) {
                     let data = JSON.parse(JSON.stringify(this.model))
                     that.confirmLoading = true;
+                    // debugger
+                    console.log('datadatadatadata',data);
+                    if (data.url) {
+                        editGood({
+                            id: data.id,
+                            hotelId: data.hotelId,
+                            name: data.name,
+                            images: data.picture,
+                            goodUnit: data.goodUnit,
+                            goodType: data.goodType,
+                            barCode: data.barCode,
+                            bid: data.bid,
+                            sellingPrice: data.sellingPrice,
+                            purchases: data.purchases,
+                            salesVolume: data.salesVolume,
+                            marketPrice: data.marketPrice,
+                            inventory: data.inventory,
+                            appState: data.appState,
+                            // 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;
+                        })
+                        return
+                    }
                     modify({
                         id: data.id,
                         hotelId: data.hotelId,

+ 35 - 2
src/views/settings/roomSettings.vue

@@ -21,7 +21,7 @@
                     <a-icon type="shop" />
                     商品库存
                 </span>
-               <goodList></goodList>     
+               <goodList></goodList>
             </a-tab-pane>
             <a-tab-pane key="4">
                 <span slot="tab">
@@ -36,6 +36,37 @@
                     钟点房计费
                 </span>
             </a-tab-pane>
+            <a-tab-pane key="6">
+                <span slot="tab">
+                    <a-icon type="file" />
+                    房价方案
+                </span>
+            </a-tab-pane>
+            <a-tab-pane key="7">
+                <span slot="tab">
+                    <a-icon type="thunderbolt" />
+                    水电煤设置
+                </span>
+            </a-tab-pane>
+            <a-tab-pane key="8">
+                <span slot="tab">
+                    <a-icon type="tool" />
+                    服务维修设置
+                </span>
+            </a-tab-pane>
+            <a-tab-pane key="9">
+                <span slot="tab">
+                    <a-icon type="flag" />
+                    销售目标设置
+                </span>
+            </a-tab-pane>
+            <a-tab-pane key="10">
+                <span slot="tab">
+                    <a-icon type="pound" />
+                    餐券设置
+                </span>
+                <meal-coupon-list></meal-coupon-list>
+            </a-tab-pane>
         </a-tabs>
     </a-card>
 </template>
@@ -45,8 +76,10 @@ import roomLayoutList from "./components/roomModules/roomLayoutList.vue"
 import goodList from "./components/roomModules/goodList.vue";
 import roomNumList from "./components/roomModules/roomNumSettings/roomNumList.vue";
 import allDaysRule from './components/roomModules/allDaysRoomFeeRule.vue'
+import MealCouponList from "./components/roomModules/mealCouponList";
 export default {
     components: {
+        MealCouponList,
         roomLayoutList,
         goodList,
         roomNumList,
@@ -61,4 +94,4 @@ export default {
 </script>
 
 <style scoped>
-</style>
+</style>

+ 63 - 5
src/views/settings/systemInfo.vue

@@ -18,38 +18,85 @@
             <a-tab-pane key="3">
                 <span slot="tab">
                     <a-icon type="pay" />
-                    支付配置
+                    支付方式
                 </span>
                 <pay-settings></pay-settings>
             </a-tab-pane>
             <a-tab-pane key="4">
                 <span slot="tab">
+                    订单铃声
+                </span>
+                <order-sound-list></order-sound-list>
+            </a-tab-pane>
+            <a-tab-pane key="5">
+                <span slot="tab">
+                    <a-icon type="pay" />
+                    数据管理
+                </span>
+                <div>
+                    <a-form-item>
+                    <a-card title="业务数据" style="width: 300px" :headStyle="{fontWeight: 600}">
+                        <a-checkbox v-model="clearBusiness">
+                            清除全部业务数据
+                        </a-checkbox>
+                    </a-card>
+                    </a-form-item>
+                    <a-button type="primary" @click="toClearBusinessData()">确定清除</a-button>
+                </div>
+            </a-tab-pane>
+            <a-tab-pane key="6">
+                <span slot="tab">
+                    <a-icon type="pay" />
+                    门锁管理
+                </span>
+                <door-lock-list></door-lock-list>
+            </a-tab-pane>
+            <a-tab-pane key="7">
+                <span slot="tab">
                     <a-icon type="payinterface" />
                     支付接口配置
                 </span>
                 <pay-api-settings></pay-api-settings>
             </a-tab-pane>
-            <a-tab-pane key="5">
+            <a-tab-pane key="8">
                 <span slot="tab">
                     <a-icon type="parameter" />
                     参数配置
                 </span>
                 <param-settings></param-settings>
             </a-tab-pane>
-            <a-tab-pane key="6">
+            <a-tab-pane key="9">
                 <span slot="tab">
                     <a-icon type="waiter" />
                     服务员配置
                 </span>
                 <waiter-settings></waiter-settings>
             </a-tab-pane>
-            <a-tab-pane key="7">
+            <a-tab-pane key="10">
                 <span slot="tab">
                     <a-icon type="salesperson" />
                     营销人员管理
                 </span>
                 <sales-person-info></sales-person-info>
             </a-tab-pane>
+            <a-tab-pane key="11">
+                <span slot="tab">
+                    <a-icon type="salesperson" />
+                    密码锁接口管理
+                </span>
+            </a-tab-pane>
+            <a-tab-pane key="12">
+                <span slot="tab">
+                    <a-icon type="salesperson" />
+                    云打印机设置
+                </span>
+            </a-tab-pane>
+            <a-tab-pane key="13">
+                <span slot="tab">
+                    <a-icon type="salesperson" />
+                    公安接口配置
+                </span>
+            </a-tab-pane>
         </a-tabs>
     </a-card>
 </template>
@@ -62,8 +109,12 @@
     import WaiterSettings from "./components/waiterSettings";
     import SalesPersonInfo from "./components/salesPersonInfo";
     import DictionaryInfo from "./components/dictionaryInfo";
+    import OrderSoundList from "./components/orderSoundList";
+    import DoorLockList from "./components/doorLockList";
     export default {
         components:{
+            DoorLockList,
+            OrderSoundList,
             DictionaryInfo,
             SalesPersonInfo,
             WaiterSettings,
@@ -74,7 +125,14 @@
         },
         data() {
             return {
-
+                clearBusiness:false
+            }
+        },
+        methods:{
+            toClearBusinessData(){
+                if (this.clearBusiness){
+                    console.log('清除数据')
+                }
             }
         }
     }