Forráskód Böngészése

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

gqx 2 éve
szülő
commit
fbe7d0973e
37 módosított fájl, 42710 hozzáadás és 98 törlés
  1. 39719 0
      package-lock.json
  2. 1 1
      public/index.html
  3. 17 2
      src/api/api.js
  4. 17 0
      src/api/good.js
  5. 1 1
      src/components/layouts/TabLayout.vue
  6. 14 14
      src/components/tools/UserMenu.vue
  7. 7 0
      src/utils/excloudHotelIdParamPath/CesRoomLayoutPriceController.js
  8. 5 0
      src/utils/excloudHotelIdParamPath/index.js
  9. 17 0
      src/utils/request.js
  10. 1 0
      src/views/settings/components/advertContentList.vue
  11. 30 1
      src/views/settings/components/advertList.vue
  12. 40 0
      src/views/settings/components/dictionaryInfo.vue
  13. 153 0
      src/views/settings/components/modules/dictItemForm.vue
  14. 84 0
      src/views/settings/components/modules/dictItemModal.Style#Drawer.vue
  15. 252 0
      src/views/settings/components/modules/dictItemModal.vue
  16. 113 0
      src/views/settings/components/modules/dictionaryInfoLeft.vue
  17. 222 0
      src/views/settings/components/modules/dictionaryInfoRight.vue
  18. 172 0
      src/views/settings/components/modules/roomPayTypeForm.vue
  19. 84 0
      src/views/settings/components/modules/roomPayTypeModal.Style#Drawer.vue
  20. 60 0
      src/views/settings/components/modules/roomPayTypeModal.vue
  21. 217 0
      src/views/settings/components/modules/salesPersonForm.vue
  22. 84 0
      src/views/settings/components/modules/salesPersonModal.Style#Drawer.vue
  23. 60 0
      src/views/settings/components/modules/salesPersonModal.vue
  24. 261 4
      src/views/settings/components/paySettings.vue
  25. 0 1
      src/views/settings/components/roomModules/RoomLayoutPriceModal.vue
  26. 197 56
      src/views/settings/components/roomModules/RoomQtfPriceTable.vue
  27. 261 0
      src/views/settings/components/roomModules/goodList.vue
  28. 123 4
      src/views/settings/components/roomModules/roomGen.vue
  29. 0 1
      src/views/settings/components/roomModules/roomLayoutForm.vue
  30. 181 0
      src/views/settings/components/roomModules/stockTypeForm.vue
  31. 60 0
      src/views/settings/components/roomModules/stockTypeModel.vue
  32. 236 4
      src/views/settings/components/salesPersonInfo.vue
  33. 1 1
      src/views/settings/components/waiterSettings.vue
  34. 4 1
      src/views/settings/roomSettings.vue
  35. 14 5
      src/views/settings/systemInfo.vue
  36. 1 1
      src/views/user/oauth2/OAuth2Login.vue
  37. 1 1
      vue.config.js

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 39719 - 0
package-lock.json


+ 1 - 1
public/index.html

@@ -250,7 +250,7 @@
     <div id="loader"></div>
     <div class="loader-section section-left"></div>
     <div class="loader-section section-right"></div>
-    <div class="load_title">正在加载 JeecgBoot 低代码平台,请耐心等待
+    <div class="load_title">正在加载,请耐心等待
 
     </div>
   </div>

+ 17 - 2
src/api/api.js

