gqx %!s(int64=2) %!d(string=hai) anos
pai
achega
d6588e80c0
Modificáronse 29 ficheiros con 4670 adicións e 0 borrados
  1. 151 0
      src/views/settings/components/pos/modules/PosMealSectionForm.vue
  2. 60 0
      src/views/settings/components/pos/modules/PosMealSectionModal.vue
  3. 151 0
      src/views/settings/components/pos/modules/PosRegionForm.vue
  4. 60 0
      src/views/settings/components/pos/modules/PosRegionModal.vue
  5. 123 0
      src/views/settings/components/pos/modules/PosSellClearGoodsForm.vue
  6. 60 0
      src/views/settings/components/pos/modules/PosSellClearGoodsModal.vue
  7. 246 0
      src/views/settings/components/pos/modules/PosTableForm.vue
  8. 60 0
      src/views/settings/components/pos/modules/PosTableModal.vue
  9. 151 0
      src/views/settings/components/pos/modules/PosTableTypeForm.vue
  10. 149 0
      src/views/settings/components/pos/modules/PosTableTypeInGoodsForm.vue
  11. 60 0
      src/views/settings/components/pos/modules/PosTableTypeInGoodsModal.vue
  12. 60 0
      src/views/settings/components/pos/modules/PosTableTypeModal.vue
  13. 318 0
      src/views/settings/components/pos/modules/PosThaliForm.vue
  14. 147 0
      src/views/settings/components/pos/modules/PosThaliInGoodsForm.vue
  15. 60 0
      src/views/settings/components/pos/modules/PosThaliInGoodsModal.vue
  16. 60 0
      src/views/settings/components/pos/modules/PosThaliModal.vue
  17. 139 0
      src/views/settings/components/pos/modules/PosTypeForm.vue
  18. 60 0
      src/views/settings/components/pos/modules/PosTypeModal.vue
  19. 465 0
      src/views/settings/components/pos/modules/SelectGoods.vue
  20. 65 0
      src/views/settings/components/pos/modules/SelectGoodsModal.vue
  21. 217 0
      src/views/settings/components/pos/modules/posTableTypeInGoods.vue
  22. 71 0
      src/views/settings/components/pos/modules/posTableTypeInGoodsListModal.vue
  23. 301 0
      src/views/settings/components/pos/posMealSection.vue
  24. 296 0
      src/views/settings/components/pos/posRegion.vue
  25. 231 0
      src/views/settings/components/pos/posSellClearGoods.vue
  26. 324 0
      src/views/settings/components/pos/posTable.vue
  27. 217 0
      src/views/settings/components/pos/posTableType.vue
  28. 309 0
      src/views/settings/components/pos/posThali.vue
  29. 59 0
      src/views/settings/posInfo.vue

+ 151 - 0
src/views/settings/components/pos/modules/PosMealSectionForm.vue

@@ -0,0 +1,151 @@
+<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="startTime2"
+            >
+              <a-time-picker v-model="model.startTime2" format="HH:mm" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="结束时间"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="endTime2"
+            >
+              <a-time-picker v-model="model.endTime2" format="HH:mm" />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+import moment from "moment";
+export default {
+  name: "PosMealSectionForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        tenantId: [{ required: true, message: "请输入关联租户!" }],
+        hotelId: [{ required: true, message: "请输入关联酒店!" }],
+        name: [{ required: true, message: "请输入餐段名称!" }],
+        startTime2: [{ required: true, message: "请输入开始时间!" }],
+        endTime2: [{ required: true, message: "请输入结束时间!" }],
+      },
+      url: {
+        add: "/pos/posMealSection/add",
+        edit: "/pos/posMealSection/edit",
+        queryById: "/pos/posMealSection/queryById",
+      },
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    moment,
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      if (this.model.startTime) {
+        this.model.startTime2 = moment(this.model.startTime, "HH:mm");
+        this.model.endTime2 = moment(this.model.endTime, "HH:mm");
+      }
+      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";
+          } else {
+            httpurl += this.url.edit;
+            method = "put";
+          }
+          this.model.startTime = moment(this.model.startTime2).format("HH:mm");
+          this.model.endTime = moment(this.model.endTime2).format("HH:mm");
+          httpAction(httpurl, this.model, method)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>

+ 60 - 0
src/views/settings/components/pos/modules/PosMealSectionModal.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="关闭">
+    <pos-meal-section-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></pos-meal-section-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import PosMealSectionForm from './PosMealSectionForm'
+  export default {
+    name: 'PosMealSectionModal',
+    components: {
+      PosMealSectionForm
+    },
+    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>

+ 151 - 0
src/views/settings/components/pos/modules/PosRegionForm.vue

@@ -0,0 +1,151 @@
+<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="pos类型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="posTypeId"
+            >
+              <a-select v-model="model.posTypeId" placeholder="请选择pos类型">
+                <a-select-option
+                  :value="item.id"
+                  v-for="item in posTypeList"
+                  :key="item.id"
+                >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </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: "PosRegionForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        tenantId: [{ required: true, message: "请输入关联租户!" }],
+        hotelId: [{ required: true, message: "请输入关联酒店!" }],
+        name: [{ required: true, message: "请输入区域名称!" }],
+        posTypeId: [{ required: true, message: "请输入pos类型id!" }],
+      },
+      url: {
+        add: "/pos/posRegion/add",
+        edit: "/pos/posRegion/edit",
+        queryById: "/pos/posRegion/queryById",
+      },
+      posTypeList: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    getAction("/pos/posType/list", {
+      hotelId: _info.id,
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.posTypeList = res.result.records;
+      }
+    });
+  },
+  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";
+          } else {
+            httpurl += this.url.edit;
+            method = "put";
+          }
+          httpAction(httpurl, this.model, method)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>

+ 60 - 0
src/views/settings/components/pos/modules/PosRegionModal.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="关闭">
+    <pos-region-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></pos-region-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import PosRegionForm from './PosRegionForm'
+  export default {
+    name: 'PosRegionModal',
+    components: {
+      PosRegionForm
+    },
+    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>

+ 123 - 0
src/views/settings/components/pos/modules/PosSellClearGoodsForm.vue

@@ -0,0 +1,123 @@
+<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="goodsId">
+              <a-input v-model="model.goodsId" placeholder="请输入商品id"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'PosSellClearGoodsForm',
+    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: '请输入关联酒店!'},
+           ],
+           goodsId: [
+              { required: true, message: '请输入商品id!'},
+           ],
+        },
+        url: {
+          add: "/pos/posSellClearGoods/add",
+          edit: "/pos/posSellClearGoods/edit",
+          queryById: "/pos/posSellClearGoods/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';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+         
+        })
+      },
+    }
+  }
+</script>

