gqx 2 gadi atpakaļ
vecāks
revīzija
a892004ebe

+ 367 - 0
src/views/pos/diandan.vue

@@ -0,0 +1,367 @@
+<template>
+  <a-card :bordered="false" class="card-pd">
+    <a-tabs v-model="tabPosTypeId" @change="tabPosTypeChange">
+      <a-tab-pane
+        :key="item.id"
+        :tab="item.name"
+        v-for="item in posTypeList"
+      ></a-tab-pane>
+    </a-tabs>
+    <div style="display: flex; height: calc(100vh - 350px)">
+      <a-card style="width: 25%">
+        <a-table
+          bordered
+          :columns="columns"
+          :data-source="selectGoodsList"
+          :pagination="false"
+          rowKey="id"
+          :scroll="{ y: 560 }"
+        >
+          <template slot="num" slot-scope="text, record, index">
+            <div>
+              <a-input-number
+                v-model="record.num"
+                :max="record.inventory"
+                @change="(event) => numChange(event, index)"
+              />
+            </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>
+        <p>数量:{{ sum }}</p>
+        <div style="display: flex; gap: 5px; flex-flow: wrap">
+          <a-button @click="handleClear" :disabled="btnDisabled">清空</a-button>
+          <!-- <a-button @click="handleAdd" :disabled="btnDisabled">备注</a-button> -->
+          <a-button :disabled="btnDisabled">退货</a-button>
+          <a-button @click="handleAdd">挂单</a-button>
+          <a-button>挂房帐</a-button>
+          <a-button type="danger" @click="handlePayment"
+            >结账¥{{ amount.toFixed(2) }}</a-button
+          >
+        </div>
+      </a-card>
+      <a-card style="width: 75%">
+        <a-tabs v-model="tabgoodsTypeId" @change="tabGoodsTypeChange">
+          <a-tab-pane key="1" tab="全部"></a-tab-pane>
+          <a-tab-pane
+            :key="item.id"
+            :tab="item.name"
+            v-for="item in goodsTypeList"
+          ></a-tab-pane>
+        </a-tabs>
+        <a-row :gutter="[5, 5]">
+          <a-col
+            v-for="item in dataSource"
+            :key="item.id"
+            :span="3"
+            @click.stop="itemClick(item)"
+          >
+            <div class="room-item check">
+              <div class="select-cell"></div>
+              <template v-if="item.id != '0'">
+                <div>{{ item.name }}</div>
+                <div style="margin-top: 10px; color: red">
+                  ¥{{ item.sellingPrice.toFixed(2) }}
+                </div>
+                <div style="margin-top: 10px">库{{ item.inventory }}</div>
+                <div
+                  v-if="item.isSellClear"
+                  style="display: flex; justify-content: right"
+                >
+                  <a-tag color="#f50"> 沽清 </a-tag>
+                </div></template
+              >
+              <template v-else>
+                <div style="font-weight: 800; text-align: center">+临时菜</div>
+              </template>
+            </div>
+          </a-col>
+        </a-row>
+      </a-card>
+    </div>
+    <payment-modal ref="modalPaymentForm" @ok="modalFormOk"></payment-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 PaymentModal from "./modules/PaymentModal.vue";
+const columns = [
+  {
+    title: "商品名称",
+    dataIndex: "name",
+  },
+  {
+    title: "数量",
+    dataIndex: "num",
+    scopedSlots: { customRender: "num" },
+  },
+  {
+    title: "售价",
+    dataIndex: "sellingPrice",
+  },
+];
+export default {
+  name: "memberList",
+  components: {
+    PaymentModal,
+  },
+  data() {
+    return {
+      columns,
+      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,
+      },
+      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: {},
+      posTypeList: [],
+      tabPosTypeId: "",
+      selectGoodsList: [],
+      goodsTypeList: [],
+      tabgoodsTypeId: "1",
+      dataSource: [],
+      oldSelectGoodsList: [],
+    };
+  },
+  computed: {
+    sum() {
+      return this.selectGoodsList.reduce(function (total, item) {
+        return total + item.num;
+      }, 0);
+    },
+    amount() {
+      return this.selectGoodsList.reduce(function (total, item) {
+        return total + item.sellingPrice * item.num;
+      }, 0);
+    },
+    btnDisabled() {
+      var res = this.selectGoodsList && this.selectGoodsList.length > 0;
+      return !res;
+    },
+  },
+  created() {
+    this.dataSource = [{ id: "0" }];
+    getAction("/pos/posType/list", { pageNo: 1, pageSize: 99 }).then((res) => {
+      if (res.success) {
+        this.posTypeList = res.result.records;
+        if (this.posTypeList && this.posTypeList.length > 0) {
+          this.tabPosTypeId = this.posTypeList[0].id;
+          this.loadGoodsType();
+        }
+      }
+    });
+  },
+  methods: {
+    modalFormOk() {},
+    numChange(e, index) {
+      console.log(e);
+      if (e <= 0) {
+        this.selectGoodsList.splice(index, 1);
+      }
+    },
+    handleClear() {
+      this.selectGoodsList = [];
+    },
+    tabPosTypeChange(e) {
+      this.loadGoodsType();
+    },
+    tabGoodsTypeChange(e) {
+      this.loadGoods();
+    },
+    loadGoodsType() {
+      getAction("/rooms/cesStockType/getTopTypesByPosType", {
+        posType: this.tabPosTypeId,
+      }).then((res2) => {
+        if (res2.success) {
+          this.goodsTypeList = res2.result;
+          if (this.goodsTypeList && this.goodsTypeList.length > 0) {
+            this.loadGoods();
+          }
+        }
+      });
+    },
+    loadGoods() {
+      var ids = [];
+      if (this.tabgoodsTypeId === "1") {
+        this.goodsTypeList.forEach((t) => {
+          ids.push(t.id);
+        });
+      } else {
+        ids.push(this.tabgoodsTypeId);
+      }
+      this.dataSource = [{ id: "0" }];
+      getAction("/pos/posSellClearGoods/list", {
+        pageNo: 1,
+        pageSize: 99999,
+        goodTypes: ids,
+      }).then((res) => {
+        if (res.success) {
+          this.dataSource = [...this.dataSource, ...res.result.records];
+        }
+      });
+    },
+    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(() => {});
+    },
+    handlePayment() {
+      this.handleAdd((e) => {
+        var amount = this.oldSelectGoodsList.reduce(function (total, item) {
+          return total + item.sellingPrice;
+        }, 0);
+        this.$refs.modalPaymentForm.edit({
+          billAmount: amount,
+          deposit: 0,
+          roomFee: amount,
+          subjectType: 5,
+          feeType: 2,
+          preferentialType: 1,
+          couponFirstAmount: 0,
+          discount: 9,
+          orderId: e,
+        });
+        this.$refs.modalPaymentForm.title = "POS结账" + e;
+        this.$refs.modalPaymentForm.disableSubmit = false;
+      });
+    },
+    handleAdd(callback) {
+      if (!this.selectGoodsList || this.selectGoodsList.length <= 0) {
+        this.$message.warning("请先选择商品");
+        return;
+      }
+      var _info = JSON.parse(localStorage.getItem("storeInfo"));
+      var model = { goodsId: this.selectGoods.id };
+      if (_info) {
+        model.hotelId = _info.id;
+      }
+      model.posType = this.tabPosTypeId;
+      var posOrderGoodsDetailList = [];
+      this.selectGoodsList.forEach((t) => {
+        posOrderGoodsDetailList.push({
+          goodsId: t.id,
+          num: t.num,
+          money: t.sellingPrice,
+        });
+      });
+      model.posOrderGoodsDetailList = posOrderGoodsDetailList;
+      postAction("/pos/posOrderGoods/add", model)
+        .then((res) => {
+          if (res.success) {
+            this.$message.success(res.message);
+            this.oldSelectGoodsList = JSON.parse(
+              JSON.stringify(this.selectGoodsList)
+            );
+            this.selectGoodsList = [];
+            this.loadGoods();
+            if (callback) {
+              callback(res.result);
+            }
+          } else {
+            this.$message.warning(res.message);
+          }
+        })
+        .finally(() => {});
+    },
+    itemClick(row) {
+      console.log(row);
+      if (row.isSellClear) {
+        this.$message.warning("选择的商品已沽清");
+        return;
+      }
+      var good = JSON.parse(JSON.stringify(row));
+      this.$set(good, "num", 1);
+      var find = this.selectGoodsList.find((t) => t.id === row.id);
+      if (find) {
+        if (find.inventory > find.num) {
+          find.num++;
+        }
+      } else {
+        this.selectGoodsList.push(good);
+      }
+    },
+  },
+};
+</script>
+  <style scoped>
+@import "~@assets/less/common.less";
+.room-item {
+  height: 110px;
+  /* line-height: 200px; */
+  font-size: 13px;
+  padding: 0px 5px;
+  border-radius: 5px;
+  cursor: pointer;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+.check {
+  border: #000 solid 3px;
+}
+.ant-table-wrapper {
+  height: calc(100vh - 500px);
+}
+/deep/ .card-pd .ant-card-body {
+  padding: 0 !important;
+}
+.select-cell {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  left: 0;
+  top: 0;
+  z-index: 10;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+</style>

+ 496 - 0
src/views/pos/modules/Payment.vue

@@ -0,0 +1,496 @@
+<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="billAmount"
+            >
+              {{ model.billAmount.toFixed(2) }}元
+              <a-switch v-model="model.coupon" />优惠
+            </a-form-model-item>
+          </a-col>
+          <template v-if="model.coupon">
+            <a-col :span="24">
+              <a-form-model-item
+                label="优惠方式"
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                prop="refund"
+              >
+                <a-radio-group v-model="model.preferentialType">
+                  <a-radio :value="1"> 抹零 </a-radio>
+                  <a-radio :value="2"> 减现 </a-radio>
+                  <a-radio :value="3"> 打折 </a-radio>
+                </a-radio-group>
+                <template v-if="model.preferentialType === 3"
+                  >打<a-input-number
+                    style="width: 50px"
+                    v-model="model.discount"
+                    :min="1"
+                    :max="9"
+                  ></a-input-number
+                  >折
+                </template>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="24" v-if="model.preferentialType == 2">
+              <a-form-model-item
+                label="优惠金额"
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                prop="couponFirstAmount"
+              >
+                <a-input-number
+                  style="width: 100px"
+                  :min="0"
+                  v-model="model.couponFirstAmount"
+                  placeholder="请输入优惠金额"
+                ></a-input-number
+                >元
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-model-item
+                label="惠后金额"
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+              >
+                {{ couponAmount.toFixed(2) }}元
+              </a-form-model-item>
+            </a-col>
+            <!-- <a-col :span="24">
+              <a-form-model-item
+                label="优惠券"
+                :labelCol="labelCol"
+                :wrapperCol="wrapperCol"
+                prop="refund"
+              >
+                <a-select
+                  v-if="model.couponCard"
+                  v-model="model.couponId"
+                  style="width: 200px"
+                  placeholder="优惠券"
+                  :allowClear="true"
+                >
+                  <a-select-option
+                    :value="couponItem.id"
+                    v-for="couponItem in memeberCouponList"
+                    :key="couponItem.id"
+                    >{{ couponItem.couponsName }}</a-select-option
+                  >
+                </a-select>
+                <a-switch v-model="model.couponCard" />使用优惠券
+              </a-form-model-item>
+            </a-col> -->
+          </template>
+          <a-col :span="24">
+            <a-form-model-item
+              label="实收金额"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              {{ realityAmount.toFixed(2) }}元
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="收款金额"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <div v-for="(item, index) in payList" :key="index">
+                <a-row type="flex" :key="index">
+                  <a-col :span="6">
+                    <a-input-number
+                      style="width: 100px"
+                      v-model="item.money"
+                      :min="0"
+                    ></a-input-number>
+                  </a-col>
+                  <a-col :span="6">
+                    <a-select
+                      v-model="item.payType"
+                      placeholder="收款方式"
+                      @change="(event) => onChange(event, item)"
+                    >
+                      <a-select-option
+                        :value="item2.id"
+                        v-for="item2 in payTypeList"
+                        :key="item2.id"
+                      >
+                        {{ item2.name }}
+                      </a-select-option>
+                    </a-select></a-col
+                  >
+                  <a-col :span="6">
+                    <a-icon
+                      v-if="index == payList.length - 1"
+                      type="plus-circle"
+                      class="dynamic-delete-button"
+                      @click="puls()" />
+                    <a-icon
+                      v-if="payList.length > 1"
+                      type="minus-circle"
+                      style="color: #f56c6c"
+                      class="dynamic-delete-button"
+                      @click="() => remove(index)"
+                  /></a-col>
+                </a-row>
+
+                <a-row type="flex" v-if="item.isVipMemmber">
+                  <a-col :span="12"> 姓名:{{ memberCard.name }} </a-col>
+                  <a-col :span="12"> 卡号:{{ memberCard.cardNo }} </a-col>
+                  <a-col :span="12">
+                    会员级别: {{ memberCard.gradeName }}</a-col
+                  >
+                  <a-col :span="12"> 余额:{{ memberCard.balance }} </a-col>
+                  <a-col :span="12"> 积分:{{ memberCard.integral }} </a-col>
+                  <!-- <a-col :span="12"> 本次扣后剩余: </a-col>
+                <a-col :span="12"> 本次新增积分: </a-col> -->
+                </a-row>
+              </div>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="实收合计"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              {{ sumAmount.toFixed(2) }}元
+            </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: "Payment",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {
+        coupon: false,
+        discount: 1,
+        couponCard: false,
+        couponType: 1,
+        couponFirstAmount: 0,
+        billAmount: 0,
+        selectedFeeIds: [],
+      },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        mobile: [
+          {
+            required: true,
+            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+            message: "请输入手机号!",
+          },
+        ],
+        cardNo: [{ required: true, message: "请输入会员卡号!" }],
+        gradeId: [{ required: true, message: "请输入等级类型!" }],
+        payType: [{ required: true, message: "请输入付款类型!" }],
+        paymentMethod: [{ required: true, message: "请输入付款方式!" }],
+        customerName: [{ required: true, message: "请输入会员姓名!" }],
+        sex: [{ required: true, message: "请输入性别!" }],
+        certificateType: [{ required: true, message: "请输入证件类型!" }],
+        validity: [{ required: true, message: "请输入有效期!" }],
+      },
+      url: {
+        add: "/business/busRoomBookingOrders/booking-to-live",
+        edit: "/business/busMemberCard/edit",
+        queryById: "/business/busMemberCard/queryById",
+      },
+      gradeList: [],
+      paymentMethodList: [],
+      staffList: [],
+      customerList: [],
+      oldcustomerList: [],
+      payTypeList: [],
+      memberCard: {},
+      isVipMemmber: false,
+      payList: [],
+      memeberCouponList: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+    sumAmount() {
+      var sum = this.payList.reduce(function (total, item) {
+        return total + item.money;
+      }, 0);
+      return sum;
+    },
+    couponAmount() {
+      var sum = 0;
+      if (this.model.coupon) {
+        if (this.model.preferentialType == 1) {
+          sum = Math.floor(this.model.billAmount);
+        } else if (this.model.preferentialType == 2) {
+          sum = this.model.billAmount - (this.model.couponFirstAmount || 0);
+        } else if (this.model.preferentialType == 3) {
+          sum = parseFloat(
+            ((this.model.billAmount * this.model.discount) / 10).toFixed(2)
+          );
+        }
+      } else {
+        sum = this.model.billAmount;
+      }
+      return sum;
+    },
+    realityAmount() {
+      if (this.model.couponCard) {
+        var find = this.memeberCouponList.find(
+          (t) => t.id == this.model.couponId
+        );
+        if (find) {
+          return this.couponAmount - find.cost;
+        }
+      }
+      return this.couponAmount;
+    },
+  },
+  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("/business/busRoomPayType/list", {
+      pageSize: 99999,
+      pageNo: 1,
+    }).then((res) => {
+      if (res.success) {
+        this.payTypeList = res.result.records;
+      }
+    });
+    getAction("/business/busMemberCard/list", {
+      id: "11111111",
+    }).then((res) => {
+      if (res.success) {
+        if (res.result.records && res.result.records.length > 0) {
+          this.memberCard = res.result.records[0];
+        }
+      }
+    });
+  },
+  methods: {
+    getbusRoomPayType() {
+      getAction("/business/busRoomPayType/list", {
+        pageSize: 99999,
+        pageNo: 1,
+      }).then((res) => {
+        if (res.success) {
+          this.payTypeList = res.result.records;
+          if (this.payTypeList && this.payTypeList.length > 0) {
+            this.$set(this.model, "payType", this.payTypeList[0].id);
+
+            this.payList = [
+              {
+                money: this.realityAmount,
+                payType: this.payTypeList[0].id,
+                isVipMemmber: false,
+              },
+            ];
+          }
+        }
+      });
+    },
+    puls() {
+      this.payList.push({
+        money: 0,
+        payType: this.payTypeList[0].id,
+        isVipMemmber: false,
+      });
+    },
+    remove(index) {
+      this.payList.splice(index, 1);
+    },
+    onChange(e, value) {
+      console.log("value", value);
+      console.log("e", e);
+      var find = this.payTypeList.find((t) => t.id == value.payType);
+      value.isVipMemmber = find && find.name == "会员卡";
+    },
+    handleSearch(value) {
+      let result;
+      if (!value) {
+        result = this.oldcustomerList;
+      } else {
+        result = this.oldcustomerList.filter((t) => t.name.includes(value));
+      }
+      this.customerList = result;
+    },
+    handleSelectMember(e) {
+      var find = this.customerList.find((t) => t.id === e);
+      this.model.phone = find.phone;
+      this.model.customerName = find.name;
+      this.model.customerId = find.id;
+    },
+    getMemeberCouponList() {
+      getAction("/business/busMarketCouponsCashUsed/memeberCouponList", {
+        pageNo: 1,
+        pageSize: 99,
+        conditions: 900,
+        mobile: this.model.vipCustomerId,
+      }).then((res) => {
+        if (res.success) {
+          this.memeberCouponList = res.result.records;
+        }
+      });
+    },
+    add(livingOrderId, roomId) {
+      this.modelDefault.livingOrderId = livingOrderId;
+      this.modelDefault.roomId = roomId;
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      this.getbusRoomPayType();
+      if (this.model.vipCustomerId) {
+        this.getMemeberCouponList();
+      }
+      this.visible = true;
+    },
+    submitForm() {
+      const that = this;
+      // 触发表单验证
+      this.$refs.form.validate((valid) => {
+        if (valid) {
+          console.log("this.realityAmount ", this.realityAmount);
+          console.log("this.sumAmount ", this.sumAmount);
+          if (this.realityAmount != this.sumAmount) {
+            that.$message.warning("实收金额和实收合计必须相等");
+            return;
+          }
+          var obj = {};
+          var fees = [];
+          if (this.model.coupon) {
+            fees.push({
+              feeType: this.model.feeType,
+              preferentialType: this.model.preferentialType,
+              money: this.couponAmount.toFixed(2),
+              custorerOrderRemark: "优惠金额",
+              isPreferential: true,
+            });
+          }
+          if (this.model.couponCard && this.model.couponId) {
+            var find = this.memeberCouponList.find(
+              (t) => t.id == this.model.couponId
+            );
+            if (find) {
+              fees.push({
+                feeType: this.model.feeType,
+                money: find.cost.toFixed(2),
+                custorerOrderRemark: "优惠券",
+                isPreferential: true,
+              });
+            }
+          }
+          this.payList.forEach((item) => {
+            fees.push({
+              feeType: this.model.feeType,
+              money: item.money.toFixed(2),
+              payType: item.payType,
+              custorerOrderRemark: "结账退房",
+              isPreferential: false,
+            });
+          });
+
+          that.confirmLoading = true;
+          var url =
+            "/business/busRoomBookingOrders/settle-checkout?bookingOrderId=" +
+            this.model.bookingOrderId;
+          if (this.model.livingOrderId) {
+            url =
+              "/business/busRoomBookingOrders/living-settle-checkout?livingOrderId=" +
+              this.model.livingOrderId;
+          }
+          if (
+            this.model.selectedFeeIds &&
+            this.model.selectedFeeIds.length > 0
+          ) {
+            url = "/business/busRoomBookingOrders/partial-settle";
+            obj = {
+              fees: fees,
+              livingOrderId: this.model.livingOrderId,
+              selectedFeeIds: this.model.selectedFeeIds,
+            };
+          }
+          httpAction(
+            url,
+            this.model.selectedFeeIds && this.model.selectedFeeIds.length > 0
+              ? obj
+              : fees,
+            "post"
+          )
+            .then((res) => {
+              if (res.success) {
+                that.$message.success("结账成功");
+                that.$emit("ok");
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>
+<style scoped>
+.dynamic-delete-button {
+  cursor: pointer;
+  position: relative;
+  /* top: 4px; */
+  margin-left: 5px;
+  font-size: 18px;
+  color: #1890ff;
+  transition: all 0.3s;
+}
+.dynamic-delete-button:hover {
+  color: #777;
+}
+.dynamic-delete-button[disabled] {
+  cursor: not-allowed;
+  opacity: 0.5;
+}
+</style>

+ 60 - 0
src/views/pos/modules/PaymentModal.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="关闭">
+    <payment ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></payment>
+  </j-modal>
+</template>
+
+<script>
+
+  import payment from './Payment'
+  export default {
+    name: 'PaymentModal',
+    components: {
+      payment
+    },
+    data () {
+      return {
+        title:'',
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add(record);
+        })
+      },
+      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>

+ 147 - 0
src/views/pos/modules/PosTypeForm.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="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-radio-group v-model="model.state">
+                <a-radio :value="1"> 启用 </a-radio>
+                <a-radio :value="0"> 停用 </a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="线上预定"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="online"
+            >
+              <a-radio-group v-model="model.online">
+                <a-radio :value="1"> 启用 </a-radio>
+                <a-radio :value="0"> 停用 </a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+export default {
+  name: "PosTypeForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: { state: 1, online: 0 },
+      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() {
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份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/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>

+ 60 - 0
src/views/pos/posInfo.vue

@@ -0,0 +1,60 @@
+<template>
+  <a-card style="width: 100%; height: 100%">
+    <a-tabs default-active-key="1">
+      <a-tab-pane key="1">
+        <span slot="tab"> 点单 </span>
+        <diandan></diandan>
+      </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"> pos类型管理 </span>
+        <pos-type></pos-type>
+      </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>
+      </a-tab-pane>
+    </a-tabs>
+  </a-card>
+</template>
+
+<script>
+import diandan from "./diandan.vue";
+import posType from "./posType.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: {
+    diandan,
+    posType,
+    // posRegion,
+    // posTableType,
+    // posSellClearGoods,
+    // posThali,
+    // posMealSection,
+  },
+  data() {
+    return {};
+  },
+};
+</script>
+
+<style scoped>
+.main {
+  height: 70% !important;
+}
+</style>

+ 299 - 0
src/views/pos/posType.vue

@@ -0,0 +1,299 @@
+<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="pos名称"
+                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-type-modal ref="modalForm" @ok="modalFormOk"></pos-type-modal>
+  </a-card>
+</template>
+  
+  <script>
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import PosTypeModal from "./modules/PosTypeModal";
+import { filterObj } from "@/utils/util";
+import { getAction } from "@/api/manage";
+export default {
+  name: "memberList",
+  mixins: [JeecgListMixin],
+  components: {
+    PosTypeModal,
+  },
+  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: "state",
+          customRender(text) {
+            return text === 1 ? "启用" : "停用";
+          },
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/pos/posType/list",
+        delete: "/pos/posType/delete",
+        deleteBatch: "/pos/posType/deleteBatch",
+        exportXlsUrl: "/pos/posType/exportXls",
+        importExcelUrl: "pos/posType/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>

+ 0 - 1
src/views/room/modules/checkIn/BillRoomInfo.vue

@@ -427,7 +427,6 @@ import CustomerModal from "./CustomerModal.vue";
 import RefundModal from "./RefundModal.vue";
 import PaymentModal from "./PaymentModal.vue";
 import { match } from "assert";
-import { postAction } from "../../../../api/manage";
 const columns = [
   // {
   //     title: "",