@@ -95,6 +95,12 @@ const getTransitURL = url => `/sys/common/transitRESTful?url=${encodeURIComponen
 const getRoomPlans = (code,params)=>postAction(`/rooms/roomPricePlan/getRoomPlans/${code}`,params);
 //排除指定id列表查询
 const getSelectList = (params)=>getAction(`/org.jeecg.modules.business/busMarketMember/getSelectList/`,params);
+/**
+ * 获取会员等级接口
+ * @param {Object} params
+ * @returns
+ */
+const getVipLevels = (params)=>getAction(`/org.jeecg.modules.business/busMarketMember/list/`,params);
 
 const getBusMarketMemberLablList = (params)=>getAction(`/business/busMarketMemberLable/list`,params);
 const getBusMarketMemberGroupList = (params)=>getAction(`/business/busMarketMemberGroup/list`,params);
@@ -102,6 +108,12 @@ const deleteMarketMemberGroup = (params)=>deleteAction("/business/busMarketMembe
 const deleteMarketMemberLable = (params)=>deleteAction("/business/busMarketMemberLable/delete",params);
 const getBusMarketCouponsList = (params)=>getAction(`/business/busMarketCoupons/list`,params);
 const getBusMarketCouponsCashList = (params)=>getAction(`/business/busMarketCouponsCash/list`,params);
+
+//业务字典管理
+const queryBusDictTreeList = (params)=>getAction("/business/busDict/queryTreeList",params);
+const addBusDictItem = (params)=>postAction("/business/busDictItem/add",params);
+const editBusDictItem = (params)=>putAction("/business/busDictItem/edit",params);
+
 // 中转HTTP请求
 export const transitRESTful = {
   get: (url, parameter) => getAction(getTransitURL(url), parameter),
@@ -173,8 +185,11 @@ export {
   deleteMarketMemberGroup,
   deleteMarketMemberLable,
   getBusMarketCouponsList,
-  getBusMarketCouponsCashList
+  getBusMarketCouponsCashList,
+  getVipLevels,
+  queryBusDictTreeList,
+  addBusDictItem,
+  editBusDictItem
 }
 
 
-

+ 17 - 0
src/api/good.js

@@ -0,0 +1,17 @@
+import { axios } from '@/utils/request'
+
+/**
+ * 获取商品分类
+ * @param {object} parameter 参数
+ * @returns Axios Promise
+ */
+export function tree(parameter) {
+    return axios({
+        url: '/rooms/cesStockType/tree',
+        method: 'get',
+        params: parameter
+    })
+}
+
+
+

+ 1 - 1
src/components/layouts/TabLayout.vue

@@ -183,7 +183,7 @@
        * @param title 要修改的新标题
        */
       changeTitle(title) {
-        let projectTitle = "Jeecg-Boot 企业级低代码平台"
+        let projectTitle = "酒店管理租户端"
         // 首页特殊处理
         if (this.$route.path === indexKey) {
           document.title = projectTitle

+ 14 - 14
src/components/tools/UserMenu.vue

@@ -2,11 +2,11 @@
   <div class="user-wrapper" :class="theme">
     <!-- update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
     <!-- update-begin author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 -->
-    <span class="action" @click="showClick">
+    <!-- <span class="action" @click="showClick">
       <a-icon type="search"></a-icon>
-    </span>
+    </span> -->
     <!-- update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 -->
-    <component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false">
+    <!-- <component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false">
       <a-select
         class="search-input"
         showSearch
@@ -22,15 +22,15 @@
       >
         <a-select-option v-for="(site,index) in searchMenuOptions" :key="index" :value="site.id">{{site.meta.title}}</a-select-option>
       </a-select>
-    </component>
+    </component> -->
     <!-- update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框 -->
     <!-- update-end author:sunjianlei date:20191220 for: 解决全局样式冲突的问题 -->
     <!-- update_end  author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
-    <span class="action">
+    <!-- <span class="action">
       <a class="logout_title" target="_blank" href="http://doc.jeecg.com">
         <a-icon type="question-circle-o"></a-icon>
       </a>
-    </span>
+    </span> -->
     <header-notice class="action"/>
     <a-dropdown>
       <span class="action action-full ant-dropdown-link user-dropdown-menu">
@@ -38,30 +38,30 @@
         <span v-if="isDesktop()">欢迎您,{{ nickname() }}</span>
       </span>
       <a-menu slot="overlay" class="user-dropdown-menu-wrapper">
-        <a-menu-item key="0">
+        <!-- <a-menu-item key="0">
           <router-link :to="{ name: 'account-center' }">
             <a-icon type="user"/>
             <span>个人中心</span>
           </router-link>
-        </a-menu-item>
-        <a-menu-item key="1">
+        </a-menu-item> -->
+        <!-- <a-menu-item key="1">
           <router-link :to="{ name: 'account-settings-base' }">
             <a-icon type="setting"/>
             <span>账户设置</span>
           </router-link>
-        </a-menu-item>
-        <a-menu-item key="3"  @click="systemSetting">
+        </a-menu-item> -->
+        <!-- <a-menu-item key="3"  @click="systemSetting">
            <a-icon type="tool"/>
            <span>系统设置</span>
-        </a-menu-item>
+        </a-menu-item> -->
         <a-menu-item key="4" @click="updatePassword">
           <a-icon type="setting"/>
           <span>密码修改</span>
         </a-menu-item>
-        <a-menu-item key="5" @click="updateCurrentDepart">
+        <!-- <a-menu-item key="5" @click="updateCurrentDepart">
           <a-icon type="cluster"/>
           <span>切换部门</span>
-        </a-menu-item>
+        </a-menu-item> -->
         <a-menu-item key="6" @click="clearCache">
           <a-icon type="sync"/>
           <span>清理缓存</span>

+ 7 - 0
src/utils/excloudHotelIdParamPath/CesRoomLayoutPriceController.js

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

+ 5 - 0
src/utils/excloudHotelIdParamPath/index.js

@@ -0,0 +1,5 @@
+import CesRoomLayoutPrice from './CesRoomLayoutPriceController'
+
+export default [
+    ...CesRoomLayoutPrice.excloudUrls,
+]

+ 17 - 0
src/utils/request.js

@@ -4,6 +4,7 @@ import store from '@/store'
 import { VueAxios } from './axios'
 import router from '@/router/index'
 import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
+import { is } from 'tinymce'
 
 /**
  * 【指定 axios的 baseURL】
@@ -116,8 +117,24 @@ service.interceptors.request.use(config => {
     // lowApp自定义筛选条件
     if ($route.params.lowAppFilter) {
       config.params = {...config.params, ...$route.params.lowAppFilter}
+
+      
       delete $route.params.lowAppFilter
     }
+    
+    
+  }
+
+  const url = config.url
+  const exUrls = require('./excloudHotelIdParamPath/index')
+  if(exUrls.default.findIndex(t=> url.indexOf(t) > -1 ) == -1) {
+    const hotelInfo = JSON.parse(localStorage.getItem('storeInfo'))
+    if(hotelInfo && hotelInfo.id) {
+      if(!config.params) config.params = {}
+      // 如果自己带了参数就不加了
+      let isQueryContain = config.url.indexOf('?')>-1 ? (config.url.split('?')[1].indexOf("hotelId=") > -1 ) : false
+      if(!config.params.hotelId && !isQueryContain) config.params['hotelId'] = hotelInfo.id
+    }
   }
   // update-end--author:sunjianlei---date:20200723---for 如果当前在low-app环境,并且携带了appId,就向Header里传递appId
 

+ 1 - 0
src/views/settings/components/advertContentList.vue

@@ -185,6 +185,7 @@
                     if(res.success){
                         that.$message.success(res.message);
                         that.$emit('ok');
+                        that.loadData(1);
                     }else{
                         that.$message.warning(res.message);
                     }

+ 30 - 1
src/views/settings/components/advertList.vue

@@ -97,6 +97,7 @@
   import { mixinDevice } from '@/utils/mixin'
   import { JeecgListMixin } from '@/mixins/JeecgListMixin'
   import advertModal from './modules/advertModal'
+  import { httpAction, getAction } from '@/api/manage'
 
   export default {
     name: 'BusAdvertList',
@@ -187,7 +188,35 @@
         fieldList.push({type:'int',value:'status',text:'状态(0-禁用;1-启用)'})
         fieldList.push({type:'int',value:'delFlag',text:'删除状态(0-正常,1-已删除)'})
         this.superFieldList = fieldList
-      }
+      },
+        handleStatus(record){
+            var status = record.status;
+            if (record.status === 1) {
+                status = 0;
+            } else {
+                status = 1;
+            }
+            var updateObj = {
+                id: record.id,
+                status: status
+            }
+            var that = this;
+            console.log(that)
+            this.confirmLoading = true;
+            var values = JSON.parse(JSON.stringify(updateObj))
+            console.log(values)
+            httpAction('/business/busAdvert/editStatus',values,'post').then((res)=>{
+                if(res.success){
+                    that.$message.success(res.message);
+                    that.$emit('ok');
+                    that.loadData(1);
+                }else{
+                    that.$message.warning(res.message);
+                }
+            }).finally(() => {
+                that.confirmLoading = false;
+            })
+        },
     }
   }
 </script>

+ 40 - 0
src/views/settings/components/dictionaryInfo.vue

@@ -0,0 +1,40 @@
+<template>
+    <a-row type="flex" :gutter="16" class="container">
+        <a-col :md="5" :sm="24">
+            <dictionary-info-left v-model="currentOrgCode"/>
+        </a-col>
+        <a-col :md="24-5" :sm="24">
+            <dictionary-info-right v-model="currentOrgCode"/>
+        </a-col>
+    </a-row>
+</template>
+
+<script>
+    import dictionaryInfoLeft from './modules/dictionaryInfoLeft'
+    import dictionaryInfoRight from './modules/dictionaryInfoRight'
+
+    export default {
+        name: 'dictionaryInfo',
+        components: { dictionaryInfoLeft, dictionaryInfoRight },
+        data() {
+            return {
+                description: '字典管理',
+                currentOrgCode: ''
+            }
+        },
+
+        methods: {
+        },
+        destroyed: function () {
+            // 离开页面生命周期函数
+            console.log('离开字典管理');
+            localStorage.removeItem("dictId")
+        },
+    }
+</script>
+<style scoped>
+    @import '~@assets/less/common.less';
+    .container{
+        background-color: #f6f6f6;
+    }
+</style>

+ 153 - 0
src/views/settings/components/modules/dictItemForm.vue

@@ -0,0 +1,153 @@
+<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="tenantId">
+              <a-input v-model="model.tenantId" placeholder="请输入关联租户"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="关联酒店" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="hotelId">
+              <a-input v-model="model.hotelId" placeholder="请输入关联酒店"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="字典id" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="dictId">
+              <a-input v-model="model.dictId" placeholder="请输入字典id"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="字典项文本" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="itemText">
+              <a-input v-model="model.itemText" placeholder="请输入字典项文本"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="字典项值" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="itemValue">
+              <a-input v-model="model.itemValue" placeholder="请输入字典项值"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="描述" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="description">
+              <a-input v-model="model.description" placeholder="请输入描述"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="排序" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="sortOrder">
+              <a-input-number v-model="model.sortOrder" placeholder="请输入排序" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="状态(1启用 0不启用)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="status">
+              <a-input-number v-model="model.status" placeholder="请输入状态(1启用 0不启用)" style="width: 100%" />
+            </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: 'dictItemForm',
+    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: '请输入关联酒店!'},
+           ],
+           itemText: [
+              { required: true, message: '请输入字典项文本!'},
+           ],
+           itemValue: [
+              { required: true, message: '请输入字典项值!'},
+           ],
+        },
+        url: {
+          add: "/business/busDictItem/add",
+          edit: "/business/busDictItem/edit",
+          queryById: "/business/busDictItem/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/dictItemModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <dict-item-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></dict-item-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 dictItemForm from './dictItemForm'
+
+  export default {
+    name: 'dictItemModal',
+    components: {
+      dictItemForm
+    },
+    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>

+ 252 - 0
src/views/settings/components/modules/dictItemModal.vue

@@ -0,0 +1,252 @@
+<!--<template>-->
+<!--  <j-modal-->
+<!--    :title="title"-->
+<!--    :width="width"-->
+<!--    :visible="visible"-->
+<!--    switchFullscreen-->
+<!--    @ok="handleOk"-->
+<!--    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"-->
+<!--    @cancel="handleCancel"-->
+<!--    cancelText="关闭">-->
+<!--    <dict-item-modal ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></dict-item-modal>-->
+<!--  </j-modal>-->
+<!--</template>-->
+
+<!--<script>-->
+
+<!--  import dictItemForm from './dictItemForm'-->
+<!--  export default {-->
+<!--    name: 'DictItemModal',-->
+<!--    components: {-->
+<!--      dictItemForm-->
+<!--    },-->
+<!--    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>-->
+
+<template>
+  <a-modal
+          :title="title"
+          :width="800"
+          :visible="visible"
+          :confirmLoading="confirmLoading"
+          @ok="handleOk"
+          @cancel="handleCancel"
+          cancelText="关闭"
+  >
+    <a-spin :spinning="confirmLoading">
+      <a-form-model  ref="form" :model="model" :rules="validatorRules">
+
+        <a-form-model-item
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                prop="itemText"
+                label="字典名称">
+          <a-input placeholder="请输入名称" v-model="model.itemText"/>
+        </a-form-model-item>
+
+        <a-form-model-item
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                prop="itemValue"
+                label="数据值">
+          <a-input placeholder="请输入数据值" v-model="model.itemValue" />
+        </a-form-model-item>
+
+        <a-form-model-item
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                label="描述">
+          <a-input v-model="model.description" />
+        </a-form-model-item>
+
+        <a-form-model-item
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                label="排序值">
+          <a-input-number :min="1" v-model="model.sortOrder" />
+          值越小越靠前
+        </a-form-model-item>
+
+        <a-form-model-item
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                label="是否启用"
+                hasFeedback>
+          <a-switch checkedChildren="启用" unCheckedChildren="禁用" @change="onChose" v-model="visibleCheck"/>
+        </a-form-model-item>
+
+      </a-form-model>
+    </a-spin>
+  </a-modal>
+</template>
+
+<script>
+  import pick from 'lodash.pick'
+  import {addBusDictItem, editBusDictItem} from '@/api/api'
+  import { getAction } from '@api/manage'
+
+  export default {
+    name: "DictItemModal",
+    data() {
+      return {
+        title: "操作",
+        visible: false,
+        visibleCheck: true,
+        model: {},
+        dictId: "",
+        status: 1,
+        labelCol: {
+          xs: {span: 24},
+          sm: {span: 5},
+        },
+        wrapperCol: {
+          xs: {span: 24},
+          sm: {span: 16},
+        },
+        confirmLoading: false,
+        validatorRules: {
+          itemText:  [{required: true, message: '请输入名称!'}],
+          itemValue:  [{required: true, message: '请输入数据值!'},{validator: this.validateItemValue}],
+        },
+      }
+    },
+    created() {
+    },
+    methods: {
+      add(dictId) {
+        this.dictId = dictId;
+        //初始化默认值
+        this.edit({sortOrder:1,status:1});
+      },
+      edit(record) {
+        if (record.id) {
+          this.dictId = record.dictId;
+        }
+        this.status = record.status;
+        this.visibleCheck = (record.status == 1) ? true : false;
+        this.model = Object.assign({}, record);
+        this.model.dictId = this.dictId;
+        this.model.status = this.status;
+        this.visible = true;
+      },
+      onChose(checked) {
+        if (checked) {
+          this.status = 1;
+          this.visibleCheck = true;
+        } else {
+          this.status = 0;
+          this.visibleCheck = false;
+        }
+      },
+      // 确定
+      handleOk() {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            this.model.itemText = (this.model.itemText || '').trim()
+            this.model.itemValue = (this.model.itemValue || '').trim()
+            this.model.description = (this.model.description || '').trim()
+            this.model.status = this.status;
+            let obj;
+            if (!this.model.id) {
+              var info = JSON.parse(localStorage.getItem("storeInfo"));
+              this.model.hotelId = info.id;
+              obj = addBusDictItem(this.model);
+            } else {
+              obj = editBusDictItem(this.model);
+            }
+            obj.then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit('ok');
+              } else {
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+              that.close();
+            })
+          }else{
+            return false;
+          }
+        })
+      },
+      // 关闭
+      handleCancel() {
+        this.close();
+      },
+      close() {
+        this.$emit('close');
+        this.visible = false;
+        this.$refs.form.resetFields();
+      },
+      validateItemValue(rule, value, callback){
+        let param = {
+          itemValue:value,
+          dictId:this.dictId,
+        }
+        if(this.model.id){
+          param.id = this.model.id
+        }
+        if(value){
+          let reg=new RegExp("[`~!@#$^&*()=|{}'.<>《》/?!¥()—【】‘;:”“。,、?]")
+          if(reg.test(value)){
+            callback("数据值不能包含特殊字符!")
+          }else{
+            // callback()
+            //update--begin--autor:lvdandan-----date:20201203------for:JT-27【数据字典】字典 - 数据值可重复
+            getAction("/business/busDictItem/dictItemCheck",param).then((res)=>{
+              if(res.success){
+                callback()
+              }else{
+                callback(res.message);
+              }
+            });
+            //update--end--autor:lvdandan-----date:20201203------for:JT-27【数据字典】字典 - 数据值可重复
+          }
+        }else{
+          callback()
+        }
+      }
+    }
+  }
+</script>
+