+ 60 - 0
src/views/settings/components/pos/modules/PosSellClearGoodsModal.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="关闭">
+    <pos-sell-clear-goods-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></pos-sell-clear-goods-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import PosSellClearGoodsForm from './PosSellClearGoodsForm'
+  export default {
+    name: 'PosSellClearGoodsModal',
+    components: {
+      PosSellClearGoodsForm
+    },
+    data () {
+      return {
+        title:'',
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>

+ 246 - 0
src/views/settings/components/pos/modules/PosTableForm.vue

@@ -0,0 +1,246 @@
+<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="pos类型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="posTypeId"
+            >
+              <a-select v-model="model.posTypeId" placeholder="请选择pos类型">
+                <a-select-option
+                  :value="item.id"
+                  v-for="item in posTypeList"
+                  :key="item.id"
+                >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="pos桌型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="posTableTypeId"
+            >
+              <a-select
+                v-model="model.posTableTypeId"
+                placeholder="请选择pos类型"
+              >
+                <a-select-option
+                  :value="item.id"
+                  v-for="item in tableTypeList"
+                  :key="item.id"
+                >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="pos餐桌区域"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="posRegionId"
+            >
+
+            <a-select
+                v-model="model.posRegionId"
+                placeholder="请选择pos类型"
+              >
+                <a-select-option
+                  :value="item.id"
+                  v-for="item in regionList"
+                  :key="item.id"
+                >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="座位数"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="num"
+            >
+              <a-input-number
+                v-model="model.num"
+                placeholder="请输入座位数"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="餐桌序号"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="tableNo"
+            >
+              <a-input
+                v-model="model.tableNo"
+                placeholder="请输入餐桌序号"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+export default {
+  name: "PosTableForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        tenantId: [{ required: true, message: "请输入关联租户!" }],
+        hotelId: [{ required: true, message: "请输入关联酒店!" }],
+        name: [{ required: true, message: "请输入餐桌名称!" }],
+        posTypeId: [{ required: true, message: "请输入pos类型id!" }],
+        posTableTypeId: [{ required: true, message: "请输入pos桌型id!" }],
+        posRegionId: [{ required: true, message: "请输入pos餐桌区域id!" }],
+        num: [{ required: true, message: "请输入座位数!" }],
+        tableNo: [{ required: true, message: "请输入餐桌序号!" }],
+        state: [{ required: true, message: "请输入状态!" }],
+      },
+      url: {
+        add: "/pos/posTable/add",
+        edit: "/pos/posTable/edit",
+        queryById: "/pos/posTable/queryById",
+      },
+      posTypeList: [],
+      tableTypeList: [],
+      regionList:[]
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    getAction("/pos/posType/list", {
+      hotelId: _info.id,
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.posTypeList = res.result.records;
+      }
+    });
+    getAction("/pos/posTableType/list", {
+      hotelId: _info.id,
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.tableTypeList = res.result.records;
+      }
+    });
+    getAction("/pos/posRegion/list", {
+      hotelId: _info.id,
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.regionList = res.result.records;
+      }
+    });
+  },
+  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";
+          } else {
+            httpurl += this.url.edit;
+            method = "put";
+          }
+          httpAction(httpurl, this.model, method)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>

+ 60 - 0
src/views/settings/components/pos/modules/PosTableModal.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="关闭">
+    <pos-table-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></pos-table-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import PosTableForm from './PosTableForm'
+  export default {
+    name: 'PosTableModal',
+    components: {
+      PosTableForm
+    },
+    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>

+ 151 - 0
src/views/settings/components/pos/modules/PosTableTypeForm.vue

@@ -0,0 +1,151 @@
+<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="pos类型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="posTypeId"
+            >
+            <a-select v-model="model.posTypeId" placeholder="请选择pos类型">
+                <a-select-option
+                  :value="item.id"
+                  v-for="item in posTypeList"
+                  :key="item.id"
+                >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </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: "PosTableTypeForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        tenantId: [{ required: true, message: "请输入关联租户!" }],
+        hotelId: [{ required: true, message: "请输入关联酒店!" }],
+        name: [{ required: true, message: "请输入桌型名称!" }],
+        posTypeId: [{ required: true, message: "请输入pos类型id!" }],
+      },
+      url: {
+        add: "/pos/posTableType/add",
+        edit: "/pos/posTableType/edit",
+        queryById: "/pos/posTableType/queryById",
+      },
+      posTypeList: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    getAction("/pos/posType/list", {
+      hotelId: _info.id,
+      pageNo: 1,
+      pageSize: 100,
+    }).then((res) => {
+      if (res.success) {
+        this.posTypeList = res.result.records;
+      }
+    });
+  },
+  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";
+          } 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>

+ 149 - 0
src/views/settings/components/pos/modules/PosTableTypeInGoodsForm.vue

@@ -0,0 +1,149 @@
+<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="pos桌型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="tableTypeName"
+            >
+              <a-input
+                disabled
+                v-model="model.tableTypeName"
+                placeholder="请输入pos桌型id"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="商品"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="goodsName"
+            >
+              <a-input
+                disabled
+                v-model="model.goodsName"
+                placeholder="请输入商品id"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="数量"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="num"
+            >
+              <a-input-number
+                v-model="model.num"
+                placeholder="请输入数量"
+                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: "PosTableTypeInGoodsForm",
+  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: "请输入关联酒店!" }],
+        posTableTypeId: [{ required: true, message: "请输入pos桌型id!" }],
+        goodsId: [{ required: true, message: "请输入商品id!" }],
+        num: [{ required: true, message: "请输入数量!" }],
+      },
+      url: {
+        add: "/pos/posTableTypeInGoods/add",
+        edit: "/pos/posTableTypeInGoods/edit",
+        queryById: "/pos/posTableTypeInGoods/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";
+          } else {
+            httpurl += this.url.edit;
+            method = "put";
+          }
+          httpAction(httpurl, this.model, method)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>

+ 60 - 0
src/views/settings/components/pos/modules/PosTableTypeInGoodsModal.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="关闭">
+    <pos-table-type-in-goods-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></pos-table-type-in-goods-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import PosTableTypeInGoodsForm from './PosTableTypeInGoodsForm'
+  export default {
+    name: 'PosTableTypeInGoodsModal',
+    components: {
+      PosTableTypeInGoodsForm
+    },
+    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>

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

+ 318 - 0
src/views/settings/components/pos/modules/PosThaliForm.vue

@@ -0,0 +1,318 @@
+<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="8">
+            <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="8">
+            <a-form-model-item
+              label="套餐条形码"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="barCode"
+            >
+              <a-input
+                v-model="model.barCode"
+                placeholder="请输入套餐条形码"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="8">
+            <a-form-model-item
+              label="分类"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="thailType"
+            >
+              <a-tree-select
+                v-model="model.thailType"
+                :tree-data="treeData"
+                :replaceFields="{
+                  children: 'children',
+                  title: 'name',
+                  key: 'id',
+                  value: 'id',
+                }"
+                placeholder="商品分类"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="8">
+            <a-form-model-item
+              label="售价"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="price"
+            >
+              <a-input-number
+                v-model="model.price"
+                placeholder="请输入售价"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="8">
+            <a-form-model-item
+              label="状态"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="state"
+            >
+              <a-switch
+                v-model="model.state"
+                checked-children="启用"
+                un-checked-children="停用"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="8">
+            <a-form-model-item
+              label="是否厨打"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="kitchen"
+            >
+              <a-switch
+                v-model="model.kitchen"
+                checked-children="是"
+                un-checked-children="否"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="8">
+            <a-form-model-item
+              label="备注"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="remark"
+            >
+              <a-textarea
+                v-model="model.remark"
+                rows="4"
+                placeholder="请输入备注"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-button @click="handleAdd" type="primary" icon="plus"
+              >选择商品</a-button
+            >
+            <a-table
+              :columns="columns"
+              :data-source="model.posThaliInGoodsList"
+              :pagination="false"
+              rowKey="id"
+            >
+              <template slot="num" slot-scope="text, record, index">
+                <div>
+                  <a-input-number v-model="record.num" :min="1" :max="99" />
+                </div>
+              </template>
+              <template slot="required" slot-scope="text, record, index">
+                <div>
+                  <a-switch v-model="record.required" />
+                </div>
+              </template>
+
+              <span slot="action" slot-scope="text, record, index">
+                <a @click="handleDelete(index)">删除</a>
+              </span>
+            </a-table>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+    <select-goods-modal ref="modalForm2" @ok="modalFormOk"></select-goods-modal>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+import { tree } from "@/api/good";
+import SelectGoodsModal from "./SelectGoodsModal";
+const columns = [
+  {
+    title: "商品名称",
+    dataIndex: "name",
+  },
+  {
+    title: "商品条码",
+    dataIndex: "barCode",
+  },
+  {
+    title: "库存",
+    dataIndex: "inventory",
+  },
+  {
+    title: "数量",
+    dataIndex: "num",
+    scopedSlots: { customRender: "num" },
+  },
+  {
+    title: "售价",
+    dataIndex: "sellingPrice",
+  },
+  {
+    title: "必选项",
+    dataIndex: "required",
+    scopedSlots: { customRender: "required" },
+  },
+  {
+    title: "操作",
+    dataIndex: "action",
+    align: "center",
+    fixed: "right",
+    width: 70,
+    scopedSlots: { customRender: "action" },
+  },
+];
+export default {
+  name: "PosThaliForm",
+  components: { SelectGoodsModal },
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      columns,
+      model: { posThaliInGoodsList: [] },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        tenantId: [{ required: true, message: "请输入关联租户!" }],
+        hotelId: [{ required: true, message: "请输入关联酒店!" }],
+        name: [{ required: true, message: "请输入套餐名称!" }],
+        posTypeId: [{ required: true, message: "请输入pos类型id!" }],
+        barCode: [{ required: true, message: "请输入套餐条形码!" }],
+        thailType: [{ required: true, message: "请输入分类!" }],
+        price: [{ required: true, message: "请输入售价!" }],
+      },
+      url: {
+        add: "/pos/posThali/add",
+        edit: "/pos/posThali/edit",
+        queryById: "/pos/posThali/queryById",
+      },
+      treeData: [],
+      goodsList: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    this.loadTree();
+  },
+  methods: {
+    handleDelete(index) {
+      this.model.posThaliInGoodsList.splice(index, 1);
+    },
+    modalFormOk(e) {
+      console.log("e", e);
+      e.forEach((t) => {
+        this.$set(t, "required", false);
+        this.$set(t, "num", 1);
+      });
+      this.model.posThaliInGoodsList = e;
+    },
+    handleAdd() {
+      this.$refs.modalForm2.edit({
+        formThali: true,
+      });
+      this.$refs.modalForm2.title = "商品选择";
+      this.$refs.modalForm2.disableSubmit = false;
+    },
+    loadTree() {
+      var that = this;
+      tree().then((res) => {
+        if (res.success) {
+          this.treeData = res.result;
+        }
+      });
+    },
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+      if (this.model.id) {
+        getAction("/pos/posThaliInGoods/list", {
+          posThaliId: this.model.id,
+        }).then((res) => {
+          if (res.success) {
+            this.model.posThaliInGoodsList = res.result.records;
+          }
+        });
+      }
+    },
+    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";
+          }
+          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>