+ 113 - 0
src/views/settings/components/modules/dictionaryInfoLeft.vue

@@ -0,0 +1,113 @@
+<template>
+    <a-card :loading="cardLoading" :bordered="false" style="height: 100%;">
+        <a-spin :spinning="loading">
+<!--            <a-input-search @search="handleSearch" style="width:100%;margin-top: 10px" placeholder="输入字典名称查询..." enterButton />-->
+
+            <a-tree
+                    showLine
+                    checkStrictly
+                    :expandedKeys.sync="expandedKeys"
+                    :selectedKeys="selectedKeys"
+                    :dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
+                    :treeData="treeDataSource"
+                    @select="handleTreeSelect"
+            />
+        </a-spin>
+    </a-card>
+</template>
+
+<script>
+    import { queryBusDictTreeList } from '@/api/api'
+
+    export default {
+        name: 'dictionaryInfoLeft',
+        props: ['value'],
+        data() {
+            return {
+                cardLoading: true,
+                loading: false,
+                treeDataSource: [],
+                selectedKeys: [],
+                expandedKeys: [],
+                dictId:''
+            }
+        },
+        created() {
+            this.queryTreeData()
+        },
+        methods: {
+
+            queryTreeData(keyword) {
+                console.log('获取数据')
+                this.commonRequestThen(queryBusDictTreeList({
+                    departName: keyword ? keyword : undefined,
+                    ids: this.dictId ? this.dictId : undefined
+                }))
+            },
+
+            // handleSearch(value) {
+            //     if (value) {
+            //         this.commonRequestThen(searchByKeywords({ keyWord: value }))
+            //     } else {
+            //         this.queryTreeData()
+            //     }
+            // },
+
+            handleTreeSelect(selectedKeys, event) {
+                console.log(event.node.dataRef)
+                //update-begin---author:wangshuai ---date:20220107  for:[JTC-378]通讯录 选中某个部门查询部门人员,想再取消选中查全部,无法取消,只能重新刷新界面------------
+                if (selectedKeys.length > 0 && event.node.dataRef.parentId != '') {
+                    if(this.selectedKeys[0] !== selectedKeys[0]){
+                        this.selectedKeys = [selectedKeys[0]]
+                        let dictId = event.node.dataRef.id
+                        localStorage.setItem("dictId", dictId)
+                        this.dictId = dictId
+                        this.emitInput(dictId)
+                    }
+                }else{
+                    this.selectedKeys = []
+                    this.emitInput("")
+                    localStorage.removeItem("dictId")
+                }
+                //update-end---author:wangshuai ---date:20220107  for:[JTC-378]通讯录 选中某个部门查询部门人员,想再取消选中查全部,无法取消,只能重新刷新界面------------
+            },
+
+            emitInput(id) {
+                this.$emit('input', id)
+            },
+
+            commonRequestThen(promise) {
+                this.loading = true
+                promise.then(res => {
+                    if (res.success) {
+                        this.treeDataSource = res.result
+                        // update-begin- --- author:wangshuai ------ date:20200102 ---- for:去除默认选中第一条数据、默认展开所有第一级
+                        // 默认选中第一条数据、默认展开所有第一级
+                        if (res.result.length > 0) {
+                          this.expandedKeys = []
+                          res.result.forEach((item, index) => {
+                            if (index === 0) {
+                              this.selectedKeys = [item.id]
+                              this.emitInput(item.orgCode)
+                            }
+                            this.expandedKeys.push(item.id)
+                          })
+                        }
+                        // update-end- --- author:wangshuai ------ date:20200102 ---- for:去除默认选中第一条数据、默认展开所有第一级
+                    } else {
+                        this.$message.warn(res.message)
+                        console.error('查询失败:', res)
+                    }
+                }).finally(() => {
+                    this.loading = false
+                    this.cardLoading = false
+                })
+            },
+
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 222 - 0
src/views/settings/components/modules/dictionaryInfoRight.vue

@@ -0,0 +1,222 @@
+<template>
+    <a-card class="j-address-list-right-card-box" :loading="cardLoading" :bordered="false">
+        <div class="table-page-search-wrapper">
+            <a-form-model layout="inline" :model="queryParam">
+                <a-row :gutter="10">
+
+                    <a-col :md="6" :sm="12">
+                        <a-form-model-item label="名称" prop="itemText" style="margin-left:8px">
+                            <j-input placeholder="请输入名称查询" v-model="queryParam.itemText"></j-input>
+                        </a-form-model-item>
+                    </a-col>
+
+                    <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+                        <a-col :md="6" :sm="24">
+                         <a-button type="primary" @click="searchQuery" icon="search" class="margin-left-8">查询</a-button>
+                          <a-button type="primary" @click="searchReset" icon="reload" class="margin-left-8">重置</a-button>
+                            <a-button @click="handleAdd" type="primary" icon="plus" class="margin-left-8">新增</a-button>
+                        </a-col>
+                      </span>
+                </a-row>
+            </a-form-model>
+        </div>
+
+        <a-table
+                ref="table"
+                size="middle"
+                bordered
+                rowKey="userId"
+                :pagination="ipagination"
+                :columns="columns"
+                :dataSource="dataSource"
+                :loading="loading"
+                @change="handleTableChange">
+
+        <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>
+        <dict-item-modal ref="modalForm" @ok="modalFormOk"></dict-item-modal>
+    </a-card>
+</template>
+
+<script>
+    import { getAction } from '@/api/manage'
+    import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+    // import DictItemModal from "../../../system/modules/DictItemModal";
+    import DictItemModal from "./dictItemModal";
+
+    export default {
+        name: 'dictionaryInfoRight',
+        mixins: [JeecgListMixin],
+        components: {DictItemModal},
+        props: ['value'],
+        data() {
+            return {
+                description: '用户信息',
+                cardLoading: true,
+                positionInfo: {},
+                columns: [
+                    {
+                        title:'显示',
+                        align:"center",
+                        dataIndex: 'itemText'
+                    },
+                    {
+                        title:'编码',
+                        align:"center",
+                        dataIndex: 'itemValue'
+                    },
+                    {
+                        title:'排序',
+                        align:"center",
+                        dataIndex: 'sortOrder'
+                    },
+                    {
+                        title:'备注',
+                        align:"center",
+                        dataIndex: 'description'
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align:"center",
+                        fixed:"right",
+                        width:147,
+                        scopedSlots: { customRender: 'action' }
+                    }
+                ],
+                url: {
+                    list: '/business/busDictItem/list',
+                    delete: "/business/busDictItem/delete",
+                    deleteBatch: "/business/busDictItem/deleteBatch",
+                    exportXlsUrl: "/business/busDictItem/exportXls",
+                    importExcelUrl: "business/busDictItem/importExcel",
+                    // listByPosition: '/sys/position/list'
+                },
+                parentId:'',
+            }
+        },
+        watch: {
+            value: {
+                immediate: true,
+                handler(id) {
+                    this.dataSource = []
+                    this.loadData(1, id)
+                }
+            },
+        },
+        created() {
+            // this.queryPositionInfo()
+        },
+        methods: {
+
+            loadData(pageNum, dictId) {
+                this.loading = true
+                if (pageNum === 1) {
+                    this.ipagination.current = 1
+                }
+                // console.log(dictId);
+                // console.log(this.getQueryParams());
+                var _dictId = localStorage.getItem("dictId")
+                if (_dictId != undefined && _dictId != '' && (dictId == undefined || dictId == '')){
+                    dictId = _dictId;
+                }
+                // update-begin- --- author:wangshuai ------ date:20200102 ---- for:传过来的部门编码为空全查
+                if (!dictId) {
+                    getAction(this.url.list, {
+                        ...this.getQueryParams()
+                    }).then((res) => {
+                        if (res.success) {
+                            this.dataSource = res.result.records
+                            this.ipagination.total = res.result.total
+                        }
+                    }).finally(() => {
+                        this.loading = false
+                        this.cardLoading = false
+                    })
+                    // update-end- --- author:wangshuai ------ date:20200102 ---- for:传过来的部门编码为空全查
+                }else{
+                    //加载数据 若传入参数1则加载第一页的内容
+                    getAction(this.url.list, {
+                        dictId,
+                        ...this.getQueryParams()
+                    }).then((res) => {
+                        if (res.success) {
+                            this.dataSource = res.result.records
+                            this.ipagination.total = res.result.total
+                        }
+                    }).finally(() => {
+                        this.loading = false
+                        this.cardLoading = false
+                    })
+                }
+            },
+
+            searchQuery() {
+                this.loadData(1, this.value)
+            },
+            searchReset() {
+                this.queryParam = {}
+                this.loadData(1, this.value)
+            },
+
+            handleTableChange(pagination, filters, sorter) {
+                if (Object.keys(sorter).length > 0) {
+                    this.isorter.column = sorter.field
+                    this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc'
+                }
+                this.ipagination = pagination
+                this.loadData(null, this.value)
+            },
+
+            // 查询职务信息
+            queryPositionInfo() {
+                getAction(this.url.listByPosition, { pageSize: 99999 }).then(res => {
+                    if (res.success) {
+                        let positionInfo = {}
+                        res.result.records.forEach(record => {
+                            positionInfo[record['code']] = record['name']
+                        })
+                        this.positionInfo = positionInfo
+                    }
+                })
+            },
+            // 添加字典数据
+            handleAdd() {
+                var dictId = localStorage.getItem("dictId")
+                this.$refs.modalForm.add(dictId);
+                this.$refs.modalForm.title = "新增";
+            },
+        }
+    }
+</script>
+<style>
+    .j-address-list-right-card-box .ant-table-placeholder {
+        min-height: 46px;
+    }
+</style>
+<style scoped>
+    .j-address-list-right-card-box {
+        height: 100%;
+        min-height: 300px;
+    }
+    .margin-left-8{
+        margin-left: 8px
+    }
+</style>

+ 172 - 0
src/views/settings/components/modules/roomPayTypeForm.vue

@@ -0,0 +1,172 @@
+<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="isDeposit">-->
+<!--              <a-input v-model="model.isDeposit" placeholder="请输入是否用于押金付款"  ></a-input>-->
+<!--            </a-form-model-item>-->
+            <a-form-model-item
+                    :labelCol="labelCol"
+                    :wrapperCol="wrapperCol"
+                    label="是否用于押金付款"
+                    prop="isDeposit">
+              <a-switch v-model="model.isDeposit"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+<!--            <a-form-model-item label="是否用于结账付款" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="isClosing">-->
+<!--              <a-input v-model="model.isClosing" placeholder="请输入是否用于结账付款"  ></a-input>-->
+<!--            </a-form-model-item>-->
+            <a-form-model-item
+                    :labelCol="labelCol"
+                    :wrapperCol="wrapperCol"
+                    label="是否用于结账付款"
+                    prop="isClosing">
+              <a-switch v-model="model.isClosing"/>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="排序" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="orderBy">
+              <a-input-number v-model="model.orderBy" placeholder="请输入排序" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+<!--            <a-form-model-item label="状态(0-禁用;1-启用)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="status">-->
+<!--              <a-input-number v-model="model.status" placeholder="请输入状态(0-禁用;1-启用)" style="width: 100%" />-->
+<!--            </a-form-model-item>-->
+            <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-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: 'roomPayTypeForm',
+    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: '请输入名称!'},
+           ],
+          isDeposit: [
+            { required: true, message: '请选择!'},
+          ],
+          isClosing: [
+            { required: true, message: '请选择!'},
+          ],
+          orderBy: [
+            { required: true, message: '请输入排序!'},
+          ],
+          status: [
+            { required: true, message: '请选择!'},
+          ],
+        },
+        url: {
+          add: "/business/busRoomPayType/add",
+          edit: "/business/busRoomPayType/edit",
+          queryById: "/business/busRoomPayType/queryById"
+        }
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+        this.edit({status:true,orderBy:0 ,isDeposit:true,isClosing:true });
+        // this.edit({isDeposit:true });
+        // this.edit({isClosing:true });
+        // this.edit({orderBy:0 });
+      },
+      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';
+            }
+            var _model = this.model;
+            if (_model.status){
+              _model.status = 1;
+            }else {
+              _model.status = 0;
+            }
+            httpAction(httpurl,_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/roomPayTypeModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <room-pay-type-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></room-pay-type-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 roomPayTypeForm from './roomPayTypeForm'
+
+  export default {
+    name: 'roomPayTypeModal',
+    components: {
+      roomPayTypeForm
+    },
+    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/roomPayTypeModal.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="关闭">
+    <room-pay-type-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></room-pay-type-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import roomPayTypeForm from './roomPayTypeForm'
+  export default {
+    name: 'roomPayTypeModal',
+    components: {
+      roomPayTypeForm
+    },
+    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>

+ 217 - 0
src/views/settings/components/modules/salesPersonForm.vue

@@ -0,0 +1,217 @@
+<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="workNo">
+              <a-input v-model="model.workNo" placeholder="请输入编号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <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="postId">
+<!--              <a-input v-model="model.operatorId" placeholder="请选择职务"  ></a-input>-->
+              <a-select
+                      mode="multiple"
+                      v-model="model.postId"
+                      placeholder="请选择职务"
+                      :allowClear="true"
+              >
+                <a-select-option :value="item.id" v-for="(item,index) in postList" :key="index">{{ item.itemText }}</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="operatorId">
+<!--              <a-input v-model="model.operatorId" placeholder="请选择关联操作用户"  ></a-input>-->
+              <a-select
+                      v-model="model.operatorId"
+                      placeholder="请选择关联操作用户"
+                      :allowClear="true"
+              >
+                <a-select-option :value="item.id" v-for="(item,index) in userList" :key="index">{{ 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="mobile">
+              <a-input v-model="model.mobile" placeholder="请输入联系电话"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="手机号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="phone">
+              <a-input v-model="model.phone" placeholder="请输入手机号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="地址" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="address">
+              <a-input v-model="model.address" placeholder="请输入地址"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="备注信息" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remarks">
+              <a-input v-model="model.remarks" placeholder="请输入备注信息"  ></a-input>
+            </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-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: 'BusSalesPersonForm',
+    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: {
+          workNo: [
+            { required: true, message: '请输入编号!'},
+          ],
+          name: [
+            { required: true, message: '请输入姓名!'},
+          ],
+          phone: [
+            { required: true, message: '请输入手机号!'},
+          ],
+          status: [
+            { required: true, message: '请选择服务员是否有效!'},
+          ],
+        },
+        url: {
+          add: "/business/busSalesPerson/add",
+          edit: "/business/busSalesPerson/edit",
+          queryById: "/business/busSalesPerson/queryById"
+        },
+        userList:[],
+        postList:[]
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+      this.getHotelPost()
+    },
+    methods: {
+        add () {
+            this.edit(this.modelDefault);
+            this.edit({status:true });
+        },
+        edit (record) {
+            if (record.status == 1){
+                record.status = true;
+            }else {
+                record.status = false;
+            }
+            record.postId = record.postIds.split(',');
+            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;
+                        var info = JSON.parse(localStorage.getItem("storeInfo"));
+                        this.model.hotelId = info.id;
+                        method = 'post';
+                    }else{
+                        httpurl+=this.url.edit;
+                        method = 'put';
+                    }
+                    var _model = this.model;
+                    if (_model.status){
+                        _model.status = 1;
+                    }else {
+                        _model.status = 0;
+                    }
+                    _model.postIds = this.model.postId.join(",")
+                    console.log(_model)
+                    this.$delete( _model, 'postId')
+
+
+                    httpAction(httpurl,_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;
+                    })
+                }
+
+            })
+        },
+        getHotelPost(){
+            var that = this;
+            var param = {
+                dictName:'职务'
+            }
+            // var values = JSON.parse(JSON.stringify(param))
+            that.confirmLoading = true;
+            getAction('/business/busDictItem/queryList',param).then((res)=>{
+                console.log(res)
+                if(res.success){
+                    if (res.code == 200 && res.result) {
+                        this.postList = res.result;
+                    }
+                }
+            }).finally(() => {
+                that.confirmLoading = false;
+            })
+        }
+    }
+  }
+</script>

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

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <sales-person-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></sales-person-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 salesPersonForm from './salesPersonForm'
+
+  export default {
+    name: 'salesPersonModal',
+    components: {
+      salesPersonForm
+    },
+    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/salesPersonModal.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="关闭">
+    <sales-person-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></sales-person-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import salesPersonForm from './salesPersonForm'
+  export default {
+    name: 'salesPersonModal',
+    components: {
+      salesPersonForm
+    },
+    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>

+ 261 - 4
src/views/settings/components/paySettings.vue

@@ -1,13 +1,270 @@
 <template>
-    <div>支付配置</div>
+    <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="6" :sm="8">
+                        <a-form-item>
+                            <a-select
+                                    :maxTagCount="1"
+                                    mode="multiple"
+                                    v-model="queryParam.hotelId"
+                                    placeholder="请选择"
+                                    :allowClear="true"
+                            >
+                                <a-select-option :value="item.id" v-for="(item,index) in hotelList" :key="index">{{ item.name }}</a-select-option>
+                            </a-select>
+                        </a-form-item>
+                    </a-col>
+                    <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">
+                        <a-form-item>
+                            <j-dict-select-tag v-model="queryParam.status" placeholder="请选择状态" dictCode="pay_status"
+                                               @change="e=>handleChangePayStatus(e)" />
+                        </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="status" slot-scope="text,record">
+                    <a-tag v-if="text == 1" color="green">已启用</a-tag>
+                    <a-tag v-else color="red">已禁用</a-tag>
+                </span>
+                <span slot="deposit" slot-scope="text,record">
+                    <a-icon v-if="text == true" type="check" style="color: #129617"/>
+                    <a-icon v-else type="close" style="color: #bb3726"/>
+                </span>
+                <span slot="closing" slot-scope="text,record">
+                    <a-icon v-if="text == true" type="check" style="color: #129617"/>
+                    <a-icon v-else type="close" style="color: #bb3726"/>
+                </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>
+
+        <room-pay-type-modal ref="modalForm" @ok="modalFormOk"></room-pay-type-modal>
+    </a-card>
 </template>
 
 <script>
+
+    import '@/assets/less/TableExpand.less'
+    import { mixinDevice } from '@/utils/mixin'
+    import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+    import roomPayTypeModal from './modules/roomPayTypeModal'
+    import {hotelQueryList} from "../../../api/hotel";
+
     export default {
-        name: "paySettings"
+        name: 'paySettings',
+        mixins:[JeecgListMixin, mixinDevice],
+        components: {
+            roomPayTypeModal
+        },
+        data () {
+            return {
+                description: '支付方式管理页面',
+                // 表头
+                columns: [
+                    // {
+                    //     title: '#',
+                    //     dataIndex: '',
+                    //     key:'rowIndex',
+                    //     width:60,
+                    //     align:"center",
+                    //     customRender:function (t,r,index) {
+                    //         return parseInt(index)+1;
+                    //     }
+                    // },
+                    // {
+                    //     title:'关联租户',
+                    //     align:"center",
+                    //     dataIndex: 'tenantId'
+                    // },
+                    {
+                        title:'商家',
+                        align:"center",
+                        dataIndex: 'hotelName'
+                    },
+                    {
+                        title:'名称',
+                        align:"center",
+                        dataIndex: 'name'
+                    },
+                    {
+                        title:'是否用于押金付款',
+                        align:"center",
+                        dataIndex: 'isDeposit',
+                        scopedSlots: { customRender: 'deposit' },
+                    },
+                    {
+                        title:'是否用于结账付款',
+                        align:"center",
+                        dataIndex: 'isClosing',
+                        scopedSlots: { customRender: 'closing' },
+                    },
+                    {
+                        title:'排序',
+                        align:"center",
+                        dataIndex: 'orderBy'
+                    },
+                    {
+                        title:'状态',
+                        align:"center",
+                        dataIndex: 'status',
+                        scopedSlots: { customRender: 'status' },
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align:"center",
+                        fixed:"right",
+                        width:147,
+                        scopedSlots: { customRender: 'action' }
+                    }
+                ],
+                url: {
+                    list: "/business/busRoomPayType/list",
+                    delete: "/business/busRoomPayType/delete",
+                    deleteBatch: "/business/busRoomPayType/deleteBatch",
+                    exportXlsUrl: "/business/busRoomPayType/exportXls",
+                    importExcelUrl: "business/busRoomPayType/importExcel",
+
+                },
+                dictOptions:{},
+                superFieldList:[],
+                hotelList:[],
+            }
+        },
+        created() {
+            this.getSuperFieldList();
+            this.initData();
+        },
+        computed: {
+            importExcelUrl: function(){
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            },
+        },
+        methods: {
+            initDictConfig(){
+            },
+            initData(){
+                hotelQueryList({
+                    key: ''
+                }).then(res => {
+                    console.log(res)
+                    if (res.code == 200 && res.result) {
+                        this.hotelList = res.result;
+                    }
+                })
+            },
+            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:'string',value:'isDeposit',text:'是否用于押金付款'})
+                fieldList.push({type:'string',value:'isClosing',text:'是否用于结账付款'})
+                fieldList.push({type:'int',value:'orderBy',text:'排序'})
+                fieldList.push({type:'int',value:'status',text:'状态(0-禁用;1-启用)'})
+                fieldList.push({type:'int',value:'delFlag',text:'删除状态(0-正常,1-已删除)'})
+                this.superFieldList = fieldList
+            },
+            handleChangePayStatus(value){
+                console.log(value)
+                this.loadData(1)
+            }
+        }
     }
 </script>
-
 <style scoped>
-
+    @import '~@assets/less/common.less';
 </style>

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

@@ -4,7 +4,6 @@
         <a-tabs
         default-active-key="1"
         tab-position="left"
-        :style="{ height: '200px' }"
       >
         <a-tab-pane  tab="全天房" key="1">
             <room-qtf-price-table v-if="raw" :layout-id="raw.id"></room-qtf-price-table>

+ 197 - 56
src/views/settings/components/roomModules/RoomQtfPriceTable.vue

@@ -1,15 +1,16 @@
 <template>
-    <div>
-        <a-table :columns="columns" :data-source="data"  :pagination="false" :loading="loading">
+    <div >
+        <a-table :columns="columns" :data-source="data" :pagination="false" :loading="loading">
             <span slot="prepay" slot-scope="text, record, index">
-                <a-switch checked-children="是" un-checked-children="否" :checked="record.prepay" @change="changePrepay(record)"/>
-              </span>
-              <span slot="isVip" slot-scope="text, record, index">
+                <a-switch checked-children="是" un-checked-children="否" :checked="record.prepay"
+                    @change="changePrepay(record)" />
+            </span>
+            <span slot="isVip" slot-scope="text, record, index">
                 <a-switch checked-children="是" un-checked-children="否" :checked="record.isVip" />