+ 147 - 0
src/views/settings/components/pos/modules/PosThaliInGoodsForm.vue

@@ -0,0 +1,147 @@
+<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="posThaliId">
+              <a-input v-model="model.posThaliId" placeholder="请输入套餐id"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="商品id" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="goodsId">
+              <a-input v-model="model.goodsId" placeholder="请输入商品id"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="数量" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="num">
+              <a-input-number v-model="model.num" placeholder="请输入数量" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="必选项" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="required">
+              <a-input-number v-model="model.required" placeholder="请输入必选项" 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: 'PosThaliInGoodsForm',
+    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: '请输入关联酒店!'},
+           ],
+           posThaliId: [
+              { required: true, message: '请输入套餐id!'},
+           ],
+           goodsId: [
+              { required: true, message: '请输入商品id!'},
+           ],
+           num: [
+              { required: true, message: '请输入数量!'},
+           ],
+           required: [
+              { required: true, message: '请输入必选项!'},
+           ],
+        },
+        url: {
+          add: "/pos/posThaliInGoods/add",
+          edit: "/pos/posThaliInGoods/edit",
+          queryById: "/pos/posThaliInGoods/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';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+         
+        })
+      },
+    }
+  }
+</script>

+ 60 - 0
src/views/settings/components/pos/modules/PosThaliInGoodsModal.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="关闭">
+    <pos-thali-in-goods-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></pos-thali-in-goods-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import PosThaliInGoodsForm from './PosThaliInGoodsForm'
+  export default {
+    name: 'PosThaliInGoodsModal',
+    components: {
+      PosThaliInGoodsForm
+    },
+    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>

+ 60 - 0
src/views/settings/components/pos/modules/PosThaliModal.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="关闭">
+    <pos-thali-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></pos-thali-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import PosThaliForm from './PosThaliForm'
+  export default {
+    name: 'PosThaliModal',
+    components: {
+      PosThaliForm
+    },
+    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>

+ 139 - 0
src/views/settings/components/pos/modules/PosTypeForm.vue

@@ -0,0 +1,139 @@
+<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="名称" :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="state">
+              <a-input-number v-model="model.state" placeholder="请输入状态" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="线上预定" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="online">
+              <a-input-number v-model="model.online" placeholder="请输入线上预定" 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: 'PosTypeForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        confirmLoading: false,
+        validatorRules: {
+           tenantId: [
+              { required: true, message: '请输入关联租户!'},
+           ],
+           hotelId: [
+              { required: true, message: '请输入关联酒店!'},
+           ],
+           name: [
+              { required: true, message: '请输入名称!'},
+           ],
+           state: [
+              { required: true, message: '请输入状态!'},
+           ],
+           online: [
+              { required: true, message: '请输入线上预定!'},
+           ],
+        },
+        url: {
+          add: "/pos/posType/add",
+          edit: "/pos/posType/edit",
+          queryById: "/pos/posType/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';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+         
+        })
+      },
+    }
+  }
+</script>

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

+ 465 - 0
src/views/settings/components/pos/modules/SelectGoods.vue