-              </span>
-              <span slot="action" slot-scope="text, record">
+            </span>
+            <span slot="action" slot-scope="text, record">
                 <a @click="handleEdit(record)">编辑</a>
-    
+
                 <a-divider type="vertical" />
                 <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
                     <a>删除</a>
@@ -17,48 +18,89 @@
             </span>
         </a-table>
         <a-form-model layout="inline" ref="form" :model="model" :rules="validatorRules" slot="detail">
-            <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-form-model-item label="原价" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="oprice">
-                <a-input-number style="width:100%;" v-model="model.oprice" :min="1"  placeholder="请填写原价"/>
-            </a-form-model-item>
-            <a-form-model-item label="现价" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="price">
-                <a-input-number style="width:100%;" v-model="model.oprice" :min="1"  placeholder="请填写现价"/>
-            </a-form-model-item>
-            <a-form-model-item label="预付" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="prepay">
-                <a-radio-group v-model="model.prepay">
-                    <a-radio :value="1">
-                      是
-                    </a-radio>
-                    <a-radio :value="0">
-                      否
-                    </a-radio>                    
-                  </a-radio-group>
-            </a-form-model-item>
-            <a-form-model-item label="积分" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="integral">
-                <a-input-number style="width:100%;" v-model="model.integral"  placeholder="请填写积分"/>
-            </a-form-model-item>
-            <a-form-model-item label="数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="num">
-                <a-input-number style="width:100%;" v-model="model.num"  placeholder="请填写数量"/>
-            </a-form-model-item>
-            <a-form-model-item label="会员折扣" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="isVip">
-                <a-radio-group v-model="model.isVip">
-                    <a-radio :value="1">
-                      是
-                    </a-radio>
-                    <a-radio :value="0">
-                      否
-                    </a-radio>                    
-                  </a-radio-group>
-            </a-form-model-item>
+            <a-row>
+                <a-col :span="3">
+                    <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="3">
+                    <a-form-model-item label="原价" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="oprice">
+                        <a-input-number style="width:100%;" v-model="model.oprice" :min="1" placeholder="请填写原价" />
+                    </a-form-model-item>
+                </a-col>
+                <a-col :span="3">
+                    <a-form-model-item label="现价" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="price">
+                        <a-input-number style="width:100%;" v-model="model.price" :min="1" placeholder="请填写现价" />
+                    </a-form-model-item>
+                </a-col>
+                <a-col :span="3">
+                    <a-form-model-item label="预付"  prop="prepay">
+                        <a-radio-group v-model="model.prepay">
+                            <a-radio-button :value="1">
+                                是
+                            </a-radio-button>
+                            <a-radio-button :value="0">
+                                否
+                            </a-radio-button>
+                        </a-radio-group>
+                    </a-form-model-item>
+                </a-col>
+                <a-col :span="3">
+                    <a-form-model-item label="积分" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="integral">
+                        <a-input-number style="width:100%;" v-model="model.integral" placeholder="请填写积分" />
+                    </a-form-model-item>
+                </a-col>
+                <a-col :span="3">
+                    <a-form-model-item label="数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="num">
+                        <a-input-number style="width:100%;" v-model="model.num" placeholder="请填写数量" />
+                    </a-form-model-item>
+                </a-col>
+                <a-col :span="3">
+                    <a-form-model-item label="会员折扣" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="isVip">
+                        <a-radio-group v-model="model.isVip" @change="onVipChange">
+                            <a-radio-button :value="1">
+                                是
+                            </a-radio-button>
+                            <a-radio-button :value="0">
+                                否
+                            </a-radio-button>
+                        </a-radio-group>
+                    </a-form-model-item>
+                </a-col>
+                <a-col :span="1">
+                    <a-button @click="submitForm" type="primary">保存</a-button>
+                </a-col>
+            </a-row>
         </a-form-model>
+
+        <div class="vip-config" v-if="model.isVip">
+            <div class="config-heads h-title">
+                <div class="head-item">会员等级</div>
+                <div class="head-item">原价</div>
+                <div class="head-item">折扣(%)</div>
+                <div class="head-item">现价</div>
+            </div>
+            <div class="config-heads" v-for="item in vipLevels" :key="item.id">
+                <div class="head-item">[{{ item.name }}]</div>
+                <div class="head-item">
+                    <a-input-number style="width:80%;" v-model="model.oprice" :min="0" placeholder="请填写原价" @change="vipOpriceChange($event, item)"/>
+                </div>
+                <div class="head-item">
+                    <a-input-number style="width:80%;" v-model="item.discount" :min="0" placeholder="请填写折扣" @change="vipDiscountChange($event, item)"/>
+                </div>
+                <div class="head-item">
+                    <a-input-number style="width:80%;" :value="item.price" :min="0" placeholder="请填写现价" @change="vipPriceChange($event, item)"/>
+                </div>
+            </div>
+        </div>
     </div>
 </template>
 
 <script>
 import { list } from '@/api/roomLayoutPrice'
-
+import { httpAction, getAction } from "@/api/manage";
+import * as api from '@/api/api'
 const columns = [
     {
         title: '房价名称',
@@ -92,7 +134,7 @@ const columns = [
         key: 'num',
     },
     {
-        title:'使用会员折扣',
+        title: '使用会员折扣',
         dataIndex: 'isVip',
         key: 'isVip',
         scopedSlots: { customRender: 'isVip' },
@@ -112,11 +154,11 @@ export default {
         return {
             labelCol: {
                 xs: { span: 24 },
-                sm: { span: 8 },
+                sm: { span: 10 },
             },
             wrapperCol: {
                 xs: { span: 24 },
-                sm: { span: 16 },
+                sm: { span: 14 },
             },
             loading: false,
             data: [],
@@ -138,42 +180,141 @@ export default {
                 prepay: 0,
                 integral: 0,
                 num: 0,
-            }
+                isVip: 0
+            },
+            vipLevels: [],
+            origiVipLevels: []
         };
     },
 
     mounted() {
         this.getData()
+        this.getVipLevels()
     },
-
     methods: {
+        vipPriceChange(e, item) {
+            if(this.model.oprice) {
+                item.discount = ((e / this.model.oprice) * 100).toFixed(2)
+            }
+            item.price = e
+        },
+        vipDiscountChange(e, item) {
+            if(this.model.oprice) {
+                item.price = (this.model.oprice * (e/100)).toFixed(2)
+            }
+            item.discount = e
+        },
+        vipOpriceChange(e, item) {
+            if(item.discount) {
+                item.price = (this.model.oprice * (item.discount/100)).toFixed(2)
+            }
+            this.model.oprice = e
+        },
+        getVipLevels() {
+            api.getVipLevels({
+                pageNo: 1,
+                pageSize: 999,
+                hotelId: hotelItem.id
+            }).then(res => {
+                if(res.result && res.result.records) {
+                    
+                    res.result.records.forEach(s=>{
+                        s['price'] = 0
+                        if(!s.discount) {
+                            s.discount = 100
+                        }
+                    })
+                    this.origiVipLevels = res.result.records
+                    this.vipLevels = JSON.parse(JSON.stringify(res.result.records))
+                }
+            })
+        },
         changePrepay(record) {
-            
+
+        },
+        onVipChange(e) {
+            if(this.model.isVip) {
+
+            }
+        },
+        handleEdit(record) {
+            let cpData = JSON.parse(JSON.stringify(record))
+            cpData.isVip = record.isVip? 1 : 0
+            cpData.prepay = record.prepay? 1 : 0
+            this.model = cpData
         },
         getData() {
             this.loading = true
             list({
                 type: this.searchType,
-                hotelId: hotelItem.id,
+                // hotelId: hotelItem.id,
                 roomLayoutId: this.layoutId,
                 pageNo: 1,
                 pageSize: 999
-            }).then(res=>{
+            }).then(res => {
                 this.loading = false
                 console.log(res)
                 this.data = res.result.records
-            }).catch(res=>{
+            }).catch(res => {
                 this.loading = false
             })
         },
         handleDelete(id) {
 
-        }
+        },
+        submitForm() {
+            const that = this;
+            // 触发表单验证
+            this.$refs.form.validate((valid) => {
+                if (valid) {
+                    that.confirmLoading = true;
+                    let httpurl = "";
+                    let method = "";
+                    // if (!this.model.id) {
+                    //     httpurl += this.url.add;
+                    //     method = "post";
+                    // } else {
+                    //     httpurl += this.url.edit;
+                    //     method = "put";
+                    // }
+                    // if (this.model.payFlag == 0) {
+                    //     this.model.payAmount = 0;
+                    // }
+                    // httpAction(httpurl, this.model, method)
+                    //     .then((res) => {
+                    //         if (res.success) {
+                    //             that.$message.success(res.message);
+                    //             that.$emit("ok");
+                    //         } else {
+                    //             that.$message.warning(res.message);
+                    //         }
+                    //     })
+                    //     .finally(() => {
+                    //         that.confirmLoading = false;
+                    //     });
+                }
+            });
+        },
 
     },
 };
 </script>
 
-<style lang="stylus" scoped>
-
+<style lang="css" scoped>
+.vip-config{
+    width: 30%;
+    height: 200px;
+    overflow-y: auto;
+    margin-top: 20px;
+}
+.config-heads{
+    display: flex;
+}
+.config-heads .head-item{
+    flex: 1;
+    text-align: left;
+}
+.h-title{
+    font-weight: 600;
+}
 </style>

+ 261 - 0
src/views/settings/components/roomModules/goodList.vue

@@ -0,0 +1,261 @@
+<template>
+    <div class="back">
+        <div class="back-left">
+            <a-button @click="handleStockTypeModelManager(undefined,1)">添加分类</a-button>
+            <a-button style="margin-left: 30px;">单位设置</a-button>
+            <a-tree class="draggable-tree" :tree-data="treeData" blockNode style="width: 400px;"
+                :replaceFields="{ children: 'children', title: 'name', key: 'id' }">
+                <div slot="title" slot-scope="item,key,children" style="display:flex; align-items: center; height: 100%; overflow: hidden;">
+                    <a-button style="font-size: 12px" type="link" @click="() => { $message.success(item.name) }">{{ item.name}}</a-button>
+                    <div style="flex:1;height:1px;"></div>
+                    <a-button style="font-size: 12px; padding: 0 5px;" type="link" v-show="item.parentId == 0" @click="handleStockTypeModelManager(item,1)">添加分类</a-button>
+                    <a-button style="font-size: 12px; padding: 0 5px;" type="link" @click="handleStockTypeModelManager(item,2)">编辑</a-button>
+                    <a-button style="font-size: 12px; padding: 0 5px;" type="link" @click="() => { $message.success('删除--' + item.id) }">删除</a-button>
+                </div>
+            </a-tree>
+        </div>
+        <div class="back-right" style="margin-top: -28px; margin-left: 10px;">
+            <a-card :bordered="false">
+                <!-- 查询区域 -->
+                <div class="table-page-search-wrapper">
+                    <a-form layout="inline" @keyup.enter.native="searchQuery">
+                        <a-row :gutter="24">
+                            <a-col :span="4">
+                                <a-form-item label="">
+                                    <j-input placeholder="商品名称" v-model="queryParam.name" style="width: 200px"></j-input>
+                                </a-form-item>
+                            </a-col>
+                            <a-col :md="13" :sm="8" style="display: flex; justify-content: space-around;">
+                                <span style="float:left; overflow: hidden" class="table-page-search-submitButtons">
+                                    <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                                </span>
+                                <span style="float:left; overflow: hidden; line-height: 32px">【全部】房间属性</span>
+                                <span style="float:left; overflow: hidden">
+                                    <a-button type="primary" @click="handleAdd">新增商品</a-button>
+                                </span>
+                                <span style="float:left; overflow: hidden">
+                                    <a-button type="danger" @click="searchQuery">批量删除</a-button>
+                                </span>
+                                <span style="float:left; overflow: hidden;">
+                                    <a-button type="primary" style="background-color:coral;border: none"
+                                        @click="searchQuery">进退货</a-button>
+                                </span>
+                                <span style="float:left; overflow: hidden">
+                                    <a-button type="primary" style="background-color:seagreen;border: none"
+                                        @click="searchQuery">导入商品</a-button>
+                                </span>
+                            </a-col>
+                        </a-row>
+                    </a-form>
+                </div>
+                <!-- 查询区域-END -->
+                <div>
+                    <a-table ref="table" size="middle" :scroll="{ x: true }" bordered rowKey="id" :columns="columns"
+                        :dataSource="dataSource" :pagination="ipagination" :loading="false" :rowSelection="{
+                            selectedRowKeys: selectedRowKeys,
+                            onChange: onSelectChange,
+                        }" class="j-table-force-nowrap" @change="handleTableChange">
+
+                    </a-table>
+                </div>
+                <!-- <room-layout-form ref="modalForm" @ok="modalFormOk"></room-layout-form> -->
+                <stock-type-model ref="stockTypeModel" @ok="onSave"></stock-type-model>
+            </a-card>
+        </div>
+    </div>
+
+</template>
+<script>
+import { tree } from '@/api/good'
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import stockTypeModel from './stockTypeModel.vue'
+export default {
+    name: "goodList",
+    mixins: [JeecgListMixin],
+    components: {
+        stockTypeModel
+      },
+    data() {
+        return {
+            treeData: [
+                {
+                    t: '111',
+                    k: '1',
+                    c: [
+                        {
+                            t: '222',
+                            k: '2',
+                            c: [
+                                { t: 'leaf', k: '333', disableCheckbox: true },
+                                { t: 'leaf', k: '444' },
+                            ],
+                        },
+                        {
+                            t: '555',
+                            k: '555',
+                            c: [{ k: '666', t: 'sb' }],
+                        },
+                    ],
+                },],
+            checkedKeys: [''],
+            selectedKeys: [],
+            queryParam: {},
+            // 分页参数
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                pageSizeOptions: ["10", "20", "30"],
+                showTotal: (total, range) => {
+                    return range[0] + "-" + range[1] + " 共" + total + "条";
+                },
+                showQuickJumper: true,
+                showSizeChanger: true,
+                total: 0,
+            },
+            // 表头
+            columns: [
+                {
+                    title: "商家",
+                    align: "center",
+                    dataIndex: "hotelName",
+                },
+                {
+                    title: "分类",
+                    align: "center",
+                    dataIndex: "cover",
+
+                },
+                {
+                    title: "单位",
+                    align: "center",
+                    dataIndex: "name",
+
+                },
+                {
+                    title: "条码",
+                    align: "center",
+                    dataIndex: "marketPrice",
+                },
+                {
+                    title: "名称",
+                    align: "center",
+                    dataIndex: "canLivePersonNum",
+                },
+                {
+                    title: "进价",
+                    align: "center",
+                    dataIndex: "num",
+                },
+                {
+                    title: "售价",
+                    align: "center",
+                    dataIndex: "state",
+
+                },
+
+                {
+                    title: "进货量",
+                    align: "center",
+                    dataIndex: "appState",
+
+                },
+                {
+                    title: "销售量",
+                    align: "center",
+                    dataIndex: "appState2",
+
+                },
+                {
+                    title: "库存量",
+                    align: "center",
+                    dataIndex: "storeNum",
+
+                },
+                {
+                    title: "排序",
+                    align: "center",
+                    dataIndex: "appState3",
+
+                },
+                {
+                    title: "操作",
+                    dataIndex: "action",
+                    align: "center",
+                    fixed: "right",
+                    width: 147,
+                },
+            ],
+            url: {
+                // list: 'org.jeecg.modules.business/busMarketMember/list',
+                list: "/rooms/cesRoomLayout/list?hotelId",
+                delete: "/rooms/cesRoomLayout/remove",
+                deleteBatch: "/rooms/cesRoomLayout/deleteBatch",
+                exportXlsUrl: "/rooms/cesRoomLayout/exportXls",
+                importExcelUrl:"rooms/cesRoomLayout/importExcel",
+            },
+            dictOptions: {},
+            superFieldList: [],
+            selectedRowKeys: [],
+            isorter: {
+                column: "createTime",
+                order: "desc",
+            },
+            stockTypeVisible:false,
+        };
+    },
+    computed: {
+
+    },
+    watch: {
+
+    },
+    created() {
+        this.loadTree();
+    },
+    methods: {
+        handleStockTypeModelManager(item,type) {
+            console.log(item, type)
+            this.$refs.stockTypeModel.title = type === 1 ?"新增":"修改"
+            this.$refs.stockTypeModel.visible = true
+        },
+        loadTree() {
+            var that = this
+            tree().then((res) => {
+                if (res.success) {
+                    this.treeData = res.result;
+                }
+            })
+        },
+        onExpand(expandedKeys) {
+            console.log('onExpand', expandedKeys);
+            // if not set autoExpandParent to false, if children expanded, parent can not collapse.
+            // or, you can remove all expanded children keys.
+        },
+        onSelect(selectedKeys, info) {
+            console.log('onSelect', info);
+            this.selectedKeys = selectedKeys;
+        },
+    },
+};
+</script>
+<style scoped>
+.back {
+    display: flex;
+    justify-content: space-between;
+}
+
+.back-left {
+    flex: 10
+}
+
+.back-right {
+    flex: 38;
+}
+
+.ant-tree li .ant-tree-node-content-wrapper {
+    height: auto !important;
+}
+
+.ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
+    background-color: #bae7ff33;
+}</style>