@@ -0,0 +1,465 @@
+<template>
+  <div class="back">
+    <div class="back-left">
+      <!-- <a-button @click="handleStockTypeModelManager('-1',1)">添加分类</a-button> -->
+      <!-- <a-button @click="unitVisible=true" style="margin-left: 30px;">单位设置</a-button> -->
+      <a-tree
+        class="draggable-tree"
+        :tree-data="treeData"
+        blockNode
+        style="width: 200px"
+        :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-popconfirm placement="topLeft" ok-text="是的" cancel-text="取消" @confirm="confirmDel(item.id)">
+                        <template slot="title">
+                        确定删除吗?
+                        </template>
+                        <a-button style="font-size: 12px; padding: 0 5px;" type="link">删除</a-button>
+                    </a-popconfirm> -->
+        </div>
+      </a-tree>
+    </div>
+    <div class="back-right" style="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>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <!-- 查询区域-END -->
+        <div>
+          <a-table
+            ref="table"
+            size="middle"
+            bordered
+            rowKey="id"
+            :columns="columns"
+            :dataSource="dataSource"
+            :pagination="ipagination"
+            :loading="loading"
+            :rowSelection="{
+              selectedRowKeys: selectedRowKeys,
+              onChange: onSelectChange,
+            }"
+            class="j-table-force-nowrap"
+            @change="handleTableChange"
+          >
+            <span slot="state" slot-scope="record">
+              {{ record ? "启用" : "停用" }}
+              <!-- {{record}} -->
+            </span>
+            <span slot="action" slot-scope="text, record">
+              <a @click="handleEdit(record)">修改</a>
+              <a-divider type="vertical" />
+              <a @click="moreSet(record)">更多设置</a>
+              <a-divider type="vertical" />
+              <a-popconfirm
+                title="确定删除吗?"
+                @confirm="() => handleDelete(record.id)"
+              >
+                <a>删除</a>
+              </a-popconfirm>
+            </span>
+          </a-table>
+        </div>
+      </a-card>
+    </div>
+    <!-- 单位设置区域 -->
+    <!-- <SetUnit :unitVisible="unitVisible" @center="handleCancel" /> -->
+  </div>
+</template>
+<script>
+import { tree, delTree, goodBatchDel, goodSet } from "@/api/good";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+// import roomLayoutForm from './goodStock/goods'
+// import index from '/src/index.vue'
+// import stockTypeModel from './stockTypeModel.vue'
+// import Commodity from './moreSet/commodity.vue'
+// import GoodImg from './moreSet/goodImg.vue';
+// import moreSet from './moreSet/moreModal.vue'
+import { computed } from "vue";
+// import SetUnit from './setUnit/index.vue'
+import { httpAction, getAction, postAction } from "@/api/manage";
+const tabListNoTitle = [
+  {
+    key: "commodity",
+    tab: "商品小程序设置",
+  },
+  {
+    key: "goodImg",
+    tab: "商品图片",
+  },
+  {
+    key: "project",
+    tab: "餐饮设置",
+  },
+  {
+    key: "game",
+    tab: "娱乐设置",
+  },
+];
+export default {
+  name: "goodList",
+  mixins: [JeecgListMixin],
+  components: {
+    // stockTypeModel,
+    // roomLayoutForm,
+    // SetUnit,
+    // moreSet,
+    // index
+    // Commodity,
+    // GoodImg
+  },
+  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" }],
+            },
+          ],
+        },
+      ],
+
+      key: "tab1",
+      noTitleKey: "commodity",
+
+      checkedKeys: [""],
+      tabListNoTitle,
+      selectedKeys: [],
+      queryParam: {},
+      //单位对话框
+      unitVisible: false,
+      // 分页参数
+      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: "barCode",
+        },
+        {
+          title: "名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "售价",
+          align: "center",
+          dataIndex: "sellingPrice",
+        },
+        {
+          title: "库存量",
+          align: "center",
+          dataIndex: "inventory",
+        },
+      ],
+      url: {
+        // list: 'org.jeecg.modules.business/busMarketMember/list',
+        list: "/rooms/cesGoods/list",
+        // list: "/rooms/cesRoomLayout/list?hotelId",
+        // delete: "/rooms/cesRoomLayout/remove",
+        delete: "/rooms/cesGoods/delete",
+        // deleteBatch: "/rooms/cesRoomLayout/deleteBatch",
+        deleteBatch: "/rooms/cesGoods/delBatch",
+        exportXlsUrl: "/rooms/cesRoomLayout/exportXls",
+        importExcelUrl: "rooms/cesRoomLayout/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+      stockTypeVisible: false,
+      // 选中的数据
+      beforeTree: null,
+      goodsSetVisible: false, //进退货弹窗
+      moreSetVisible: false, //更多设置弹窗
+      goodsSetData: {
+        number: 0,
+        type: 1,
+      },
+      model: { hotelId: "" },
+    };
+  },
+  computed: {},
+  watch: {},
+  created() {
+    this.loadTree();
+  },
+  provide() {
+    return {
+      beforeTree: computed(() =>
+        this.beforeTree ? this.beforeTree : { id: "0" }
+      ),
+      treeData: computed(() => this.treeData),
+      dataSource: computed(() => this.dataSource),
+    };
+  },
+  methods: {
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+    submitForm() {
+      const that = this;
+      if (this.selectedRowKeys.length > 0) {
+        if (this.model.formThali) {
+          that.$emit("ok", this.selectionRows);
+        } else {
+          var list = [];
+          this.selectedRowKeys.forEach((item) => {
+            list.push({
+              hotelId: this.model.hotelId,
+              posTableTypeId: this.model.posTableTypeId,
+              goodsId: item,
+              num: 1,
+            });
+          });
+          that.confirmLoading = true;
+
+          postAction("/pos/posTableTypeInGoods/addBatch", list)
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      }
+    },
+    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;
+    },
+    /**
+     * 保存成功
+     */
+    onSave() {
+      this.loadTree();
+    },
+    /**
+     * 删除
+     */
+    confirmDel(id) {
+      delTree({ id: id }).then((res) => {
+        if (res.code && res.code == 200) {
+          this.$message.success("删除成功");
+          this.loadTree();
+        }
+      });
+    },
+    //批量删除
+    goodBatchDel() {
+      console.log(this.selectedRowKeys);
+      if (this.selectedRowKeys.length == 0) {
+        this.$message.info("请先选择要删除的数据");
+        return;
+      }
+      this.$confirm({
+        title: "提示",
+        content: "确认要删除吗",
+        okText: "确认",
+        cancelText: "取消",
+        onOk: (e) => {
+          return goodBatchDel({ idStr: this.selectedRowKeys.toString() }).then(
+            (res) => {
+              if (res.code && res.code == 200) {
+                this.$message.success(res.message);
+                this.loadData();
+              } else {
+                this.$message.error(res.message);
+              }
+            }
+          );
+        },
+      });
+    },
+    //单位设置区域
+    handleOk(e) {
+      // this.confirmLoading = true;
+      // setTimeout(() => {
+      //     this.visible = false;
+      //     this.confirmLoading = false;
+      // }, 2000);
+      this.unitVisible = false;
+    },
+    handleCancel(e) {
+      console.log("Clicked cancel button", e);
+      this.unitVisible = false;
+    },
+    /**
+     * 进退货
+     */
+    goodsSet() {
+      this.goodsSetData = this.dataSource.filter(
+        (item) => item.id == this.selectedRowKeys.toString()
+      )[0];
+      console.log(this.goodsSetData);
+      this.goodsSetVisible = true;
+    },
+    goodChange(e) {
+      console.log(e);
+      this.goodsSetData.type = e.target.value;
+    },
+    //更多设置
+    moreSet(record) {
+      console.log(this.$refs.modalSet);
+      this.$refs.modalSet.edit(record);
+      this.$refs.modalForm.disableSubmit = false;
+      // this.moreSetVisible = true
+    },
+    //更多设置确认
+    handleMoreSetOk() {},
+    //更多设置切换卡片
+    onTabChange(key, type) {
+      console.log(key, type);
+      this[type] = key;
+    },
+
+    //进退货确认事件
+    handleGoodOk() {
+      console.log(this.goodsSetData);
+      if (!this.goodsSetData.type) {
+        this.goodsSetData.type = 1;
+      }
+      let obj = {
+        hotelId: this.goodsSetData.hotelId,
+        goodId: this.goodsSetData.id,
+        type: this.goodsSetData.type,
+        goodNum: this.goodsSetData.goodNum,
+        remark: this.goodsSetData.remark ? this.goodsSetData.remark : "",
+      };
+      // this.goodsSetData.goodId = this.goodsSetData.id
+      goodSet(obj).then((res) => {
+        if (res.code && res.code == 200) {
+          this.$message.success(res.message);
+          this.goodsSetVisible = false;
+          // this.goodsSetData = {}
+          this.loadData();
+        } else {
+          this.$message.error(res.message);
+        }
+      });
+    },
+    //进退货取消
+    handleGoodCancel() {
+      this.goodsSetVisible = false;
+    },
+  },
+};
+</script>
+<style scoped>
+.back {
+  display: flex;
+  justify-content: space-between;
+}
+
+.back-left {
+  /* flex: 1 */
+}
+
+.back-right {
+  flex: 1;
+}
+
+.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>

+ 65 - 0
src/views/settings/components/pos/modules/SelectGoodsModal.vue