+ 123 - 4
src/views/settings/components/roomModules/roomGen.vue

@@ -1,16 +1,117 @@
 <template>
-    <div>
-        实现功能
+    <div  style="display: flex;">
+        <div style="flex: 3">
+            <a-form :form="form">
+                酒店名称<a-select
+                        show-search
+                        placeholder="请选择酒店"
+                        option-filter-prop="children"
+                        style="width: 200px"
+                        @change="hotelChange"
+                >
+                    <a-select-option v-for="(item, index) in hotelId" :key="index">
+                        {{item.name}}
+                    </a-select-option>
+                </a-select>
+                <div></div>
+                楼栋名称<a-select
+                    show-search
+                    placeholder="请选择楼栋"
+                    option-filter-prop="children"
+                    style="width: 200px"
+                    @change="floorChange"
+            >
+                <a-select-option v-for="(item, index) in buildId" :key="index">
+                    {{item.name}}
+                </a-select-option>
+            </a-select>
+                <div>设置最高层数 最高<a-input placeholder="输入楼层数" v-model="floor"/>层</div>
+                <div>每层房间数量<a-input placeholder="输入每层房间数" v-model="roomsFromOneFloor" />间</div>
+                <div>设置前缀<a-input placeholder="输入房号前缀" v-model="prefixName"/></div>
+                <a-form-item :label-col="formTailLayout.labelCol" :wrapper-col="formTailLayout.wrapperCol">
+                    <div>
+                        <a-checkbox :checked="checkNick" @change="tailNumberExclude">
+                            尾号排除
+                        </a-checkbox>
+                        <a-input placeholder="输入排除的其他尾号" v-model="tailNumber"/>
+                    </div>
+                </a-form-item>
+                <a-form-item :label-col="formTailLayout.labelCol" :wrapper-col="formTailLayout.wrapperCol">
+                    <a-button type="primary" @click="check">
+                        批量生成
+                    </a-button>
+                </a-form-item>
+            </a-form>
+        </div>
+        <div style="flex: 7">
+<!--            <a-collapse v-model="activeKey">-->
+<!--                <a-collapse-panel key="1" :header="item.name" v-for="(item, index) in floor" :key="index">-->
+<!--&lt;!&ndash;                    <p>{{ item.name }}</p>&ndash;&gt;-->
+<!--                    <div style="display: flex; justify-content: space-between">-->
+<!--                        <div v-for="(items, indexs) in item.chil" :key="indexs">-->
+<!--                            {{items.name}}-->
+<!--                        </div>-->
+<!--                    </div>-->
+<!--                </a-collapse-panel>-->
+<!--            </a-collapse>-->
+                <div v-for="(item, index) in floor" :key="index">
+                    <div style="font-width: 600; font-size: 20px" @click="sele(item)">
+                        {{item.name}}
+                    </div>
+                    <div v-if="item.show" style="display: flex; justify-content: space-around; padding: 20px">
+                        <div v-for="(items, indexs) in item.chil" :key="indexs" style="width: 25%;">
+                            <input :value="items.name" style="width: 50%; margin: auto"><a-button type="danger" shape="circle" size="small" icon="minus" style="margin-left: 5px;" />
+                        </div>
+                    </div>
+                    <div>
+                        <a-button type="primary" shape="circle" size="small" icon="plus" style="margin-left: 20px;" />添加房间
+                    </div>
+                </div>
+
+        </div>
     </div>
 </template>
 
 <script>
+    const formItemLayout = {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 8 },
+    };
+    const formTailLayout = {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 8, offset: 4 },
+    };
 export default {
     name: 'HotelSaasTenantFrontendRoomGen',
 
     data() {
         return {
-            
+            hotelId: [{name: 'A酒店'}, {name: 'B酒店'}, {name: 'C酒店'}],
+            buildId: [{name: 'A栋'},{name: 'B栋'},{name: 'C栋'}],
+            floor: [
+                {name: '第一层', show: true,
+                    chil:[{name: '101'},{name: '102'},{name: '103'},{name: '104'}]
+                },
+                {name: '第二层', show: true,
+                    chil:[{name: '101'},{name: '102'},{name: '103'},{name: '104'}]
+                },
+                {name: '第三层', show: true,
+                    chil:[{name: '101'},{name: '102'},{name: '103'},{name: '104'}]
+                }
+                ],
+
+
+
+
+            prefixName: 'room',
+            roomsFromOneFloor: 6,
+            tailNumber: 4,
+            activeKey: ['1'],
+            checkNick: false,
+            formItemLayout,
+            formTailLayout,
+            form: this.$form.createForm(this, { name: 'dynamic_rule' }),
+            seleShow: '', // 用于切换折叠
         };
     },
 
@@ -19,7 +120,25 @@ export default {
     },
 
     methods: {
-        
+        hotelChange(value) {
+            console.log(`selected ${value}`);
+        },
+        floorChange(value) {
+            console.log(`selected ${value}`);
+        },
+        tailNumberExclude() {
+            console.log(`selected ${value}`);
+        },
+        activeKey(key) {
+            console.log(key);
+        },
+        sele(data) {
+            data.show = !data.show
+        },
+        check() {
+
+        },
+
     },
 };
 </script>

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

@@ -29,7 +29,6 @@
         </j-form-container>
     </a-spin>
 </template>
-
 <script>
 import { getRoomPlans, getSelectList } from "@/api/api";
 import { httpAction, getAction } from "@/api/manage";

+ 181 - 0
src/views/settings/components/roomModules/stockTypeForm.vue

@@ -0,0 +1,181 @@
+<template>
+    <a-spin :spinning="confirmLoading">
+        <j-form-container :disabled="formDisabled">
+            <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+                <a-form-model-item label="名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="name">
+                    <a-input v-model="model.name" placeholder="请输入名称"></a-input>
+                </a-form-model-item>
+                <a-form-model-item label="上级" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="marketPrice">
+                    <a-select  style="width: 120px" v-model="model.canLivePersonNum" defaultValue="0">
+                        <a-select-option value ="0">{{"顶级目录"}}</a-select-option>
+                        <a-select-option v-for="d in selectData" :key="d.value">
+                            {{ d.name }}
+                        </a-select-option>
+                    </a-select>
+                </a-form-model-item>
+                
+                <a-form-model-item label="快捷" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="canLivePersonNum">
+                    <a-switch default-checked @change="onChange"  v-model="model.canLivePersonNum" />
+                </a-form-model-item>
+
+                <a-form-model-item label="是否启用" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="breakfastNum">
+                    <a-switch default-checked @change="onChange"  v-model="model.canLivePersonNum" />
+                </a-form-model-item>
+
+                <a-form-model-item label="应用范围" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="lunchNum">
+                    <a-checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange">
+                        Check all
+                    </a-checkbox>
+                    <a-checkbox-group v-model="checkedList" :options="plainOptions" @change="onChange" />
+                </a-form-model-item>
+
+                <a-form-model-item label="排序" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="dinnerNum">
+                    <a-input-number style="width:50%;" v-model="model.dinnerNum" :min="0"  placeholder="请输入排序"/>
+                </a-form-model-item>
+            </a-form-model>
+
+        </j-form-container>
+    </a-spin>
+</template>
+<script>
+import { getRoomPlans, getSelectList } from "@/api/api";
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+
+export default {
+    name: "BusMarketMemberForm",
+    props: {
+        disabled: {
+            type: Boolean,
+            default: false,
+            required: false,
+        },
+    },
+    data() {
+        return {
+            selectData:[],
+            model: {
+                id: "",
+                hotelId: 0,
+                name: null,
+                marketPrice: null,
+                canLivePersonNum: "0",
+                breakfastNum: 0,
+                lunchNum: 0,
+                dinnerNum: 0
+            },
+            labelCol: {
+                xs: { span: 24 },
+                sm: { span: 5 },
+            },
+            wrapperCol: {
+                xs: { span: 24 },
+                sm: { span: 16 },
+            },
+            confirmLoading: false,
+            validatorRules: {
+                name: [{ required: true, message: "请输入房型!" }],
+                marketPrice: [{ required: true, message: "请填写门市价!" }],
+                canLivePersonNum: [{ required: true, message: "请填写可住人数!" }],
+                breakfastNum: [{ required: true, message: "请填写早餐数量!" }],
+                lunchNum: [{ required: true, message: "请填写中餐数量!" }],
+                dinnerNum: [{ required: true, message: "请填写晚餐数量!" }],
+            },
+            url: {
+                add: "/rooms/cesRoomLayout/save",
+                edit: "/rooms/cesRoomLayout/modify",
+                queryById: "/rooms/cesRoomLayout/queryById",
+            },
+            iconChooseVisible: false,
+            roomPlans: [],
+            members: [],
+        };
+    },
+    computed: {
+        formDisabled() {
+            return this.disabled;
+        },
+    },
+    created() {
+        var _info = JSON.parse(localStorage.getItem("storeInfo"));
+        if (_info) {
+            this.model.hotelId = _info.id;
+            this.initData();
+        }
+        this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+        initData() {
+            getRoomPlans(this.model.hotelId, null).then((res) => {
+                if (res.success) {
+                    this.roomPlans = res.result;
+                }
+            });
+
+        },
+        selectIcons() {
+            this.iconChooseVisible = true;
+        },
+        handleIconCancel() {
+            this.iconChooseVisible = false;
+        },
+        handleIconChoose(value) {
+            console.log(value);
+            this.model.icon = value;
+            this.iconChooseVisible = false;
+        },
+        add() {
+            this.edit(this.modelDefault);
+        },
+        edit(record) {
+            this.model = Object.assign({}, record);
+            this.visible = true;
+            getSelectList({ id: this.model.id }).then((res) => {
+                if (res.success) {
+                    this.members = res.result;
+                }
+            });
+        },
+        submitForm() {
+            const that = this;
+            // 触发表单验证
+            this.$refs.form.validate((valid) => {
+                if (valid) {
+                    that.confirmLoading = true;
+                    let httpurl = "";
+                    let method = "";
+                    if (!this.model.id) {
+                        httpurl += this.url.add;
+                        method = "post";
+                    } else {
+                        httpurl += this.url.edit;
+                        method = "put";
+                    }
+                    if (this.model.payFlag == 0) {
+                        this.model.payAmount = 0;
+                    }
+                    httpAction(httpurl, this.model, method)
+                        .then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit("ok");
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        })
+                        .finally(() => {
+                            that.confirmLoading = false;
+                        });
+                }
+            });
+        },
+    },
+};
+</script>
+<style scoped>
+.avatar-uploader>.ant-upload {
+    width: 104px;
+    height: 104px;
+}
+</style>