@@ -0,0 +1,65 @@
+<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 "./SelectGoods.vue";
+export default {
+  name: "stockTypeModel",
+  components: {
+    stockTypeForm,
+  },
+  data() {
+    return {
+      title: "",
+      width: 1200,
+      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(e) {
+      this.$emit("ok", e);
+      this.visible = false;
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

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

@@ -0,0 +1,217 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline">
+        <a-row :gutter="24">
+          <a-col :span="6">
+            <a-form-item label="">
+              <a-input
+                disabled
+                placeholder="区域名称"
+                v-model="model.name"
+              ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+              <a-button @click="handleAdd" type="primary" icon="plus"
+                >新增</a-button
+              >
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 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="payFlagslot" slot-scope="text, record, index">
+          {{ record.payFlag == 1 ? "是" : "否" }}
+        </template>
+        <template slot="iconslot" slot-scope="text, record, index">
+          <a-icon :type="record.icon" theme="filled" />
+        </template>
+        <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>
+        <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-popconfirm
+            title="确定删除吗?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+
+    <pos-region-modal ref="modalForm" @ok="modalFormOk"></pos-region-modal>
+    <select-goods-modal ref="modalForm2" @ok="modalFormOk"></select-goods-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import PosRegionModal from "./PosTableTypeInGoodsModal";
+import SelectGoodsModal from "./SelectGoodsModal";
+import { filterObj } from "@/utils/util";
+import { getAction } from "@/api/manage";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    PosRegionModal,
+    SelectGoodsModal,
+  },
+  props: {
+    posTableTypeId: {
+      type: String,
+    },
+  },
+  data() {
+    return {
+      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: "goodsName",
+        },
+        {
+          title: "价格",
+          align: "center",
+          dataIndex: "price",
+        },
+        {
+          title: "数量",
+          align: "center",
+          dataIndex: "num",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list:
+          "/pos/posTableTypeInGoods/list?posTableTypeId=" + this.posTableTypeId,
+        delete: "/pos/posTableTypeInGoods/delete",
+        deleteBatch: "/pos/posTableTypeInGoods/deleteBatch",
+        exportXlsUrl: "/pos/posTableTypeInGoods/exportXls",
+        importExcelUrl: "pos/posTableTypeInGoods/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+      model: {},
+    };
+  },
+  created() {
+    console.log("this.posTableTypeId",this.posTableTypeId)
+  },
+  methods: {
+    handleAdd() {
+      var _info = JSON.parse(localStorage.getItem("storeInfo"));
+
+      this.$refs.modalForm2.edit({
+        hotelId: _info.id,
+        posTableTypeId: this.model.id,
+      });
+      this.$refs.modalForm2.title = "商品选择";
+      this.$refs.modalForm2.disableSubmit = false;
+    },
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.visible = true;
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 71 - 0
src/views/settings/components/pos/modules/posTableTypeInGoodsListModal.vue

@@ -0,0 +1,71 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
+    @cancel="handleCancel"
+    cancelText="关闭"
+  >
+    <pos-table-type-in-goods
+      ref="realForm"
+      @ok="submitCallback"
+      :disabled="disableSubmit"
+      :posTableTypeId="posTableTypeId"
+    ></pos-table-type-in-goods>
+  </j-modal>
+</template>
+
+<script>
+import posTableTypeInGoods from "./posTableTypeInGoods";
+export default {
+  name: "PosThaliInGoodsModal",
+  components: {
+    posTableTypeInGoods,
+  },
+  props: {
+    posTableTypeId: {
+      type: String,
+    },
+  },
+  data() {
+    return {
+      title: "",
+      width: 800,
+      visible: false,
+      disableSubmit: false,
+    };
+  },
+  methods: {
+    add() {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.realForm.add();
+      });
+    },
+    edit(record) {
+      console.log('posTableTypeId2',this.posTableTypeId)
+      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>

+ 301 - 0
src/views/settings/components/pos/posMealSection.vue

@@ -0,0 +1,301 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="餐段名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+              <a-button type="primary" @click="searchQuery" icon="search"
+                >查询</a-button
+              >
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+                >重置</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>
+    </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="payFlagslot" slot-scope="text, record, index">
+          {{ record.payFlag == 1 ? "是" : "否" }}
+        </template>
+        <template slot="iconslot" slot-scope="text, record, index">
+          <a-icon :type="record.icon" theme="filled" />
+        </template>
+        <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>
+        <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-popconfirm
+            title="确定删除吗?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+
+    <pos-thali-modal ref="modalForm" @ok="modalFormOk"></pos-thali-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import posThaliModal from "./modules/PosMealSectionModal";
+import { filterObj } from "@/utils/util";
+import { getAction } from "@/api/manage";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    posThaliModal,
+  },
+  data() {
+    return {
+      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: "name",
+        },
+        {
+          title: "开始时间",
+          align: "center",
+          dataIndex: "startTime",
+        },
+        {
+          title: "结束时间",
+          align: "center",
+          dataIndex: "endTime",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/pos/posMealSection/list",
+        delete: "/pos/posMealSection/delete",
+        deleteBatch: "/pos/posMealSection/deleteBatch",
+        exportXlsUrl: "/pos/posMealSection/exportXls",
+        importExcelUrl: "pos/posMealSection/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+    };
+  },
+  created() {
+    // this.loadData()
+  },
+  methods: {
+    // searchQuery() {
+    //   this.loadData(1);
+    // },
+    // loadData(arg) {
+    //   //加载数据 若传入参数1则加载第一页的内容
+    //   if (arg === 1) {
+    //     this.ipagination.current = 1;
+    //   }
+    //   var params = this.getQueryParams(); //查询条件
+    //   getAction(this.url.list, params).then((res) => {
+    //     if (res.success) {
+    //       this.dataSource1 = res.result.records;
+    //       this.ipagination.total = res.result.total;
+    //     }
+    //   });
+    // },
+    // getQueryParams() {
+    //   var param = Object.assign({}, this.queryParam, this.isorter);
+    //   param.pageNo = this.ipagination.current;
+    //   param.pageSize = this.ipagination.pageSize;
+    //   return filterObj(param);
+    // },
+    getAvatarView: function (avatar) {
+      return getFileAccessHttpUrl(avatar);
+    },
+
+    batchFrozen: function (status) {
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return false;
+      } else {
+        let ids = "";
+        let that = this;
+        let isAdmin = false;
+        that.selectionRows.forEach(function (row) {
+          if (row.username == "admin") {
+            isAdmin = true;
+          }
+        });
+        if (isAdmin) {
+          that.$message.warning("管理员账号不允许此操作,请重新选择!");
+          return;
+        }
+        that.selectedRowKeys.forEach(function (val) {
+          ids += val + ",";
+        });
+        that.$confirm({
+          title: "确认操作",
+          content: "是否" + (status == 1 ? "解冻" : "冻结") + "选中账号?",
+          onOk: function () {
+            frozenBatch({ ids: ids, status: status }).then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.loadData();
+                that.onClearSelected();
+              } else {
+                that.$message.warning(res.message);
+              }
+            });
+          },
+        });
+      }
+    },
+    handleMenuClick(e) {
+      if (e.key == 1) {
+        this.batchDel();
+      } else if (e.key == 2) {
+        this.batchFrozen(2);
+      } else if (e.key == 3) {
+        this.batchFrozen(1);
+      }
+    },
+    handleFrozen: function (id, status, username) {
+      let that = this;
+      //TODO 后台校验管理员角色
+      if ("admin" == username) {
+        that.$message.warning("管理员账号不允许此操作!");
+        return;
+      }
+      frozenBatch({ ids: id, status: status }).then((res) => {
+        if (res.success) {
+          that.$message.success(res.message);
+          that.loadData();
+        } else {
+          that.$message.warning(res.message);
+        }
+      });
+    },
+    handleChangePassword(username) {
+      this.$refs.passwordmodal.show(username);
+    },
+    passwordModalOk() {
+      //TODO 密码修改完成 不需要刷新页面,可以把datasource中的数据更新一下
+    },
+    onSyncFinally({ isToLocal }) {
+      // 同步到本地时刷新下数据
+      if (isToLocal) {
+        this.loadData();
+      }
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 296 - 0
src/views/settings/components/pos/posRegion.vue

@@ -0,0 +1,296 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="区域名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+              <a-button type="primary" @click="searchQuery" icon="search"
+                >查询</a-button
+              >
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+                >重置</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>
+    </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="payFlagslot" slot-scope="text, record, index">
+          {{ record.payFlag == 1 ? "是" : "否" }}
+        </template>
+        <template slot="iconslot" slot-scope="text, record, index">
+          <a-icon :type="record.icon" theme="filled" />
+        </template>
+        <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>
+        <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-popconfirm
+            title="确定删除吗?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+
+    <pos-region-modal ref="modalForm" @ok="modalFormOk"></pos-region-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import PosRegionModal from "./modules/PosRegionModal";
+import { filterObj } from "@/utils/util";
+import { getAction } from "@/api/manage";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    PosRegionModal,
+  },
+  data() {
+    return {
+      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: "pos类型",
+          align: "center",
+          dataIndex: "typeName",
+        },
+        {
+          title: "区域名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/pos/posRegion/list",
+        delete: "/pos/posRegion/delete",
+        deleteBatch: "/pos/posRegion/deleteBatch",
+        exportXlsUrl: "/pos/posRegion/exportXls",
+        importExcelUrl: "pos/posRegion/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+    };
+  },
+  created() {
+    // this.loadData()
+  },
+  methods: {
+    // searchQuery() {
+    //   this.loadData(1);
+    // },
+    // loadData(arg) {
+    //   //加载数据 若传入参数1则加载第一页的内容
+    //   if (arg === 1) {
+    //     this.ipagination.current = 1;
+    //   }
+    //   var params = this.getQueryParams(); //查询条件
+    //   getAction(this.url.list, params).then((res) => {
+    //     if (res.success) {
+    //       this.dataSource1 = res.result.records;
+    //       this.ipagination.total = res.result.total;
+    //     }
+    //   });
+    // },
+    // getQueryParams() {
+    //   var param = Object.assign({}, this.queryParam, this.isorter);
+    //   param.pageNo = this.ipagination.current;
+    //   param.pageSize = this.ipagination.pageSize;
+    //   return filterObj(param);
+    // },
+    getAvatarView: function (avatar) {
+      return getFileAccessHttpUrl(avatar);
+    },
+
+    batchFrozen: function (status) {
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return false;
+      } else {
+        let ids = "";
+        let that = this;
+        let isAdmin = false;
+        that.selectionRows.forEach(function (row) {
+          if (row.username == "admin") {
+            isAdmin = true;
+          }
+        });
+        if (isAdmin) {
+          that.$message.warning("管理员账号不允许此操作,请重新选择!");
+          return;
+        }
+        that.selectedRowKeys.forEach(function (val) {
+          ids += val + ",";
+        });
+        that.$confirm({
+          title: "确认操作",
+          content: "是否" + (status == 1 ? "解冻" : "冻结") + "选中账号?",
+          onOk: function () {
+            frozenBatch({ ids: ids, status: status }).then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.loadData();
+                that.onClearSelected();
+              } else {
+                that.$message.warning(res.message);
+              }
+            });
+          },
+        });
+      }
+    },
+    handleMenuClick(e) {
+      if (e.key == 1) {
+        this.batchDel();
+      } else if (e.key == 2) {
+        this.batchFrozen(2);
+      } else if (e.key == 3) {
+        this.batchFrozen(1);
+      }
+    },
+    handleFrozen: function (id, status, username) {
+      let that = this;
+      //TODO 后台校验管理员角色
+      if ("admin" == username) {
+        that.$message.warning("管理员账号不允许此操作!");
+        return;
+      }
+      frozenBatch({ ids: id, status: status }).then((res) => {
+        if (res.success) {
+          that.$message.success(res.message);
+          that.loadData();
+        } else {
+          that.$message.warning(res.message);
+        }
+      });
+    },
+    handleChangePassword(username) {
+      this.$refs.passwordmodal.show(username);
+    },
+    passwordModalOk() {
+      //TODO 密码修改完成 不需要刷新页面,可以把datasource中的数据更新一下
+    },
+    onSyncFinally({ isToLocal }) {
+      // 同步到本地时刷新下数据
+      if (isToLocal) {
+        this.loadData();
+      }
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 231 - 0
src/views/settings/components/pos/posSellClearGoods.vue

@@ -0,0 +1,231 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :span="6">
+            <a-tree-select
+              v-model="queryParam.goodType"
+              :tree-data="treeData"
+              :replaceFields="{
+                children: 'children',
+                title: 'name',
+                key: 'id',
+                value: 'id',
+              }"
+              placeholder="商品分类"
+            />
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+              <a-button type="primary" @click="searchQuery" icon="search"
+                >查询</a-button
+              >
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+                >重置</a-button
+              >
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button v-if="sellClear == 1" @click="handleAdd">立即沽清</a-button>
+      <a-button v-if="sellClear == 2" @click="handleDelete">取消沽清</a-button>
+    </div>
+
+    <div>
+      <a-row :gutter="[5, 5]">
+        <a-col
+          v-for="item in dataSource"
+          :key="item.id"
+          :span="2"
+          @click.stop="itemClick(item)"
+        >
+          <div
+            class="room-item"
+            :class="item.sort == 888888 ? 'check' : ''"
+            :style="{
+              background: item.isSellClear ? 'grey' : 'goldenrod',
+            }"
+          >
+            <div>{{ item.name }}</div>
+            <div style="margin-top: 20px">
+              ¥{{ item.sellingPrice.toFixed(2) }}
+            </div>
+            <div
+              v-if="item.isSellClear"
+              style="display: flex; justify-content: right"
+            >
+              <a-tag color="#f50"> 沽清 </a-tag>
+            </div>
+          </div>
+        </a-col>
+      </a-row>
+    </div>
+
+    <pos-region-modal ref="modalForm" @ok="modalFormOk"></pos-region-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import PosRegionModal from "./modules/PosRegionModal";
+import { filterObj } from "@/utils/util";
+import { getAction, postAction, deleteAction } from "@/api/manage";
+import { tree } from "@/api/good";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    PosRegionModal,
+  },
+  data() {
+    return {
+      sellClear: 0,
+      queryParam: {},
+      // 分页参数
+      ipagination: {
+        current: 1,
+        pageSize: 99999,
+        pageSizeOptions: ["10", "20", "30"],
+        showTotal: (total, range) => {
+          return range[0] + "-" + range[1] + " 共" + total + "条";
+        },
+        showQuickJumper: true,
+        showSizeChanger: true,
+        total: 0,
+      },
+      // 表头
+      columns: [
+        {
+          title: "pos类型",
+          align: "center",
+          dataIndex: "typeName",
+        },
+        {
+          title: "区域名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/pos/posSellClearGoods/list",
+        delete: "/pos/posSellClearGoods/delete",
+        deleteBatch: "/pos/posSellClearGoods/deleteBatch",
+        exportXlsUrl: "/pos/posSellClearGoods/exportXls",
+        importExcelUrl: "pos/posSellClearGoods/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+      treeData: [],
+      selectGoods: {},
+    };
+  },
+  created() {
+    this.loadTree();
+  },
+  methods: {
+    handleDelete() {
+      deleteAction("/pos/posSellClearGoods/delete", {
+        goodsId: this.selectGoods.id,
+      })
+        .then((res) => {
+          if (res.success) {
+            this.$message.success(res.message);
+            this.loadData();
+            this.sellClear = 0;
+          } else {
+            this.$message.warning(res.message);
+          }
+        })
+        .finally(() => {});
+    },
+    handleAdd() {
+      var _info = JSON.parse(localStorage.getItem("storeInfo"));
+      var model = { goodsId: this.selectGoods.id };
+      if (_info) {
+        model.hotelId = _info.id;
+      }
+      postAction("/pos/posSellClearGoods/add", model)
+        .then((res) => {
+          if (res.success) {
+            this.$message.success(res.message);
+            this.loadData();
+            this.sellClear = 0;
+          } else {
+            this.$message.warning(res.message);
+          }
+        })
+        .finally(() => {});
+    },
+    itemClick(row) {
+      console.log(row);
+      if (row.sort != 888888) {
+        this.selectGoods = row;
+        var list = this.dataSource.filter((t) => (t) => t.sort == 888888);
+        list.forEach((t) => {
+          t.sort = 0;
+        });
+        row.sort = 888888;
+        if (row.isSellClear) {
+          this.sellClear = 2;
+        } else {
+          this.sellClear = 1;
+        }
+      } else {
+        row.sort = 0;
+        this.sellClear = 0;
+      }
+    },
+    loadTree() {
+      var that = this;
+      tree().then((res) => {
+        if (res.success) {
+          this.treeData = res.result;
+        }
+      });
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+.room-item {
+  height: 110px;
+  /* line-height: 200px; */
+  font-size: 13px;
+  color: #f9f9f9;
+  padding: 20px 10px;
+  border-radius: 5px;
+  cursor: pointer;
+  position: relative;
+}
+.check {
+  border: #000 solid 3px;
+}
+</style>

+ 324 - 0
src/views/settings/components/pos/posTable.vue

@@ -0,0 +1,324 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="餐桌名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+              <a-button type="primary" @click="searchQuery" icon="search"
+                >查询</a-button
+              >
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+                >重置</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>
+    </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="payFlagslot" slot-scope="text, record, index">
+          {{ record.payFlag == 1 ? "是" : "否" }}
+        </template>
+        <template slot="iconslot" slot-scope="text, record, index">
+          <a-icon :type="record.icon" theme="filled" />
+        </template>
+        <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>
+        <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-popconfirm
+            title="确定删除吗?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+
+    <pos-table-modal ref="modalForm" @ok="modalFormOk"></pos-table-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import PosTableModal from "./modules/PosTableModal";
+import { filterObj } from "@/utils/util";
+import { getAction } from "@/api/manage";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    PosTableModal,
+  },
+  data() {
+    return {
+      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: "pos类型",
+          align: "center",
+          dataIndex: "typeName",
+        },
+        {
+          title: "餐桌区域",
+          align: "center",
+          dataIndex: "regionName",
+        },
+        {
+          title: "餐桌名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "桌型",
+          align: "center",
+          dataIndex: "tableTypeName",
+        },
+        {
+          title: "座位数",
+          align: "center",
+          dataIndex: "num",
+        },
+        {
+          title: "餐桌序号",
+          align: "center",
+          dataIndex: "tableNo",
+        },
+        {
+          title: "状态",
+          align: "center",
+          dataIndex: "state",
+          customRender: function (text) {
+            return text == 0 ? "空桌台" : "用餐中";
+          },
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/pos/posTable/list",
+        delete: "/pos/posTable/delete",
+        deleteBatch: "/pos/posTable/deleteBatch",
+        exportXlsUrl: "/pos/posTable/exportXls",
+        importExcelUrl: "pos/posTable/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+    };
+  },
+  created() {
+    // this.loadData()
+  },
+  methods: {
+    // searchQuery() {
+    //   this.loadData(1);
+    // },
+    // loadData(arg) {
+    //   //加载数据 若传入参数1则加载第一页的内容
+    //   if (arg === 1) {
+    //     this.ipagination.current = 1;
+    //   }
+    //   var params = this.getQueryParams(); //查询条件
+    //   getAction(this.url.list, params).then((res) => {
+    //     if (res.success) {
+    //       this.dataSource1 = res.result.records;
+    //       this.ipagination.total = res.result.total;
+    //     }
+    //   });
+    // },
+    // getQueryParams() {
+    //   var param = Object.assign({}, this.queryParam, this.isorter);
+    //   param.pageNo = this.ipagination.current;
+    //   param.pageSize = this.ipagination.pageSize;
+    //   return filterObj(param);
+    // },
+    getAvatarView: function (avatar) {
+      return getFileAccessHttpUrl(avatar);
+    },
+
+    batchFrozen: function (status) {
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return false;
+      } else {
+        let ids = "";
+        let that = this;
+        let isAdmin = false;
+        that.selectionRows.forEach(function (row) {
+          if (row.username == "admin") {
+            isAdmin = true;
+          }
+        });
+        if (isAdmin) {
+          that.$message.warning("管理员账号不允许此操作,请重新选择!");
+          return;
+        }
+        that.selectedRowKeys.forEach(function (val) {
+          ids += val + ",";
+        });
+        that.$confirm({
+          title: "确认操作",
+          content: "是否" + (status == 1 ? "解冻" : "冻结") + "选中账号?",
+          onOk: function () {
+            frozenBatch({ ids: ids, status: status }).then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.loadData();
+                that.onClearSelected();
+              } else {
+                that.$message.warning(res.message);
+              }
+            });
+          },
+        });
+      }
+    },
+    handleMenuClick(e) {
+      if (e.key == 1) {
+        this.batchDel();
+      } else if (e.key == 2) {
+        this.batchFrozen(2);
+      } else if (e.key == 3) {
+        this.batchFrozen(1);
+      }
+    },
+    handleFrozen: function (id, status, username) {
+      let that = this;
+      //TODO 后台校验管理员角色
+      if ("admin" == username) {
+        that.$message.warning("管理员账号不允许此操作!");
+        return;
+      }
+      frozenBatch({ ids: id, status: status }).then((res) => {
+        if (res.success) {
+          that.$message.success(res.message);
+          that.loadData();
+        } else {
+          that.$message.warning(res.message);
+        }
+      });
+    },
+    handleChangePassword(username) {
+      this.$refs.passwordmodal.show(username);
+    },
+    passwordModalOk() {
+      //TODO 密码修改完成 不需要刷新页面,可以把datasource中的数据更新一下
+    },
+    onSyncFinally({ isToLocal }) {
+      // 同步到本地时刷新下数据
+      if (isToLocal) {
+        this.loadData();
+      }
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 217 - 0
src/views/settings/components/pos/posTableType.vue

@@ -0,0 +1,217 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="桌型名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+              <a-button type="primary" @click="searchQuery" icon="search"
+                >查询</a-button
+              >
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+                >重置</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>
+    </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="payFlagslot" slot-scope="text, record, index">
+          {{ record.payFlag == 1 ? "是" : "否" }}
+        </template>
+        <template slot="iconslot" slot-scope="text, record, index">
+          <a-icon :type="record.icon" theme="filled" />
+        </template>
+        <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>
+        <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="handleInGoods(record)">自动新增项目设置</a>
+
+          <a-divider type="vertical" />
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-popconfirm
+            title="确定删除吗?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+
+    <pos-table-type-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></pos-table-type-modal>
+    <pos-table-type-in-goods-modal
+      ref="modalForm2"
+      @ok="modalFormOk"
+      :posTableTypeId="posTableTypeId"
+    ></pos-table-type-in-goods-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import PosTableTypeModal from "./modules/PosTableTypeModal";
+import posTableTypeInGoodsModal from "./modules/posTableTypeInGoodsListModal";
+import { filterObj } from "@/utils/util";
+import { getAction } from "@/api/manage";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    PosTableTypeModal,
+    posTableTypeInGoodsModal,
+  },
+  data() {
+    return {
+      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: "pos类型",
+          align: "center",
+          dataIndex: "typeName",
+        },
+        {
+          title: "桌型名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/pos/posTableType/list",
+        delete: "/pos/posTableType/delete",
+        deleteBatch: "/pos/posTableType/deleteBatch",
+        exportXlsUrl: "/pos/posTableType/exportXls",
+        importExcelUrl: "pos/posTableType/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+      posTableTypeId: "",
+    };
+  },
+  created() {
+    // this.loadData()
+  },
+  methods: {
+    handleInGoods(row) {
+      console.log(row)
+      this.posTableTypeId = row.id;
+      this.$refs.modalForm2.edit(row);
+      this.$refs.modalForm2.title = "开单自动新增项目配置";
+      this.$refs.modalForm2.disableSubmit = true;
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 309 - 0
src/views/settings/components/pos/posThali.vue

@@ -0,0 +1,309 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="套餐名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+              <a-button type="primary" @click="searchQuery" icon="search"
+                >查询</a-button
+              >
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+                >重置</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>
+    </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="payFlagslot" slot-scope="text, record, index">
+          {{ record.payFlag == 1 ? "是" : "否" }}
+        </template>
+        <template slot="iconslot" slot-scope="text, record, index">
+          <a-icon :type="record.icon" theme="filled" />
+        </template>
+        <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>
+        <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-popconfirm
+            title="确定删除吗?"
+            @confirm="() => handleDelete(record.id)"
+          >
+            <a>删除</a>
+          </a-popconfirm>
+        </span>
+      </a-table>
+    </div>
+
+    <pos-thali-modal ref="modalForm" @ok="modalFormOk"></pos-thali-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import posThaliModal from "./modules/PosThaliModal";
+import { filterObj } from "@/utils/util";
+import { getAction } from "@/api/manage";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    posThaliModal,
+  },
+  data() {
+    return {
+      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: "name",
+        },
+        {
+          title: "套餐条码",
+          align: "center",
+          dataIndex: "barCode",
+        },
+        {
+          title: "售价",
+          align: "center",
+          dataIndex: "price",
+        },
+        {
+          title: "状态",
+          align: "center",
+          dataIndex: "state",
+          customRender(text) {
+            return text ? "启用" : "停用";
+          },
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/pos/posThali/list",
+        delete: "/pos/posThali/delete",
+        deleteBatch: "/pos/posThali/deleteBatch",
+        exportXlsUrl: "/pos/posThali/exportXls",
+        importExcelUrl: "pos/posThali/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      selectedRowKeys: [],
+      isorter: {
+        column: "createTime",
+        order: "desc",
+      },
+    };
+  },
+  created() {
+    // this.loadData()
+  },
+  methods: {
+    // searchQuery() {
+    //   this.loadData(1);
+    // },
+    // loadData(arg) {
+    //   //加载数据 若传入参数1则加载第一页的内容
+    //   if (arg === 1) {
+    //     this.ipagination.current = 1;
+    //   }
+    //   var params = this.getQueryParams(); //查询条件
+    //   getAction(this.url.list, params).then((res) => {
+    //     if (res.success) {
+    //       this.dataSource1 = res.result.records;
+    //       this.ipagination.total = res.result.total;
+    //     }
+    //   });
+    // },
+    // getQueryParams() {
+    //   var param = Object.assign({}, this.queryParam, this.isorter);
+    //   param.pageNo = this.ipagination.current;
+    //   param.pageSize = this.ipagination.pageSize;
+    //   return filterObj(param);
+    // },
+    getAvatarView: function (avatar) {
+      return getFileAccessHttpUrl(avatar);
+    },
+
+    batchFrozen: function (status) {
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return false;
+      } else {
+        let ids = "";
+        let that = this;
+        let isAdmin = false;
+        that.selectionRows.forEach(function (row) {
+          if (row.username == "admin") {
+            isAdmin = true;
+          }
+        });
+        if (isAdmin) {
+          that.$message.warning("管理员账号不允许此操作,请重新选择!");
+          return;
+        }
+        that.selectedRowKeys.forEach(function (val) {
+          ids += val + ",";
+        });
+        that.$confirm({
+          title: "确认操作",
+          content: "是否" + (status == 1 ? "解冻" : "冻结") + "选中账号?",
+          onOk: function () {
+            frozenBatch({ ids: ids, status: status }).then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.loadData();
+                that.onClearSelected();
+              } else {
+                that.$message.warning(res.message);
+              }
+            });
+          },
+        });
+      }
+    },
+    handleMenuClick(e) {
+      if (e.key == 1) {
+        this.batchDel();
+      } else if (e.key == 2) {
+        this.batchFrozen(2);
+      } else if (e.key == 3) {
+        this.batchFrozen(1);
+      }
+    },
+    handleFrozen: function (id, status, username) {
+      let that = this;
+      //TODO 后台校验管理员角色
+      if ("admin" == username) {
+        that.$message.warning("管理员账号不允许此操作!");
+        return;
+      }
+      frozenBatch({ ids: id, status: status }).then((res) => {
+        if (res.success) {
+          that.$message.success(res.message);
+          that.loadData();
+        } else {
+          that.$message.warning(res.message);
+        }
+      });
+    },
+    handleChangePassword(username) {
+      this.$refs.passwordmodal.show(username);
+    },
+    passwordModalOk() {
+      //TODO 密码修改完成 不需要刷新页面,可以把datasource中的数据更新一下
+    },
+    onSyncFinally({ isToLocal }) {
+      // 同步到本地时刷新下数据
+      if (isToLocal) {
+        this.loadData();
+      }
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 59 - 0
src/views/settings/posInfo.vue

@@ -0,0 +1,59 @@
+<template>
+  <a-card style="width: 100%; height: 100%">
+    <a-tabs default-active-key="1">
+      <a-tab-pane key="1">
+        <span slot="tab"> 桌台设置 </span>
+        <pos-table></pos-table>
+      </a-tab-pane>
+      <a-tab-pane key="2">
+        <span slot="tab"> 桌台区域设置 </span>
+        <pos-region></pos-region>
+      </a-tab-pane>
+      <a-tab-pane key="3">
+        <span slot="tab"> 桌台桌型设置 </span>
+        <pos-table-type></pos-table-type>
+      </a-tab-pane>
+      <a-tab-pane key="4">
+        <span slot="tab"> 沽清设置 </span>
+        <pos-sell-clear-goods></pos-sell-clear-goods>
+      </a-tab-pane>
+      <a-tab-pane key="5">
+        <span slot="tab"> 套餐管理 </span>
+        <pos-thali></pos-thali>
+      </a-tab-pane>
+      <a-tab-pane key="6">
+        <span slot="tab"> 餐段设置 </span>
+        <pos-meal-section></pos-meal-section>
+      </a-tab-pane>
+    </a-tabs>
+  </a-card>
+</template>
+
+<script>
+import posTable from "./components/pos/posTable.vue";
+import posRegion from "./components/pos/posRegion.vue";
+import posTableType from "./components/pos/posTableType.vue";
+import posSellClearGoods from "./components/pos/posSellClearGoods.vue";
+import posThali from "./components/pos/posThali.vue";
+import posMealSection from "./components/pos/posMealSection.vue";
+
+export default {
+  components: {
+    posTable,
+    posRegion,
+    posTableType,
+    posSellClearGoods,
+    posThali,
+    posMealSection,
+  },
+  data() {
+    return {};
+  },
+};
+</script>
+
+<style scoped>
+.main {
+  height: 70% !important;
+}
+</style>