+ 60 - 0
src/views/settings/components/roomModules/stockTypeModel.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="关闭">
+      <stock-type-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></stock-type-form>
+    </j-modal>
+  </template>
+  
+  <script>
+    import stockTypeForm from './stockTypeForm.vue'
+    export default {
+      name: 'stockTypeModel',
+      components: {
+        stockTypeForm
+      },
+      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>

+ 236 - 4
src/views/settings/components/salesPersonInfo.vue

@@ -1,13 +1,245 @@
 <template>
-    <div>营销人员管理</div>
+    <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="6" :sm="8">
+                        <a-form-item>
+                            <!--                            <j-dict-select-tag v-model="queryParam.hotelId" placeholder="请选择关联酒店" @change="e=>handleChangeHotel(e)"-->
+                            <!--                                               dictCode="bus_hotel_info,name,id,`status`=1 and check_status=1 and del_flag=0 "  />-->
+                            <a-select
+                                    :maxTagCount="1"
+                                    mode="multiple"
+                                    v-model="queryParam.hotelId"
+                                    placeholder="请选择"
+                                    :allowClear="true"
+                            >
+                                <a-select-option :value="item.id" v-for="(item,index) in hotelList" :key="index">{{ item.name }}</a-select-option>
+                            </a-select>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="4" :sm="6">
+                        <a-form-item>
+                            <a-input placeholder="关键字查询" v-model="queryParam.keyWord"></a-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>-->
+            <!-- 高级查询区域 -->
+<!--            <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="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>
+                <span slot="status" slot-scope="text,record">
+                    <a-tag v-if="text == 1" color="green">有效</a-tag>
+                    <a-tag v-else color="grey">无效</a-tag>
+                </span>
+                <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>
+
+        <sales-person-modal ref="modalForm" @ok="modalFormOk"></sales-person-modal>
+    </a-card>
 </template>
 
 <script>
+
+    import '@/assets/less/TableExpand.less'
+    import { mixinDevice } from '@/utils/mixin'
+    import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+    import salesPersonModal from './modules/salesPersonModal'
+    import { hotelQueryList } from '../../../api/hotel'
+
     export default {
-        name: "salesPersonInfo"
+        name: 'BusSalesPersonList',
+        mixins:[JeecgListMixin, mixinDevice],
+        components: {
+            salesPersonModal
+        },
+        data () {
+            return {
+                description: '营销人员管理管理页面',
+                // 表头
+                columns: [
+                    {
+                        title:'编号',
+                        align:"center",
+                        dataIndex: 'workNo'
+                    },
+                    {
+                        title:'姓名',
+                        align:"center",
+                        dataIndex: 'name'
+                    },
+                    {
+                        title:'关联操作用户',
+                        align:"center",
+                        dataIndex: 'operatorId'
+                    },
+                    {
+                        title:'联系电话',
+                        align:"center",
+                        dataIndex: 'mobile'
+                    },
+                    {
+                        title:'手机号',
+                        align:"center",
+                        dataIndex: 'phone'
+                    },
+                    {
+                        title:'地址',
+                        align:"center",
+                        dataIndex: 'address'
+                    },
+                    {
+                        title:'状态',
+                        align:"center",
+                        dataIndex: 'status',
+                        scopedSlots: { customRender: 'status' },
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align:"center",
+                        fixed:"right",
+                        width:147,
+                        scopedSlots: { customRender: 'action' }
+                    }
+                ],
+                url: {
+                    list: "/business/busSalesPerson/list",
+                    delete: "/business/busSalesPerson/delete",
+                    deleteBatch: "/business/busSalesPerson/deleteBatch",
+                    exportXlsUrl: "/business/busSalesPerson/exportXls",
+                    importExcelUrl: "business/busSalesPerson/importExcel",
+
+                },
+                dictOptions:{},
+                superFieldList:[],
+                hotelList:[],
+            }
+        },
+        created() {
+            this.getSuperFieldList();
+            this.initData();
+        },
+        computed: {
+            importExcelUrl: function(){
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            },
+        },
+        methods: {
+            initDictConfig(){
+            },
+            initData(){
+                hotelQueryList({
+                    key: ''
+                }).then(res => {
+                    console.log(res)
+                    if (res.code == 200 && res.result) {
+                        this.hotelList = res.result;
+                    }
+                })
+            },
+            getSuperFieldList(){
+                let fieldList=[];
+                fieldList.push({type:'string',value:'tenantId',text:'关联租户'})
+                fieldList.push({type:'string',value:'hotelId',text:'关联酒店'})
+                fieldList.push({type:'string',value:'workNo',text:'工号,唯一键'})
+                fieldList.push({type:'string',value:'name',text:'姓名'})
+                fieldList.push({type:'string',value:'operatorId',text:'关联操作用户'})
+                fieldList.push({type:'string',value:'mobile',text:'联系电话'})
+                fieldList.push({type:'string',value:'phone',text:'手机号'})
+                fieldList.push({type:'string',value:'address',text:'地址'})
+                fieldList.push({type:'int',value:'status',text:'状态(0-禁用;1-启用)'})
+                fieldList.push({type:'string',value:'remarks',text:'备注信息'})
+                fieldList.push({type:'int',value:'delFlag',text:'删除状态(0-正常,1-已删除)'})
+                this.superFieldList = fieldList
+            }
+        }
     }
 </script>
-
 <style scoped>
-
+    @import '~@assets/less/common.less';
 </style>

+ 1 - 1
src/views/settings/components/waiterSettings.vue

@@ -9,7 +9,7 @@
 <!--                            <j-dict-select-tag v-model="queryParam.hotelId" placeholder="请选择关联酒店" @change="e=>handleChangeHotel(e)"-->
 <!--                                               dictCode="bus_hotel_info,name,id,`status`=1 and check_status=1 and del_flag=0 "  />-->
                             <a-select
-                                    maxTagCount="1"
+                                    :maxTagCount="1"
                                     mode="multiple"
                                     v-model="queryParam.hotelId"
                                     placeholder="请选择"

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

@@ -20,6 +20,7 @@
                     <a-icon type="shop" />
                     商品库存
                 </span>
+               <goodList></goodList>     
             </a-tab-pane>
         </a-tabs>
     </a-card>
@@ -28,10 +29,12 @@
 <script>
 import roomLayoutList from "./components/roomModules/roomLayoutList.vue"
 import roomGen from "./components/roomModules/roomGen.vue";
+import goodList from "./components/roomModules/goodList.vue";
 export default {
     components: {
         roomLayoutList,
-        roomGen
+        roomGen,
+        goodList
     },
     data() {
         return {

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

@@ -4,39 +4,46 @@
             <a-tab-pane key="1">
                 <span slot="tab">
                     <a-icon type="template" />
+                    字典管理
+                </span>
+                <dictionary-info></dictionary-info>
+            </a-tab-pane>
+            <a-tab-pane key="2">
+                <span slot="tab">
+                    <a-icon type="template" />
                     打印模板设置
                 </span>
                 <print-template></print-template>
             </a-tab-pane>
-            <a-tab-pane key="2">
+            <a-tab-pane key="3">
                 <span slot="tab">
                     <a-icon type="pay" />
                     支付配置
                 </span>
                 <pay-settings></pay-settings>
             </a-tab-pane>
-            <a-tab-pane key="3">
+            <a-tab-pane key="4">
                 <span slot="tab">
                     <a-icon type="payinterface" />
                     支付接口配置
                 </span>
                 <pay-api-settings></pay-api-settings>
             </a-tab-pane>
-            <a-tab-pane key="4">
+            <a-tab-pane key="5">
                 <span slot="tab">
                     <a-icon type="parameter" />
                     参数配置
                 </span>
                 <param-settings></param-settings>
             </a-tab-pane>
-            <a-tab-pane key="5">
+            <a-tab-pane key="6">
                 <span slot="tab">
                     <a-icon type="waiter" />
                     服务员配置
                 </span>
                 <waiter-settings></waiter-settings>
             </a-tab-pane>
-            <a-tab-pane key="6">
+            <a-tab-pane key="7">
                 <span slot="tab">
                     <a-icon type="salesperson" />
                     营销人员管理
@@ -54,8 +61,10 @@
     import ParamSettings from "./components/paramSettings";
     import WaiterSettings from "./components/waiterSettings";
     import SalesPersonInfo from "./components/salesPersonInfo";
+    import DictionaryInfo from "./components/dictionaryInfo";
     export default {
         components:{
+            DictionaryInfo,
             SalesPersonInfo,
             WaiterSettings,
             ParamSettings,

+ 1 - 1
src/views/user/oauth2/OAuth2Login.vue

@@ -4,7 +4,7 @@
       <div id="loader"></div>
       <div class="loader-section section-left"></div>
       <div class="loader-section section-right"></div>
-      <div class="load_title">正在登录 JeecgBoot 低代码平台,请耐心等待</div>
+      <div class="load_title">正在登录,请耐心等待</div>
     </div>
   </div>
 </template>

+ 1 - 1
vue.config.js

@@ -116,4 +116,4 @@ module.exports = {
   },
 
   lintOnSave: undefined
-}
+}