Parcourir la source

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

DESKTOP-B78GIPM\admin il y a 2 ans
Parent
commit
f6923debe4
69 fichiers modifiés avec 9577 ajouts et 216 suppressions
  1. 20 20
      package.json
  2. 12 1
      src/api/roomBuildingApi.js
  3. 7 0
      src/utils/excloudHotelIdParamPath/MemeberController.js
  4. 2 1
      src/utils/excloudHotelIdParamPath/index.js
  5. 6 4
      src/views/markets/coupons.vue
  6. 352 0
      src/views/markets/couponscash.vue
  7. 36 5
      src/views/markets/marketInfo.vue
  8. 328 0
      src/views/markets/mealcoupons.vue
  9. 254 0
      src/views/markets/mealcouponsverify.vue
  10. 254 0
      src/views/markets/meetingroom.vue
  11. 659 0
      src/views/markets/meetingroomschedule.vue
  12. 751 0
      src/views/markets/member.vue
  13. 365 0
      src/views/markets/memberrecharge.vue
  14. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsForm.vue
  15. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsModal.Style#Drawer.vue
  16. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsModal.vue
  17. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsUsedForm.vue
  18. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsUsedGenerateForm.vue
  19. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsUsedGenerateFormModal.vue
  20. 2 3
      src/views/markets/modules/BusMarketCouponsUsedList.vue
  21. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsUsedListModal.vue
  22. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsUsedModal.Style#Drawer.vue
  23. 0 0
      src/views/markets/modules/coupons/BusMarketCouponsUsedModal.vue
  24. 286 0
      src/views/markets/modules/couponsCash/BusMarketCouponsCashForm.vue
  25. 60 0
      src/views/markets/modules/couponsCash/BusMarketCouponsCashModal.vue
  26. 145 0
      src/views/markets/modules/couponsCash/BusMarketCouponsCashUsedGenerateForm.vue
  27. 60 0
      src/views/markets/modules/couponsCash/BusMarketCouponsCashUsedGenerateFormModal.vue
  28. 61 25
      src/views/markets/modules/Provide/UserList.vue
  29. 64 0
      src/views/markets/modules/couponsCash/BusMarketCouponsCashUsedListModal.vue
  30. 352 0
      src/views/markets/modules/couponsProvide/BusMemberCardList.vue
  31. 10 5
      src/views/markets/modules/Provide/MobileForm.vue
  32. 23 16
      src/views/markets/modules/Provide/index.vue
  33. 212 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsForm.vue
  34. 145 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsGenerateForm.vue
  35. 60 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsGenerateFormModal.vue
  36. 84 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsModal.Style#Drawer.vue
  37. 60 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsModal.vue
  38. 352 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedList.vue
  39. 64 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedListModal.vue
  40. 276 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedVerify.vue
  41. 71 0
      src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedVerifyModal.vue
  42. 181 0
      src/views/markets/modules/meetingRoom/BusMeetingRoomForm.vue
  43. 84 0
      src/views/markets/modules/meetingRoom/BusMeetingRoomModal.Style#Drawer.vue
  44. 60 0
      src/views/markets/modules/meetingRoom/BusMeetingRoomModal.vue
  45. 400 0
      src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleConfirm.vue
  46. 66 0
      src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleConfirmModal.vue
  47. 227 0
      src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleEditForm.vue
  48. 60 0
      src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleEditModal.vue
  49. 324 0
      src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleForm.vue
  50. 60 0
      src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleModal.vue
  51. 310 0
      src/views/markets/modules/meetingRoomSchedule/meetingRoomScheduleDetail/meetingRoomScheduleDetailList.vue
  52. 66 0
      src/views/markets/modules/meetingRoomSchedule/meetingRoomScheduleDetail/meetingRoomScheduleDetailModal.vue
  53. 316 0
      src/views/markets/modules/memberBalance/BusMemberBalanceLogForm.vue
  54. 84 0
      src/views/markets/modules/memberBalance/BusMemberBalanceLogModal.Style#Drawer.vue
  55. 60 0
      src/views/markets/modules/memberBalance/BusMemberBalanceLogModal.vue
  56. 286 0
      src/views/markets/modules/memberCard/BusMemberCardForm.vue
  57. 84 0
      src/views/markets/modules/memberCard/BusMemberCardModal.Style#Drawer.vue
  58. 60 0
      src/views/markets/modules/memberCard/BusMemberCardModal.vue
  59. 170 0
      src/views/markets/modules/memberPoint/BusMemberPointLogForm.vue
  60. 84 0
      src/views/markets/modules/memberPoint/BusMemberPointLogModal.Style#Drawer.vue
  61. 60 0
      src/views/markets/modules/memberPoint/BusMemberPointLogModal.vue
  62. 208 0
      src/views/settings/components/modules/printTemplateForm.vue
  63. 84 0
      src/views/settings/components/modules/printTemplateModal.Style#Drawer.vue
  64. 60 0
      src/views/settings/components/modules/printTemplateModal.vue
  65. 203 4
      src/views/settings/components/printTemplate.vue
  66. 537 124
      src/views/settings/components/roomModules/roomGen.vue
  67. 6 6
      src/views/settings/components/roomModules/roomNumSettings/roomNumList.vue
  68. 3 1
      src/views/settings/components/roomModules/roomNumSettings/roomNumTable.vue
  69. 1 1
      vue.config.js

+ 20 - 20
package.json

@@ -10,42 +10,42 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@antv/data-set": "^0.11.4",
     "@jeecg/antd-online-mini": "3.4.3-beta2",
+    "@tinymce/tinymce-vue": "2.1.0",
+    "@toast-ui/editor": "^2.1.2",
     "ant-design-vue": "^1.7.2",
-    "@antv/data-set": "^0.11.4",
-    "viser-vue": "^2.4.8",
     "axios": "^0.18.0",
+    "china-area-data": "^5.0.1",
+    "clipboard": "^2.0.4",
+    "codemirror": "^5.46.0",
+    "cron-parser": "^2.10.0",
     "dayjs": "^1.8.0",
+    "dom-align": "1.12.0",
     "enquire.js": "^2.1.6",
     "js-cookie": "^2.2.0",
     "lodash.get": "^4.4.2",
     "lodash.pick": "^4.4.0",
     "md5": "^2.2.1",
     "nprogress": "^0.2.0",
+    "qiankun": "^2.5.1",
+    "tinymce": "5.4.1",
+    "viser-vue": "^2.4.8",
     "vue": "^2.6.10",
+    "vue-area-linkage": "^5.1.0",
     "vue-cropper": "^0.5.4",
     "vue-i18n": "^8.7.0",
     "vue-loader": "^15.7.0",
     "vue-ls": "^3.2.0",
-    "vue-router": "^3.0.1",
-    "vuex": "^3.1.0",
-    "vue-print-nb-jeecg": "^1.0.10",
-    "clipboard": "^2.0.4",
     "vue-photo-preview": "^1.1.3",
+    "vue-print-nb-jeecg": "^1.0.10",
+    "vue-router": "^3.0.1",
     "vue-splitpane": "^1.0.4",
-    "vuedraggable": "^2.20.0",
-    "codemirror": "^5.46.0",
-    "@tinymce/tinymce-vue": "2.1.0",
-    "tinymce": "5.4.1",
-    "@toast-ui/editor": "^2.1.2",
-    "vue-area-linkage": "^5.1.0",
-    "china-area-data": "^5.0.1",
-    "dom-align": "1.12.0",
-    "xe-utils": "2.4.8",
+    "vuedraggable": "^2.24.3",
+    "vuex": "^3.1.0",
     "vxe-table": "2.9.13",
     "vxe-table-plugin-antd": "1.8.10",
-    "cron-parser": "^2.10.0",
-    "qiankun": "^2.5.1",
+    "xe-utils": "2.4.8",
     "xss": "^1.0.13"
   },
   "devDependencies": {
@@ -55,13 +55,13 @@
     "@vue/cli-service": "^3.3.0",
     "@vue/eslint-config-standard": "^4.0.0",
     "babel-eslint": "7.2.3",
+    "compression-webpack-plugin": "^3.1.0",
     "eslint": "^5.16.0",
     "eslint-plugin-vue": "^5.1.0",
+    "html-webpack-plugin": "^4.2.0",
     "less": "^3.9.0",
     "less-loader": "^4.1.0",
-    "vue-template-compiler": "^2.6.10",
-    "html-webpack-plugin": "^4.2.0",
-    "compression-webpack-plugin": "^3.1.0"
+    "vue-template-compiler": "^2.6.10"
   },
   "eslintConfig": {
     "root": false,

+ 12 - 1
src/api/roomBuildingApi.js

@@ -52,4 +52,15 @@ export function buildingTree (param) {
         params: param
     })
 }
-
+/**
+ * 批量添加房间
+ * @param {Object} param 
+ * @returns 
+ */
+export function saveBatch(param) { 
+    return axios({
+        url: '/rooms/cesRooms/saveBatchRoom',
+        method: 'post',
+        data: param
+    })
+ }

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

@@ -0,0 +1,7 @@
+export default {
+    name: '会员管理模块',
+    excloudUrls: [
+        '/business/busMemberCard/list',
+        '/business/busMemberBalanceLog/list'
+    ]
+}

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

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

+ 6 - 4
src/views/markets/coupons.vue

@@ -46,7 +46,7 @@
 
     <!-- 操作按钮区域 -->
     <div class="table-operator">
-      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button @click="handleAdd" type="danger" icon="plus">新增</a-button>
       <!-- <a-button type="primary" icon="download" @click="handleExportXls('bus_market_coupons_info')">导出</a-button>
       <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
         <a-button type="primary" icon="import">导入</a-button>
@@ -151,9 +151,9 @@
 import "@/assets/less/TableExpand.less";
 import { mixinDevice } from "@/utils/mixin";
 import { JeecgListMixin } from "@/mixins/JeecgListMixin";
-import BusMarketCouponsModal from "./modules/BusMarketCouponsModal";
-import BusMarketCouponsUsedListModal from "./modules/BusMarketCouponsUsedListModal";
-import ProvideIndexModal from "./modules/Provide/index";
+import BusMarketCouponsModal from "./modules/coupons/BusMarketCouponsModal";
+import BusMarketCouponsUsedListModal from "./modules/coupons/BusMarketCouponsUsedListModal";
+import ProvideIndexModal from "./modules/couponsProvide/index";
 import { deleteAction } from "@/api/manage";
 export default {
   name: "coupons",
@@ -299,12 +299,14 @@ export default {
       this.couponsId = item.id;
       this.$refs.modalProvideIndexModal.visible = true;
       this.$refs.modalProvideIndexModal.title = "发放";
+      this.$refs.modalProvideIndexModal.disableSubmit = true;
     },
     handleConfig(item) {
       this.couponsId = item.id;
       // this.$refs.modalCouponsUsedListModal.eventId = item.id;
       this.$refs.modalCouponsUsedListModal.visible = true;
       this.$refs.modalCouponsUsedListModal.title = "详情";
+      this.$refs.modalCouponsUsedListModal.disableSubmit = true;
       this.$refs.modalCouponsUsedListModal.add(item.id);
     },
     searchReset() {

+ 352 - 0
src/views/markets/couponscash.vue

@@ -0,0 +1,352 @@
+<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="4">
+            <a-form-item label="">
+              <a-input
+                placeholder="优惠券名称"
+                v-model="queryParam.name"
+              ></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <a-range-picker
+                format="YYYY-MM-DD"
+                :placeholder="['开始日期', '结束日期']"
+                @change="onChange"
+                v-model="datetime"
+              />
+            </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="danger" icon="plus">新增</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('bus_market_coupons_info')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown> -->
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <!-- <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div> -->
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text, record">
+          <span v-if="!text" style="font-size: 12px; font-style: italic"
+            >无图片</span
+          >
+          <img
+            v-else
+            :src="getImgView(text)"
+            :preview="record.id"
+            height="25px"
+            alt=""
+            style="max-width: 80px; font-size: 12px; font-style: italic"
+          />
+        </template>
+        <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="handleConfig(record)">详情</a>
+          <a-divider type="vertical" />
+          <a @click="handleProvide(record)">发放</a>
+          <a-divider type="vertical" />
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a @click="handleDelete(record.id)">删除</a>
+        </span>
+      </a-table>
+    </div>
+
+    <bus-market-coupons-cash-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-market-coupons-cash-modal>
+    <bus-market-coupons-cash-used-list-modal
+      ref="modalCouponsCashUsedListModal"
+      :couponsId="couponsId"
+    ></bus-market-coupons-cash-used-list-modal>
+
+    <provide-index-modal
+      ref="modalProvideIndexModal"
+      :couponsId="couponsId"
+      :couponsType="2"
+      @ok="modalFormOk"
+    ></provide-index-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import BusMarketCouponsCashModal from "./modules/couponsCash/BusMarketCouponsCashModal";
+import BusMarketCouponsCashUsedListModal from "./modules/couponsCash/BusMarketCouponsCashUsedListModal";
+import ProvideIndexModal from "./modules/couponsProvide/index";
+import { deleteAction } from "@/api/manage";
+export default {
+  name: "coupons",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMarketCouponsCashModal,
+    BusMarketCouponsCashUsedListModal,
+    ProvideIndexModal,
+  },
+  data() {
+    return {
+      couponsId: "",
+      datetime: [],
+      queryParam: {},
+      description: "bus_market_coupons_info管理页面",
+      // 表头
+      columns: [
+        // {
+        //   title: "#",
+        //   dataIndex: "",
+        //   key: "rowIndex",
+        //   width: 60,
+        //   align: "center",
+        //   customRender: function (t, r, index) {
+        //     return parseInt(index) + 1;
+        //   },
+        // },
+        // {
+        //   title: "关联租户",
+        //   align: "center",
+        //   dataIndex: "tenantId",
+        // },
+        {
+          title: "商家",
+          align: "center",
+          dataIndex: "hotelName",
+        },
+        {
+          title: "名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "开始时间",
+          align: "center",
+          dataIndex: "startTime",
+          customRender: function (text) {
+            return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
+          },
+        },
+        {
+          title: "结束时间",
+          align: "center",
+          dataIndex: "endTime",
+          customRender: function (text) {
+            return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
+          },
+        },
+        {
+          title: "优惠条件",
+          align: "center",
+          dataIndex: "type",
+          customRender: function (text, record) {
+            return text == 1 ? "无限制" : "满" + record.conditions + "可使用";
+          },
+        },
+        {
+          title: "生成数量",
+          align: "center",
+          dataIndex: "count",
+        },
+        {
+          title: "待领取",
+          align: "center",
+          dataIndex: "notClaimed",
+        },
+        {
+          title: "已领取",
+          align: "center",
+          dataIndex: "received",
+        },
+        {
+          title: "已使用",
+          align: "center",
+          dataIndex: "used",
+        },
+        {
+          title: "已作废",
+          align: "center",
+          dataIndex: "voided",
+        },
+        {
+          title: "每人可领取张数",
+          align: "center",
+          dataIndex: "klqzs",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/business/busMarketCouponsCash/list",
+        delete: "/business/busMarketCouponsCash/delete",
+        deleteBatch: "/business/busMarketCouponsCash/deleteBatch",
+        exportXlsUrl: "/business/busMarketCouponsCash/exportXls",
+        importExcelUrl: "business/busMarketCouponsCash/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    };
+  },
+  created() {
+    // this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    handleDelete: function (id) {
+      if (!this.url.delete) {
+        this.$message.error("请设置url.delete属性!");
+        return;
+      }
+      var that = this;
+      this.$confirm({
+        title: "确认删除",
+        content: "是否删除?",
+        onOk: function () {
+          deleteAction(that.url.delete, { id: id }).then((res) => {
+            if (res.success) {
+              //重新计算分页问题
+              that.reCalculatePage(1);
+              that.$message.success(res.message);
+              that.loadData();
+            } else {
+              that.$message.warning(res.message);
+            }
+          });
+        },
+        onCancel: function () {},
+      });
+    },
+    handleProvide(item) {
+      this.couponsId = item.id;
+      this.$refs.modalProvideIndexModal.visible = true;
+      this.$refs.modalProvideIndexModal.title = "发放";
+      this.$refs.modalProvideIndexModal.disableSubmit = true;
+    },
+    handleConfig(item) {
+      this.couponsId = item.id;
+      this.$refs.modalCouponsCashUsedListModal.visible = true;
+      this.$refs.modalCouponsCashUsedListModal.title = "详情";
+      this.$refs.modalCouponsCashUsedListModal.disableSubmit = true;
+      this.$refs.modalCouponsCashUsedListModal.add(item.id);
+    },
+    searchReset() {
+      this.datetime = [];
+      this.queryParam = {};
+      this.loadData(1);
+    },
+    onChange(e, dateString) {
+      // console.log("Selected Time: ", e);
+      // console.log("Formatted Selected Time: ", dateString);
+      this.queryParam.startTime = dateString[0];
+      this.queryParam.endTime = dateString[1];
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({ type: "string", value: "tenantId", text: "关联租户" });
+      fieldList.push({ type: "string", value: "hotelId", text: "关联酒店" });
+      fieldList.push({ type: "string", value: "name", text: "名称" });
+      fieldList.push({ type: "date", value: "startTime", text: "开始时间" });
+      fieldList.push({ type: "date", value: "endTime", text: "结束时间" });
+      fieldList.push({ type: "string", value: "tenantId", text: "适用房型" });
+      fieldList.push({ type: "int", value: "klqzs", text: "可领取张数" });
+      fieldList.push({ type: "string", value: "type", text: "类型" });
+      fieldList.push({ type: "string", value: "introduce", text: "说明" });
+      fieldList.push({ type: "int", value: "lqNum", text: "领取数量" });
+      fieldList.push({ type: "string", value: "ruleDec", text: "使用说明" });
+      this.superFieldList = fieldList;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 36 - 5
src/views/markets/marketInfo.vue

@@ -3,14 +3,14 @@
     <p>会员分组设置</p>
     <a-divider />
     <div class="space-align-container">
-      <div class="height-100" @click="toPage()">
+      <div class="height-100" @click="toPage('/tenant/marketinfo/member')">
         <img
           src="http://oss.qlan99.com/20200529/733024169836404bb2db66450167dd06.png"
         />
         <p>会员列表</p>
       </div>
 
-      <div class="height-100" @click="toPage()">
+      <div class="height-100" @click="toPage('/tenant/marketinfo/memberrecharge')">
         <img
           src="http://oss.qlan99.com/20200529/4446ad625b404d64ac67494266d2452b.png"
           width="50"
@@ -33,18 +33,24 @@
         />
         <p>协议单位</p>
       </div>
-      <div class="height-100" @click="toPage()">
+      <div class="height-100" @click="toPage('/tenant/marketinfo/mealcouponsverify')">
         <img
           src="http://oss.qlan99.com/20200529/7a270d9a3a534034ac03c2fdd23139ab.png"
         />
         <p>餐券核销</p>
       </div>
-      <div class="height-100" @click="toPage()">
+      <div class="height-100" @click="toPage('/tenant/marketinfo/couponscash')">
         <img
           src="http://oss.qlan99.com/20200529/7a270d9a3a534034ac03c2fdd23139ab.png"
         />
         <p>优惠券</p>
       </div>
+      <div class="height-100" @click="toPage('/tenant/marketinfo/mealcoupons')">
+        <img
+          src="http://oss.qlan99.com/20200529/7a270d9a3a534034ac03c2fdd23139ab.png"
+        />
+        <p>餐券</p>
+      </div>
       <div class="height-100" @click="toPage('/tenant/marketinfo/coupons')">
         <img
           src="http://oss.qlan99.com/20200529/7a270d9a3a534034ac03c2fdd23139ab.png"
@@ -53,6 +59,31 @@
         <p>免房券</p>
       </div>
     </div>
+    <p>会议管理</p>
+    <a-divider />
+    <div class="space-align-container">
+      <div class="height-100" @click="toPage('/tenant/marketinfo/meetingroomschedule')">
+        <img
+          src="http://oss.qlan99.com/20210204/1aef78a036e84fd18caebc0de5175281.png"
+        />
+        <p>会议室管理</p>
+      </div>
+
+      <div class="height-100" @click="toPage('/tenant/marketinfo/meetingroom')">
+        <img
+          src="http://oss.qlan99.com/20210204/70ad866bfd9a431b9bec3e8e2234ee39.png"
+          width="50"
+        />
+        <p>会议室设置</p>
+      </div>
+      <div class="height-100" @click="toPage()">
+        <img
+          src="http://oss.qlan99.com/20210204/528927c30c854370a28085a02774b951.png"
+          width="50"
+        />
+        <p>会议室订单管理</p>
+      </div>
+    </div>
     <!-- <p>会员分组设置</p>
     <a-divider />
     <a-space>
@@ -81,7 +112,7 @@ export default {
   methods: {
     toPage(url) {
       if(!url){
-        this.$message.warning('开发中,请先体验免房券');
+        this.$message.warning('开发中,请先体验其他');
         return
       }
       this.$router.push(url);

+ 328 - 0
src/views/markets/mealcoupons.vue

@@ -0,0 +1,328 @@
+<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="4">
+            <a-form-item label="">
+              <a-input
+                placeholder="餐券名称"
+                v-model="queryParam.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 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="danger" icon="plus">新增</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('bus_market_coupons_info')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown> -->
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <!-- <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div> -->
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text, record">
+          <span v-if="!text" style="font-size: 12px; font-style: italic"
+            >无图片</span
+          >
+          <img
+            v-else
+            :src="getImgView(text)"
+            :preview="record.id"
+            height="25px"
+            alt=""
+            style="max-width: 80px; font-size: 12px; font-style: italic"
+          />
+        </template>
+        <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="handleConfig(record)">详情</a>
+          <a-divider type="vertical" />
+          <!-- <a @click="handleProvide(record)">发放</a>
+          <a-divider type="vertical" /> -->
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a @click="handleDelete(record.id)">删除</a>
+        </span>
+      </a-table>
+    </div>
+
+    <bus-market-meal-coupons-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-market-meal-coupons-modal>
+    <bus-market-meal-coupons-used-list-modal
+      ref="modalMealCouponsUsedListModal"
+      :couponsId="couponsId"
+    ></bus-market-meal-coupons-used-list-modal>
+
+    <provide-index-modal
+      ref="modalProvideIndexModal"
+      :couponsId="couponsId"
+      :couponsType="2"
+      @ok="modalFormOk"
+    ></provide-index-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import BusMarketMealCouponsModal from "./modules/mealCoupons/BusMarketMealCouponsModal";
+import BusMarketMealCouponsUsedListModal from "./modules/mealCoupons/BusMarketMealCouponsUsedListModal";
+import ProvideIndexModal from "./modules/couponsProvide/index";
+import { deleteAction } from "@/api/manage";
+export default {
+  name: "coupons",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMarketMealCouponsModal,
+    BusMarketMealCouponsUsedListModal,
+    ProvideIndexModal,
+  },
+  data() {
+    return {
+      couponsId: "",
+      datetime: [],
+      queryParam: {},
+      description: "bus_market_coupons_info管理页面",
+      // 表头
+      columns: [
+        // {
+        //   title: "#",
+        //   dataIndex: "",
+        //   key: "rowIndex",
+        //   width: 60,
+        //   align: "center",
+        //   customRender: function (t, r, index) {
+        //     return parseInt(index) + 1;
+        //   },
+        // },
+        // {
+        //   title: "关联租户",
+        //   align: "center",
+        //   dataIndex: "tenantId",
+        // },
+        {
+          title: "商家",
+          align: "center",
+          dataIndex: "hotelName",
+        },
+        {
+          title: "名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "餐券类型",
+          align: "center",
+          dataIndex: "typeName",
+        },
+        {
+          title: "金额",
+          align: "center",
+          dataIndex: "cost",
+        },
+        {
+          title: "已生成",
+          align: "center",
+          dataIndex: "count",
+        },
+        {
+          title: "待发放",
+          align: "center",
+          dataIndex: "notClaimed",
+        },
+        {
+          title: "未核销",
+          align: "center",
+          dataIndex: "received",
+        },
+        {
+          title: "已核销",
+          align: "center",
+          dataIndex: "used",
+        },
+        {
+          title: "已作废",
+          align: "center",
+          dataIndex: "voided",
+        },
+        {
+          title: "说明",
+          align: "center",
+          dataIndex: "introduce",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/business/busMarketMealCoupons/list",
+        delete: "/business/busMarketMealCoupons/delete",
+        deleteBatch: "/business/busMarketMealCoupons/deleteBatch",
+        exportXlsUrl: "/business/busMarketMealCoupons/exportXls",
+        importExcelUrl: "business/busMarketMealCoupons/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    };
+  },
+  created() {
+    // this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    handleDelete: function (id) {
+      if (!this.url.delete) {
+        this.$message.error("请设置url.delete属性!");
+        return;
+      }
+      var that = this;
+      this.$confirm({
+        title: "确认删除",
+        content: "是否删除?",
+        onOk: function () {
+          deleteAction(that.url.delete, { id: id }).then((res) => {
+            if (res.success) {
+              //重新计算分页问题
+              that.reCalculatePage(1);
+              that.$message.success(res.message);
+              that.loadData();
+            } else {
+              that.$message.warning(res.message);
+            }
+          });
+        },
+        onCancel: function () {},
+      });
+    },
+    handleProvide(item) {
+      this.couponsId = item.id;
+      this.$refs.modalProvideIndexModal.visible = true;
+      this.$refs.modalProvideIndexModal.title = "发放";
+      this.$refs.modalProvideIndexModal.disableSubmit = true;
+    },
+    handleConfig(item) {
+      this.couponsId = item.id;
+      this.$refs.modalMealCouponsUsedListModal.visible = true;
+      this.$refs.modalMealCouponsUsedListModal.title = "详情";
+      this.$refs.modalMealCouponsUsedListModal.disableSubmit = true;
+      this.$refs.modalMealCouponsUsedListModal.add(item.id);
+    },
+    searchReset() {
+      this.datetime = [];
+      this.queryParam = {};
+      this.loadData(1);
+    },
+    onChange(e, dateString) {
+      // console.log("Selected Time: ", e);
+      // console.log("Formatted Selected Time: ", dateString);
+      this.queryParam.startTime = dateString[0];
+      this.queryParam.endTime = dateString[1];
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({ type: "string", value: "tenantId", text: "关联租户" });
+      fieldList.push({ type: "string", value: "hotelId", text: "关联酒店" });
+      fieldList.push({ type: "string", value: "name", text: "名称" });
+      fieldList.push({ type: "date", value: "startTime", text: "开始时间" });
+      fieldList.push({ type: "date", value: "endTime", text: "结束时间" });
+      fieldList.push({ type: "string", value: "tenantId", text: "适用房型" });
+      fieldList.push({ type: "int", value: "klqzs", text: "可领取张数" });
+      fieldList.push({ type: "string", value: "type", text: "类型" });
+      fieldList.push({ type: "string", value: "introduce", text: "说明" });
+      fieldList.push({ type: "int", value: "lqNum", text: "领取数量" });
+      fieldList.push({ type: "string", value: "ruleDec", text: "使用说明" });
+      this.superFieldList = fieldList;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 254 - 0
src/views/markets/mealcouponsverify.vue

@@ -0,0 +1,254 @@
+<template>
+  <a-card style="width: 100%; height: 100%">
+    <a-tabs type="card" default-active-key="0" @tabClick="tabClick">
+      <a-tab-pane key="">
+        <span slot="tab"> 全部 </span>
+        <!-- <member-list></member-list> -->
+      </a-tab-pane>
+      <a-tab-pane v-for="(item, index) in mealCouponTypeList" :key="item.value">
+        <span slot="tab">
+          {{ item.label }}
+        </span>
+        <!-- <market-recharge-list></market-recharge-list> -->
+      </a-tab-pane>
+    </a-tabs>
+    <div style="position: absolute; right: 50px; bottom: 120px; z-index: 99999">
+      <a-button
+        type="danger"
+        shape="circle"
+        icon="plus"
+        size="large"
+        @click="handleAdd"
+      />
+    </div>
+    <a-row type="flex">
+      <a-col :span="6" :order="1">
+        <div class="height-100">
+          <p class="header_num">{{ stat.dayCount || 0 }}</p>
+          <span class="header_name">今日总数</span>
+        </div>
+      </a-col>
+      <a-col :span="6" :order="2">
+        <div class="height-100">
+          <p class="header_num">{{ stat.dayUsedCount || 0 }}</p>
+          <span class="header_name">今日已核销</span>
+        </div>
+      </a-col>
+      <a-col :span="6" :order="3">
+        <div class="height-100">
+          <p class="header_num">{{ stat.dayReceivedCount || 0 }}</p>
+          <span class="header_name">今日待核销</span>
+        </div>
+      </a-col>
+      <a-col :span="6" :order="4">
+        <div class="height-100">
+          <p class="header_num">{{ stat.dayVoidedCount || 0 }}</p>
+          <span class="header_name">今日作废</span>
+        </div>
+      </a-col>
+    </a-row>
+    <div style="margin-top: 15px">
+      <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="avatar" slot-scope="text">
+          <a-avatar v-if="text" :src="text" />
+          <a-avatar v-else icon="user" />
+        </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="handlePointEdit(record)">积分调整</a>
+          <a-divider type="vertical" />
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm
+                  title="确定删除吗?"
+                  @confirm="() => handleDelete(record.id)"
+                >
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+      </a-table>
+    </div>
+    <bus-market-meal-coupons-used-verify-modal
+      ref="modalMarketMealCouponsUsedVerifyModal"
+      @fatherLoadData="fatherLoadData"
+    ></bus-market-meal-coupons-used-verify-modal>
+  </a-card>
+</template>
+
+<script>
+import BusMarketMealCouponsUsedVerifyModal from "./modules/mealCoupons/BusMarketMealCouponsUsedVerifyModal.vue";
+import { httpAction, getAction } from "@/api/manage";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+const hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+export default {
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMarketMealCouponsUsedVerifyModal,
+  },
+  data() {
+    return {
+      mealCouponTypeList: [],
+      description: "餐券核销页面",
+      // 表头
+      columns: [
+        {
+          title: "餐券名称",
+          align: "center",
+          dataIndex: "couponsName",
+        },
+        {
+          title: "餐券类型",
+          align: "center",
+          dataIndex: "typeName",
+        },
+        {
+          title: "券号",
+          align: "center",
+          dataIndex: "code",
+        },
+        {
+          title: "房间号",
+          align: "center",
+          dataIndex: "roomNumber",
+        },
+        {
+          title: "核销人",
+          align: "center",
+          dataIndex: "usedUserName",
+        },
+        {
+          title: "核销时间",
+          align: "center",
+          dataIndex: "usedTime",
+        },
+      ],
+      url: {
+        list: "/business/busMarketMealCouponsUsed/verifyList",
+        delete: "/business/busMarketMealCouponsUsed/delete",
+        deleteBatch: "/business/busMarketMealCouponsUsed/deleteBatch",
+        exportXlsUrl: "/business/busMarketMealCouponsUsed/exportXls",
+        importExcelUrl: "business/busMarketMealCouponsUsed/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      stat: {},
+    };
+  },
+  created() {
+    httpAction(
+      "/rooms/cesMealCoupon/fetch",
+      { hotelId: hotelInfo.id },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.mealCouponTypeList = res.result;
+      }
+    });
+    this.getStat();
+  },
+  methods: {
+    getStat() {
+      console.log("this.queryParam.type",this.queryParam.type)
+      getAction(
+        "/business/busMarketMealCouponsUsed/stat",
+        { hotelId: hotelInfo.id, type: this.queryParam.type }
+      ).then((res) => {
+        if (res.success) {
+          this.stat = res.result;
+        }
+      });
+    },
+    tabClick(e) {
+      console.log(e);
+      this.queryParam.type = e;
+      this.loadData();
+      this.getStat();
+    },
+    handleAdd() {
+      this.$refs.modalMarketMealCouponsUsedVerifyModal.visible = true;
+      this.$refs.modalMarketMealCouponsUsedVerifyModal.title = "详情";
+      this.$refs.modalMarketMealCouponsUsedVerifyModal.disableSubmit = true;
+      this.$refs.modalMarketMealCouponsUsedVerifyModal.add();
+    },
+    fatherLoadData() {
+      console.log(2);
+      this.loadData();
+    },
+  },
+};
+</script>
+
+<style scoped>
+.main {
+  height: 70% !important;
+}
+.height-100 {
+  padding: 2px;
+  border: 1px solid #d8d8d8;
+  text-align: center;
+}
+.header_num {
+  font-size: 24px;
+  color: #5197ee;
+  font-weight: bold;
+}
+.header_name {
+  font-size: 17px;
+}
+</style>

+ 254 - 0
src/views/markets/meetingroom.vue

@@ -0,0 +1,254 @@
+<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
+              >
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button @click="batchDel" type="danger" icon="minus">批量删除</a-button>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="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 v-if="record.status != 1" @click="setStatus(record,1)">启用</a>
+          <a v-else @click="setStatus(record,0)">禁用</a>
+          <a-divider type="vertical" />
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm
+                  title="确定删除吗?"
+                  @confirm="() => handleDelete(record.id)"
+                >
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+      </a-table>
+    </div>
+
+    <bus-meeting-room-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-meeting-room-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import BusMeetingRoomModal from "./modules/meetingRoom/BusMeetingRoomModal";
+import { httpAction, postAction } from "@/api/manage";
+export default {
+  name: "BusMeetingRoomList",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMeetingRoomModal,
+  },
+  data() {
+    return {
+      description: "bus_meeting_room管理页面",
+      // 表头
+      columns: [
+        {
+          title: "名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "规格",
+          align: "center",
+          dataIndex: "spec",
+        },
+        {
+          title: "面积",
+          align: "center",
+          dataIndex: "area",
+        },
+        {
+          title: "人数",
+          align: "center",
+          dataIndex: "number",
+        },
+        {
+          title: "管理员姓名",
+          align: "center",
+          dataIndex: "adminName",
+        },
+        {
+          title: "地址",
+          align: "center",
+          dataIndex: "address",
+        },
+        {
+          title: "设备",
+          align: "center",
+          dataIndex: "facility",
+        },
+        {
+          title: "排序",
+          align: "center",
+          dataIndex: "sort",
+        },
+        {
+          title: "描述",
+          align: "center",
+          dataIndex: "remark",
+        },
+        {
+          title: "状态",
+          align: "center",
+          dataIndex: "status",
+          customRender: function (text) {
+            return text == 1 ? "启用" : "未启用";
+          },
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/business/busMeetingRoom/list",
+        delete: "/business/busMeetingRoom/delete",
+        deleteBatch: "/business/busMeetingRoom/deleteBatch",
+        exportXlsUrl: "/business/busMeetingRoom/exportXls",
+        importExcelUrl: "business/busMeetingRoom/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    };
+  },
+  created() {
+    this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    setStatus(record, status) {
+      record.status = status;
+      postAction("/business/busMeetingRoom/edit", record).then((res) => {
+        if (res.success) {
+          this.$message.success(res.message);
+        } else {
+          this.$message.warning(res.message);
+        }
+      });
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({ type: "string", value: "tenantId", text: "关联租户" });
+      fieldList.push({ type: "string", value: "hotelId", text: "关联酒店" });
+      fieldList.push({ type: "string", value: "name", text: "名称" });
+      fieldList.push({ type: "string", value: "spec", text: "规格" });
+      fieldList.push({ type: "number", value: "area", text: "金额" });
+      fieldList.push({ type: "int", value: "number", text: "人数" });
+      fieldList.push({
+        type: "string",
+        value: "adminName",
+        text: "管理员姓名",
+      });
+      fieldList.push({ type: "string", value: "address", text: "地址" });
+      fieldList.push({ type: "string", value: "facility", text: "设备" });
+      fieldList.push({ type: "int", value: "sort", text: "排序" });
+      fieldList.push({ type: "string", value: "remark", text: "描述" });
+      fieldList.push({ type: "int", value: "status", text: "状态" });
+      this.superFieldList = fieldList;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 659 - 0
src/views/markets/meetingroomschedule.vue

@@ -0,0 +1,659 @@
+<template>
+  <a-card :bordered="false">
+    <div class="course-week">
+      <div class="week-top">
+        <div class="week-btn-wrap">
+          <span @click="getLastWeek">上周</span>
+          <span @click="getCurWeek">本周</span>
+          <span @click="getNextWeek">下周</span>
+        </div>
+        <span class="w-today-date"> {{ todayDate }}</span>
+        <div class="w-choose-status">
+          <div v-for="sta in cardStatus">
+            <span class="square" :style="{ background: sta.color }"></span>
+            <span class="title">{{ sta.title }}</span>
+          </div>
+        </div>
+      </div>
+      <div class="week-table">
+        <div class="table-header">
+          <div class="table-week">
+            <template v-for="(item, index) of weeks">
+              <span class="w-first" v-if="index === 0" :key="index">{{
+                item
+              }}</span>
+              <span v-else :key="index">{{ item }}</span>
+            </template>
+          </div>
+          <div class="w-table-date">
+            <template v-for="(item, index) of months">
+              <span class="w-first" v-if="index === 0" :key="index"> </span>
+              <template v-else>
+                <span
+                  :key="index"
+                  class="w-day-item"
+                  :class="{ 'w-isCurDate': item && item.isCurDate }"
+                >
+                  {{
+                    `${
+                      item && item.isCurDate
+                        ? (item && item.showDate + "(今天)") || ""
+                        : (item && item.showDate) || ""
+                    }`
+                  }}
+                </span>
+              </template>
+            </template>
+          </div>
+        </div>
+        <div class="w-time-period-list">
+          <ul
+            class="w-time-period-row"
+            v-for="(i, i_index) in planList2"
+            :key="i_index"
+          >
+            <!--循环时段,看时段有多少个-->
+            <template v-if="i.child && i.child.length > 0">
+              <li
+                class="w-time-period-col"
+                v-for="(period, p_index) in i.child"
+                :key="`period${p_index}`"
+              >
+                <!--第一列显示时段-->
+                <div class="w-time-period">
+                  <span v-if="p_index == 1" class="meeting-room-center">{{
+                    i.meetingRoomName
+                  }}</span
+                  >{{ period.timePeriod }}
+                </div>
+                <!-- 后面显示周一到周日的计划-->
+                <div class="w-row-day">
+                  <!-- 循环显示每周的日期-->
+                  <template v-for="(month, m_index) of months">
+                    <!-- v-if="month" 去除数据处理的时候移除数组第一个为empty的问题-->
+                    <div
+                      v-if="month"
+                      :key="`month${m_index}`"
+                      class="w-things"
+                      @click="handleCardDetail(month, period)"
+                    >
+                      <!-- 循环每个时间段的计划-->
+                      <template v-for="(card, t_index) of period.schedule">
+                        <template
+                          v-if="card.key == month.date"
+                          v-for="(single, sIndex) in card.value"
+                        >
+                          <div style="width: 80%">
+                            <a-popover placement="rightTop">
+                              <template slot="content">
+                                <p>会议室:{{ i.meetingRoomName }}</p>
+                                <p>会议主题:{{ single.roomSchedule.theme }}</p>
+                                <p>公司名称:{{ single.roomSchedule.name }}</p>
+                                <p>
+                                  预定人:{{ single.roomSchedule.destinedName }}
+                                </p>
+                                <p>
+                                  联系电话:{{ single.roomSchedule.mobile }}
+                                </p>
+                                <p>是否结账:未结账</p>
+                                <p>备注:{{ single.roomSchedule.remark }}</p>
+                              </template>
+                              <template slot="title">
+                                <span>详情</span>
+                              </template>
+
+                              <div
+                                :key="`thing${sIndex}`"
+                                class="w-thing-item"
+                                @click.stop="handleDetail(single)"
+                                :style="{
+                                  background:
+                                    cardStatus[single.detail.status].color,
+                                }"
+                              >
+                                <span>{{ single.theme }}</span>
+                              </div>
+                            </a-popover>
+                          </div>
+                        </template>
+                      </template>
+                    </div>
+                  </template>
+                </div>
+              </li>
+            </template>
+            <!-- <div class="w-noMore" v-else><span>暂无数据</span></div> -->
+          </ul>
+        </div>
+      </div>
+    </div>
+    <bus-meeting-room-schedule-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-meeting-room-schedule-modal>
+    <bus-meeting-room-schedule-confirm-modal
+      ref="modalBusMeetingRoomScheduleConfirm"
+      @ok="modalFormOk"
+    ></bus-meeting-room-schedule-confirm-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+// import { mixinDevice } from "@/utils/mixin";
+// import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import { httpAction, getAction } from "@/api/manage";
+import BusMeetingRoomScheduleModal from "./modules/meetingRoomSchedule/BusMeetingRoomScheduleModal.vue";
+import BusMeetingRoomScheduleConfirmModal from "./modules/meetingRoomSchedule/BusMeetingRoomScheduleConfirmModal.vue";
+
+export default {
+  name: "BusMeetingRoomList",
+  // mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMeetingRoomScheduleModal,
+    BusMeetingRoomScheduleConfirmModal,
+  },
+  data() {
+    const planList = [
+      {
+        timePeriod: "上午",
+        schedule: [
+          {
+            key: "2023-03-15",
+            value: [
+              {
+                theme: "大会议室",
+                status: 1,
+                meeting_room_schedule: {}, //预定信息实体
+              },
+            ],
+          },
+          {
+            key: "2023-03-14",
+            value: [
+              {
+                theme: "大会议室",
+                status: 0,
+                meeting_room_schedule: {}, //预定信息实体
+              },
+            ],
+          },
+        ],
+      },
+      {
+        timePeriod: "下午",
+        schedule: [
+          {
+            key: "2023-03-15",
+            value: [
+              {
+                theme: "大会议室1111111111111111111111111",
+                status: 0,
+                meeting_room_schedule: {}, //预定信息实体
+              },
+            ],
+          },
+          {
+            key: "2023-03-14",
+            value: [
+              {
+                theme: "大会议室",
+                status: 0,
+                meeting_room_schedule: {}, //预定信息实体
+              },
+            ],
+          },
+        ],
+      },
+      {
+        timePeriod: "晚上",
+        schedule: [],
+      },
+    ];
+    return {
+      isFirstDayOfMondayOrSunday: 1,
+      cardStatus: {
+        0: {
+          title: "预定未确认",
+          color: "#3291F8",
+        },
+        1: {
+          title: "预定已确认",
+          color: "#FF6200",
+        },
+      },
+      weeks: ["时段", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
+      todayDate: "",
+      months: [],
+      curDate: "",
+      nowDate: new Date(),
+      planList2: [
+        // { meetingRoomName: "大会议", child: planList },
+        // { meetingRoomName: "大会议2", child: planList },
+      ],
+      startDate: "",
+      endDate: "",
+    };
+  },
+  watch: {
+    isFirstDayOfMondayOrSunday: {
+      handler(val) {
+        if (val > 1) {
+          let arr = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
+          const arr1 = arr.slice(val - 1);
+          const arr2 = arr.slice(0, val - 1);
+          this.weeks = ["时段", ...arr1, ...arr2];
+        }
+      },
+      immediate: true,
+    },
+  },
+  mounted() {
+    this.getCurWeek();
+  },
+  created() {},
+  methods: {
+    modalFormOk() {
+      this.loadData();
+    },
+    loadData() {
+      var _info = JSON.parse(localStorage.getItem("storeInfo"));
+      getAction("/business/busMeetingRoomSchedule/fetch", {
+        startDate: this.startDate,
+        endDate: this.endDate,
+        hotelId: _info.id,
+      }).then((res) => {
+        if (res.success) {
+          this.planList2 = res.result;
+        }
+      });
+    },
+    /**
+     * 获取 时间
+     * @param time
+     */
+    getWeek(time) {
+      this.curDate = new Date(time);
+      //当前是周几
+      const whichDay = time.getDay();
+      let num = 0;
+      if (this.isFirstDayOfMondayOrSunday <= whichDay) {
+        num = this.isFirstDayOfMondayOrSunday;
+      } else {
+        num = this.isFirstDayOfMondayOrSunday - 7;
+      }
+      const weekDay = time.getDay() - num;
+      time = this.addDate(time, weekDay * -1);
+      for (let i = 0; i < 7; i++) {
+        const { year, month, day } = this.formatDate(
+          i === 0 ? time : this.addDate(time, 1)
+        );
+        this.months.push({
+          date: `${year}-${month}-${day}`,
+          showDate: `${month}-${day}`,
+          timestamp: new Date(`${year}-${month}-${day}`).getTime(),
+        });
+      }
+      this.months.sort((a, b) => a.timestamp - b.timestamp);
+      delete this.months[0];
+      this.todayDate = `${this.months[1].date} ~ ${
+        this.months[this.months.length - 1].date
+      }`;
+
+      this.startDate = this.months[1].date + " 00:00:00";
+      this.endDate = this.months[this.months.length - 1].date + " 00:00:00";
+      this.loadData();
+    },
+    /**
+     * 处理日期
+     * @param date
+     * @param n
+     * @returns {*}
+     */
+    addDate(date, n) {
+      date.setDate(date.getDate() + n);
+      return date;
+    },
+    /**
+     * 上周
+     */
+    getLastWeek() {
+      const date = this.addDate(this.curDate, -7),
+        { year, month, day } = this.formatDate(date),
+        dateObj = {
+          date: `${year}-${month}-${day}`,
+          timestamp: new Date(`${year}-${month}-${day}`).getTime(),
+        };
+      this.dealDate(date);
+      this.$emit("changeWeek", dateObj);
+    },
+    /**
+     * 本周
+     */
+    getCurWeek() {
+      const { year, month, day } = this.formatDate(new Date()),
+        dateObj = {
+          date: `${year}-${month}-${day}`,
+          timestamp: new Date(`${year}-${month}-${day}`).getTime(),
+        };
+      this.dealDate(new Date());
+      this.$emit("changeWeek", dateObj);
+    },
+    //日期格式处理
+    formatDate(date) {
+      var year = date.getFullYear();
+      var months = date.getMonth() + 1;
+      var month = (months < 10 ? "0" + months : months).toString();
+      var day = (
+        date.getDate() < 10 ? "0" + date.getDate() : date.getDate()
+      ).toString();
+      return {
+        year: year.toString(),
+        month,
+        day,
+      };
+    },
+    /**
+     * 获取当天时间
+     * @returns {string}
+     */
+    getCurDay(num = 0) {
+      var datetime = new Date();
+      var year = datetime.getFullYear();
+      var month =
+        datetime.getMonth() + 1 < 10
+          ? "0" + (datetime.getMonth() + 1)
+          : datetime.getMonth() + 1;
+      let day = datetime.getDate();
+      if (day + num > 0) {
+        day =
+          day + num < 10
+            ? "0" + (datetime.getDate() + num)
+            : datetime.getDate() + num;
+      } else {
+        day =
+          day - num < 10
+            ? "0" + (datetime.getDate() - num)
+            : datetime.getDate() - num;
+      }
+      return `${year}-${month}-${day}`;
+    },
+    /**
+     * 下周
+     */
+    getNextWeek() {
+      const date = this.addDate(this.curDate, 7),
+        { year, month, day } = this.formatDate(date),
+        dateObj = {
+          date: `${year}-${month}-${day}`,
+          timestamp: new Date(`${year}-${month}-${day}`).getTime(),
+        };
+      this.dealDate(date);
+      this.$emit("changeWeek", dateObj);
+    },
+    /**
+     * 显示当天日期状态
+     * @param date
+     */
+    dealDate(date) {
+      this.months = [""];
+      this.getWeek(date);
+      const curDate = this.getCurDay();
+      this.months.forEach((item) => {
+        item.isCurDate = item.date === curDate;
+      });
+    },
+    /**
+     * 预定确认
+     * @param row
+     */
+    handleDetail(row) {
+      console.log("row", row);
+      this.$refs.modalBusMeetingRoomScheduleConfirm.edit(row);
+      this.$refs.modalBusMeetingRoomScheduleConfirm.title = "预定确认";
+      this.$refs.modalBusMeetingRoomScheduleConfirm.disableSubmit = false;
+      this.$refs.modalBusMeetingRoomScheduleConfirm.disableSubmit = true;
+    },
+    /**
+     * 预定登记
+     * @param month
+     * @param period
+     */
+    handleCardDetail(month, period) {
+      this.$refs.modalForm.add();
+      this.$refs.modalForm.title = "预定登记";
+      this.$refs.modalForm.disableSubmit = false;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>
+<style>
+ul {
+  list-style: none;
+}
+
+ul,
+li {
+  margin: 0;
+  padding: 0;
+}
+
+.course-week {
+  width: 100%;
+  border: 1px solid #ddd;
+  padding: 1%;
+  box-sizing: border-box;
+}
+
+.week-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+  height: 40px;
+  padding: 0 1%;
+  box-sizing: border-box;
+}
+
+.week-top .week-btn-wrap {
+  width: 200px;
+  display: flex;
+  justify-content: space-around;
+  color: #409eff;
+}
+
+.week-top .week-btn-wrap span {
+  cursor: pointer;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 15px;
+}
+
+.w-today-date {
+  font-weight: bold;
+  font-size: 16px;
+}
+
+.w-choose-status {
+  display: flex;
+  justify-content: flex-end;
+  width: 200px;
+}
+
+.w-choose-status > div {
+  width: 100%;
+  flex: 1;
+  display: flex;
+  padding: 0 2%;
+  white-space: nowrap;
+  line-height: 20px;
+  box-sizing: border-box;
+}
+
+.w-choose-status > div .square {
+  display: flex;
+  width: 16px;
+  height: 16px;
+  border-radius: 4px;
+  box-sizing: border-box;
+}
+
+.w-choose-status > div .title {
+  display: flex;
+  align-items: center;
+  line-height: 16px;
+  padding-left: 4px;
+  font-size: 14px;
+  box-sizing: border-box;
+}
+
+.week-table {
+  display: flex;
+  flex-direction: column;
+}
+
+.week-table .table-header {
+  width: 100%;
+  height: 80px;
+  background: #eaedf2;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  border-bottom: 1px solid #eaedf2;
+  box-sizing: border-box;
+}
+
+.table-header .w-table-date,
+.table-week {
+  width: 100%;
+  height: 40px;
+  text-align: left;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.table-header .w-table-date > span,
+.table-week > span {
+  flex: 1;
+  color: #000;
+  height: 100%;
+  font-size: 14px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-weight: bold;
+}
+
+.w-table-date .w-day-item,
+.table-week .w-day-item {
+  color: #000;
+  font-size: 14px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.week-table .w-time-period-list {
+  width: 100%;
+}
+
+.w-time-period-list .w-time-period-row {
+  width: 100%;
+  min-height: 60px;
+}
+
+.w-time-period-col {
+  width: 100%;
+  min-height: 60px;
+  display: flex;
+}
+
+.w-time-period-col .w-time-period {
+  width: 12.5%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-left: 1px solid #eaedf2;
+  /* border-bottom: 1px solid #eaedf2; */
+  box-sizing: border-box;
+}
+.w-time-period-col:last-child {
+  border-bottom: 1px solid #eaedf2;
+}
+.meeting-room-center {
+  transform: translate(-200%, 0%);
+  width: 14px;
+  font-size: 14px;
+  word-wrap: break-word;
+  position: absolute;
+}
+
+.w-time-period-col .w-row-day {
+  width: 87.5%;
+  display: flex;
+  justify-content: center;
+}
+
+.w-row-day .w-things {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  border-left: 1px solid #eaedf2;
+  border-bottom: 1px solid #eaedf2;
+  box-sizing: border-box;
+  cursor: pointer;
+}
+
+.w-row-day .w-things:last-child {
+  border-right: 1px solid #eaedf2;
+}
+
+.w-things .w-thing-item {
+  display: flex;
+  width: 80%;
+  font-size: 14px;
+  flex-direction: column;
+  justify-content: space-around;
+  min-height: 50px;
+  border-radius: 10px;
+  margin: 2% 1%;
+  padding: 1% 2%;
+  cursor: pointer;
+  color: #fff;
+  background: #ff6200;
+  box-sizing: border-box;
+  transition: all 1s linear 0.5s;
+}
+
+.w-isCurDate {
+  color: #ff2525 !important;
+}
+
+.w-noMore {
+  min-height: 200px;
+  padding: 2%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border: 1px solid rgba(156, 173, 173, 0.3);
+  color: #9cadadb7;
+  box-sizing: border-box;
+}
+
+.w_expand,
+.w_shrink {
+  color: #0a98d5;
+  cursor: pointer;
+  width: 100%;
+  padding: 2% 0;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+</style>

+ 751 - 0
src/views/markets/member.vue

@@ -0,0 +1,751 @@
+<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="">
+              <a-select
+                mode="multiple"
+                style="width: 180px"
+                placeholder="商家名称"
+                :maxTagCount="1"
+                :maxTagTextLength="50"
+                v-model="queryParam.hotelIds"
+              >
+                <a-select-option
+                  v-for="(item, index) in hotelList"
+                  :key="index"
+                  :value="item.id"
+                >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="会员名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="会员手机号"
+                v-model="queryParam.mobile"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="会员卡号"
+                v-model="queryParam.cardNo"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <a-select
+                v-model:value="queryParam.gradeId"
+                style="width: 100%"
+                placeholder="会员等级"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in gradeList"
+                  :key="index"
+                  :value="item.id"
+                  >{{ item.name }}</a-select-option
+                >
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <a-select
+                v-model:value="queryParam.groupId"
+                style="width: 100%"
+                placeholder="会员分组"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in groupList"
+                  :key="index"
+                  :value="item.id"
+                  >{{ item.name }}</a-select-option
+                >
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <a-select
+                v-model:value="queryParam.labelId"
+                style="width: 100%"
+                placeholder="会员标签"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in labelList"
+                  :key="index"
+                  :value="item.id"
+                  >{{ item.name }}</a-select-option
+                >
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <a-range-picker
+                format="YYYY-MM-DD"
+                :placeholder="['注册开始日期', '注册结束日期']"
+                @change="onChange"
+                v-model="datetime"
+              />
+            </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"
+      style="display: flex; justify-content: space-between"
+    >
+      <div>
+        <a-button @click="handleAdd" type="primary" icon="plus">办卡</a-button>
+        <a-button @click="batchDel" type="danger" icon="minus"
+          >批量删除</a-button
+        >
+        <!-- <a-button
+          type="primary"
+          icon="download"
+          @click="handleExportXls('bus_market_coupons_info')"
+          >导出</a-button
+        >
+        <a-upload
+          name="file"
+          :showUploadList="false"
+          :multiple="false"
+          :headers="tokenHeader"
+          :action="importExcelUrl"
+          @change="handleImportExcel"
+        >
+          <a-button type="primary" icon="import">导入</a-button>
+        </a-upload> -->
+      </div>
+      <div>
+        <a-switch @change="onSwitchChange" />
+      </div>
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>-->
+    </div>
+    <div v-show="showCard">
+      <a-row :gutter="24">
+        <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+          <div class="ant-card ant-card-h">
+            <div class="ant-card-body" style="padding: 20px 24px 8px">
+              <div class="chart-card-header">
+                <div class="meta">
+                  <span class="chart-card-title">今日过生日的会员</span>
+                </div>
+                <div class="total" style="color: #ff5400">
+                  <span>{{ stat.birthdayCount || 0 }}</span
+                  ><span style="font-size: 15px">位</span>
+                </div>
+              </div>
+              <div class="chart-card-content">
+                <div class="content-fix">
+                  <div>
+                    <div style="margin-right: 16px">
+                      本月还有<span style="color: #ff5400">{{
+                        stat.monthBirthdayCount || 0
+                      }}</span
+                      >位会员生日
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </a-col>
+
+        <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+          <div class="ant-card ant-card-h">
+            <div class="ant-card-body" style="padding: 20px 24px 8px">
+              <div class="chart-card-header">
+                <div class="meta">
+                  <span class="chart-card-title">会员总数</span>
+                </div>
+                <div class="total" style="color: #ff5400">
+                  <span>{{ stat.count || 0 }}</span
+                  ><span style="font-size: 15px">位</span>
+                </div>
+              </div>
+              <div class="chart-card-content">
+                <div class="content-fix">
+                  <div>
+                    <div style="margin-right: 16px">
+                      今日新增<span style="color: #ff5400">{{
+                        stat.dayCount || 0
+                      }}</span
+                      >位会员
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </a-col>
+
+        <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+          <div class="ant-card ant-card-h">
+            <div class="ant-card-body" style="padding: 20px 24px 8px">
+              <div class="chart-card-header">
+                <div class="meta">
+                  <span class="chart-card-title">累计消费</span>
+                </div>
+                <div class="total" style="color: #ff5400">
+                  <span>0.00</span><span style="font-size: 15px">元</span>
+                </div>
+              </div>
+              <div class="chart-card-content">
+                <div class="content-fix">
+                  <div>
+                    <div style="margin-right: 16px">
+                      今日已有<span style="color: #ff5400">0</span
+                      >位会员消费<span style="color: #ff5400">0.00</span>元
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </a-col>
+
+        <a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
+          <div class="ant-card ant-card-h">
+            <div class="ant-card-body" style="padding: 20px 24px 8px">
+              <div class="chart-card-header">
+                <div class="meta">
+                  <span class="chart-card-title">消费会员(TOP3)</span>
+                </div>
+              </div>
+              <div class="chart-card-content">
+                <div class="content-fix">
+                  <div>
+                    <div style="margin-right: 16px">暂无</div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </a-col>
+      </a-row>
+    </div>
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="avatar" slot-scope="text">
+          <a-avatar v-if="text" :src="text" />
+          <a-avatar v-else icon="user" />
+        </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="handlePointEdit(record)">积分调整</a>
+          <a-divider type="vertical" />
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm
+                  title="确定删除吗?"
+                  @confirm="() => handleDelete(record.id)"
+                >
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+      </a-table>
+      <a-select
+        style="width: 200px"
+        placeholder="请选择会员分组"
+        :disabled="selectedRowKeys.length <= 0"
+        v-model="groupId"
+        @change="groupChange"
+      >
+        <a-select-option
+          v-for="(item, index) in groupList"
+          :key="index"
+          :value="item.id"
+          >{{ item.name }}</a-select-option
+        >
+      </a-select>
+      <a-select
+        style="width: 200px; margin-left: 10px"
+        placeholder="请选择会员标签"
+        :disabled="selectedRowKeys.length <= 0"
+        v-model="labelId"
+        @change="labelChange"
+      >
+        <a-select-option
+          v-for="(item, index) in labelList"
+          :key="index"
+          :value="item.id"
+          >{{ item.name }}</a-select-option
+        >
+      </a-select>
+    </div>
+    <bus-member-card-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-member-card-modal>
+    <bus-member-point-log-modal
+      ref="modalMemberPointLogForm"
+      @ok="modalFormOk"
+    ></bus-member-point-log-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import { httpAction } from "@/api/manage";
+import BusMemberCardModal from "./modules/memberCard/BusMemberCardModal";
+import BusMemberPointLogModal from "./modules/memberPoint/BusMemberPointLogModal";
+
+const hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+export default {
+  name: "BusMemberCardList",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMemberCardModal,
+    BusMemberPointLogModal,
+  },
+  data() {
+    return {
+      showCard: false,
+      groupId: undefined,
+      labelId: undefined,
+      description: "会员页面",
+      datetime: [],
+      // 表头
+      columns: [
+        {
+          title: "商家",
+          align: "center",
+          dataIndex: "hotelName",
+        },
+        {
+          title: "头像",
+          align: "center",
+          dataIndex: "avatar",
+          scopedSlots: { customRender: "avatar" },
+        },
+        {
+          title: "会员姓名",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "手机号",
+          align: "center",
+          dataIndex: "mobile",
+        },
+        {
+          title: "性别",
+          align: "center",
+          dataIndex: "sex",
+          customRender: function (text) {
+            return text === 1 ? "男" : "女";
+          },
+        },
+        {
+          title: "会员卡号",
+          align: "center",
+          dataIndex: "cardNo",
+        },
+        {
+          title: "等级类型",
+          align: "center",
+          dataIndex: "gradeName",
+        },
+        {
+          title: "证件号",
+          align: "center",
+          dataIndex: "certificateNo",
+        },
+        {
+          title: "创建日期",
+          align: "center",
+          dataIndex: "createTime",
+        },
+        {
+          title: "推荐员工",
+          align: "center",
+          dataIndex: "staffId",
+        },
+        {
+          title: "可用积分",
+          align: "center",
+          dataIndex: "integral",
+          customRender: function (text) {
+            return text || 0;
+          },
+        },
+        {
+          title: "可用余额",
+          align: "center",
+          dataIndex: "balance",
+          customRender: function (text) {
+            return text || 0;
+          },
+        },
+        {
+          title: "标签",
+          align: "center",
+          dataIndex: "labelName",
+        },
+        {
+          title: "分组",
+          align: "center",
+          dataIndex: "groupName",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list:
+          hotelInfo && hotelInfo.id
+            ? "/business/busMemberCard/list?hotelId=" + hotelInfo.id
+            : "/business/busMemberCard/list",
+        delete: "/business/busMemberCard/delete",
+        deleteBatch: "/business/busMemberCard/deleteBatch",
+        exportXlsUrl: "/business/busMemberCard/exportXls",
+        importExcelUrl: "business/busMemberCard/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      hotelList: [],
+      gradeList: [],
+      groupList: [],
+      labelList: [],
+      stat: {},
+    };
+  },
+  created() {
+    // this.getSuperFieldList();
+    httpAction(
+      "/business/busHotel/list",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.hotelList = res.result.records;
+      }
+    });
+    httpAction(
+      "/org.jeecg.modules.business/busMarketMember/list",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.gradeList = res.result.records;
+      }
+    });
+    httpAction(
+      "/business/busMarketMemberGroup/list",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.groupList = res.result.records;
+      }
+    });
+    httpAction(
+      "/business/busMarketMemberLable/list",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.labelList = res.result.records;
+      }
+    });
+    httpAction("/business/busMemberCard/stat", {}, "get").then((res) => {
+      if (res.success) {
+        this.stat = res.result;
+      }
+    });
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    searchQuery() {
+      if (this.queryParam.hotelIds && this.queryParam.hotelIds.length > 0) {
+        this.url.list = "/business/busMemberCard/list";
+      } else {
+        this.url.list = "/business/busMemberCard/list?hotelId=" + hotelInfo.id;
+      }
+      this.loadData(1);
+      this.selectedRowKeys = [];
+      this.selectionRows = [];
+    },
+    handlePointEdit(item) {
+      this.$refs.modalMemberPointLogForm.add({
+        memberId: item.id,
+        hotelId: item.hotelId,
+        tenantId: item.tenantId,
+        integral: item.integral,
+        cardNo: item.cardNo,
+        name: item.name,
+      });
+      this.$refs.modalMemberPointLogForm.title = "积分调整";
+      this.$refs.modalMemberPointLogForm.disableSubmit = false;
+    },
+    groupChange(e) {
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return;
+      }
+      var that = this;
+      httpAction(
+        "/business/busMemberCard/groupBatch",
+        {
+          groupId: e,
+          ids: this.selectedRowKeys,
+        },
+        "post"
+      )
+        .then((res) => {
+          if (res.success) {
+            that.$message.success(res.message);
+            that.groupId = undefined;
+            that.modalFormOk();
+          } else {
+            that.$message.warning(res.message);
+          }
+        })
+        .finally(() => {});
+    },
+    labelChange(e) {
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return;
+      }
+      var that = this;
+      httpAction(
+        "/business/busMemberCard/lableBatch",
+        {
+          labelId: e,
+          ids: this.selectedRowKeys,
+        },
+        "post"
+      )
+        .then((res) => {
+          if (res.success) {
+            that.$message.success(res.message);
+            that.labelId = undefined;
+            that.modalFormOk();
+          } else {
+            that.$message.warning(res.message);
+          }
+        })
+        .finally(() => {});
+    },
+    searchReset() {
+      this.datetime = [];
+      this.queryParam = {};
+      this.loadData(1);
+    },
+    onChange(e, dateString) {
+      // console.log("Selected Time: ", e);
+      // console.log("Formatted Selected Time: ", dateString);
+      this.queryParam.startTime = dateString[0];
+      this.queryParam.endTime = dateString[1];
+    },
+    onSwitchChange(e) {
+      console.log(e);
+      this.showCard = e;
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({ type: "string", value: "tenantId", text: "关联租户" });
+      fieldList.push({ type: "string", value: "hotelId", text: "关联酒店" });
+      fieldList.push({ type: "string", value: "mobile", text: "手机号" });
+      fieldList.push({ type: "string", value: "cardNo", text: "会员卡号" });
+      fieldList.push({ type: "string", value: "cardInnerNo", text: "卡内码" });
+      fieldList.push({ type: "string", value: "gradeId", text: "等级类型" });
+      fieldList.push({ type: "number", value: "memberFee", text: "会员费" });
+      fieldList.push({ type: "int", value: "payType", text: "付款类型" });
+      fieldList.push({ type: "int", value: "paymentMethod", text: "付款方式" });
+      fieldList.push({ type: "string", value: "name", text: "会员姓名" });
+      fieldList.push({ type: "string", value: "avatar", text: "头像" });
+      fieldList.push({ type: "int", value: "sex", text: "性别" });
+      fieldList.push({
+        type: "int",
+        value: "certificateType",
+        text: "证件类型",
+      });
+      fieldList.push({
+        type: "string",
+        value: "certificateNo",
+        text: "证件号",
+      });
+      fieldList.push({ type: "string", value: "address", text: "地址" });
+      fieldList.push({
+        type: "string",
+        value: "consumePassword",
+        text: "消费密码",
+      });
+      fieldList.push({ type: "int", value: "validity", text: "有效期" });
+      fieldList.push({
+        type: "date",
+        value: "validityEndTime",
+        text: "有效期截止日期",
+      });
+      fieldList.push({ type: "string", value: "remark", text: "备注" });
+      fieldList.push({ type: "string", value: "staffId", text: "推荐员工" });
+      fieldList.push({ type: "int", value: "integral", text: "可用积分" });
+      fieldList.push({ type: "number", value: "balance", text: "可用余额" });
+      this.superFieldList = fieldList;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+/deep/ .ant-input-search-button {
+  background-color: #ff4d4f;
+  border-color: #ff4d4f;
+}
+/deep/ .ant-input-search-button[disabled]:hover {
+  opacity: 0.7;
+  background-color: #ff4d4f;
+  border-color: #ff4d4f;
+}
+/deep/ .ant-input-search-button[disabled] {
+  opacity: 0.7;
+  color: #ffffff;
+}
+.ant-card-h {
+  border: 1px solid #e8e8e8;
+  height: 150px;
+}
+.total {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  word-break: break-all;
+  white-space: nowrap;
+  color: #000;
+  margin-top: 4px;
+  margin-bottom: 0;
+  font-size: 30px;
+  line-height: 38px;
+  height: 38px;
+}
+.chart-card-content {
+  margin-bottom: 12px;
+  position: relative;
+  height: 46px;
+  width: 100%;
+}
+.chart-card-content .content-fix {
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  width: 100%;
+}
+</style>
+

+ 365 - 0
src/views/markets/memberrecharge.vue

@@ -0,0 +1,365 @@
+<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="">
+              <a-select
+                mode="multiple"
+                style="width: 180px"
+                placeholder="商家名称"
+                :maxTagCount="1"
+                :maxTagTextLength="50"
+                v-model="queryParam.hotelIds"
+              >
+                <a-select-option
+                  v-for="(item, index) in hotelList"
+                  :key="index"
+                  :value="item.id"
+                >
+                  {{ item.name }}
+                </a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="会员名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="会员手机号"
+                v-model="queryParam.mobile"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="3">
+            <a-form-item label="">
+              <j-input
+                placeholder="会员卡号"
+                v-model="queryParam.cardNo"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <a-range-picker
+                format="YYYY-MM-DD"
+                :placeholder="['开始日期', '注结束日期']"
+                @change="onChange"
+                v-model="datetime"
+              />
+            </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>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('bus_member_balance_log')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown> -->
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <!-- <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div> -->
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text, record">
+          <span v-if="!text" style="font-size: 12px; font-style: italic"
+            >无图片</span
+          >
+          <img
+            v-else
+            :src="getImgView(text)"
+            :preview="record.id"
+            height="25px"
+            alt=""
+            style="max-width: 80px; font-size: 12px; font-style: italic"
+          />
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px; font-style: italic"
+            >无文件</span
+          >
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)"
+          >
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm
+                  title="确定删除吗?"
+                  @confirm="() => handleDelete(record.id)"
+                >
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+      </a-table>
+    </div>
+
+    <bus-member-balance-log-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-member-balance-log-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import BusMemberBalanceLogModal from "./modules/memberBalance/BusMemberBalanceLogModal";
+import { httpAction } from "@/api/manage";
+const hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+export default {
+  name: "BusMemberBalanceLogList",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMemberBalanceLogModal,
+  },
+  data() {
+    return {
+      description: "bus_member_balance_log管理页面",
+      datetime: [],
+      // 表头
+      columns: [
+        {
+          title: "商家",
+          align: "center",
+          dataIndex: "hotelName",
+        },
+        {
+          title: "姓名",
+          align: "center",
+          dataIndex: "memberName",
+        },
+        {
+          title: "手机号",
+          align: "center",
+          dataIndex: "mobile",
+        },
+        {
+          title: "会员卡号",
+          align: "center",
+          dataIndex: "cardNo",
+        },
+        {
+          title: "流水号",
+          align: "center",
+          dataIndex: "code",
+        },
+        {
+          title: "充值金额",
+          align: "center",
+          dataIndex: "money",
+          customRender: function (text, record) {
+            return record.type === 1 ? "+" + text : "-" + text;
+          },
+        },
+        {
+          title: "赠送金额",
+          align: "center",
+          dataIndex: "giveMoney",
+          customRender: function (text, record) {
+            return text > 0 ? "+" + text : "-";
+          },
+        },
+        {
+          title: "支付金额",
+          align: "center",
+          dataIndex: "payMoney",
+        },
+        {
+          title: "支付方式",
+          align: "center",
+          dataIndex: "paymentMethodName",
+        },
+        {
+          title: "状态",
+          align: "center",
+          dataIndex: "status",
+          customRender: function (text, record) {
+            return text == 1 ? "已支付" : "未支付";
+          },
+        },
+        {
+          title: "备注",
+          align: "center",
+          dataIndex: "remarks",
+        },
+        {
+          title: "推荐员工",
+          align: "center",
+          dataIndex: "staffId",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 147,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list:
+          hotelInfo && hotelInfo.id
+            ? "/business/busMemberBalanceLog/list?hotelId=" + hotelInfo.id
+            : "/business/busMemberBalanceLog/list",
+        delete: "/business/busMemberBalanceLog/delete",
+        deleteBatch: "/business/busMemberBalanceLog/deleteBatch",
+        exportXlsUrl: "/business/busMemberBalanceLog/exportXls",
+        importExcelUrl: "business/busMemberBalanceLog/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      hotelList: [],
+    };
+  },
+  created() {
+    // this.getSuperFieldList();
+    httpAction(
+      "/business/busHotel/list",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.hotelList = res.result.records;
+      }
+    });
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    searchQuery() {
+      if (this.queryParam.hotelIds && this.queryParam.hotelIds.length > 0) {
+        this.url.list = "/business/busMemberBalanceLog/list";
+      } else {
+        this.url.list =
+          "/business/busMemberBalanceLog/list?hotelId=" + hotelInfo.id;
+      }
+      this.loadData(1);
+      this.selectedRowKeys = [];
+      this.selectionRows = [];
+    },
+    searchReset() {
+      this.datetime = [];
+      this.queryParam = {};
+      this.loadData(1);
+    },
+    onChange(e, dateString) {
+      // console.log("Selected Time: ", e);
+      // console.log("Formatted Selected Time: ", dateString);
+      this.queryParam.startTime = dateString[0];
+      this.queryParam.endTime = dateString[1];
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({ type: "string", value: "tenantId", text: "关联租户" });
+      fieldList.push({ type: "string", value: "hotelId", text: "关联酒店" });
+      fieldList.push({ type: "string", value: "memberId", text: "会员id" });
+      fieldList.push({ type: "int", value: "type", text: "类型" });
+      fieldList.push({ type: "number", value: "money", text: "充值金额" });
+      fieldList.push({ type: "number", value: "balance", text: "金额余额" });
+      fieldList.push({ type: "number", value: "giveMoney", text: "赠送金额" });
+      fieldList.push({ type: "string", value: "remarks", text: "备注" });
+      fieldList.push({ type: "string", value: "staffId", text: "推荐员工" });
+      fieldList.push({
+        type: "string",
+        value: "paymentMethod",
+        text: "支付方式",
+      });
+      fieldList.push({ type: "number", value: "payMoney", text: "支付金额" });
+      fieldList.push({ type: "string", value: "code", text: "流水号" });
+      this.superFieldList = fieldList;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

src/views/markets/modules/BusMarketCouponsForm.vue → src/views/markets/modules/coupons/BusMarketCouponsForm.vue


src/views/markets/modules/BusMarketCouponsModal.Style#Drawer.vue → src/views/markets/modules/coupons/BusMarketCouponsModal.Style#Drawer.vue


src/views/markets/modules/BusMarketCouponsModal.vue → src/views/markets/modules/coupons/BusMarketCouponsModal.vue


src/views/markets/modules/BusMarketCouponsUsedForm.vue → src/views/markets/modules/coupons/BusMarketCouponsUsedForm.vue


src/views/markets/modules/BusMarketCouponsUsedGenerateForm.vue → src/views/markets/modules/coupons/BusMarketCouponsUsedGenerateForm.vue


src/views/markets/modules/BusMarketCouponsUsedGenerateFormModal.vue → src/views/markets/modules/coupons/BusMarketCouponsUsedGenerateFormModal.vue


+ 2 - 3
src/views/markets/modules/BusMarketCouponsUsedList.vue

@@ -28,7 +28,7 @@
           <a-col :span="4">
             <a-form-item label="">
               <a-select
-                v-model:value="queryParam.status"
+                v-model="queryParam.status"
                 style="width: 120px"
                 placeholder="请选择状态"
                 :allowClear="true"
@@ -57,8 +57,7 @@
               >
               <a-button
                 @click="handleAdd"
-                type="primary"
-                icon="plus"
+                type="danger"
                 style="margin-left: 8px"
                 >生成免房券</a-button
               >

src/views/markets/modules/BusMarketCouponsUsedListModal.vue → src/views/markets/modules/coupons/BusMarketCouponsUsedListModal.vue


src/views/markets/modules/BusMarketCouponsUsedModal.Style#Drawer.vue → src/views/markets/modules/coupons/BusMarketCouponsUsedModal.Style#Drawer.vue


src/views/markets/modules/BusMarketCouponsUsedModal.vue → src/views/markets/modules/coupons/BusMarketCouponsUsedModal.vue


+ 286 - 0
src/views/markets/modules/couponsCash/BusMarketCouponsCashForm.vue

@@ -0,0 +1,286 @@
+<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="startTime"
+            >
+              <j-date
+                placeholder="请选择开始时间"
+                v-model="model.startTime"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="结束时间"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="endTime"
+            >
+              <j-date
+                placeholder="请选择结束时间"
+                v-model="model.endTime"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="优惠条件"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="conditions"
+            >
+              <a-radio-group v-model="model.type">
+                <a-radio :value="1">不限制</a-radio>
+                <a-radio :value="2">满</a-radio>
+              </a-radio-group>
+              <a-input-number
+                v-model="model.conditions"
+                :min="1"
+                style="width: 30%"
+                @blur="handleChange"
+              />元可使用
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="每单可使用张数"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="ksyzs"
+            >
+              <a-input-number
+                v-model="model.ksyzs"
+                :min="1"
+                placeholder="请输入每单可使用张数"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="金额"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="cost"
+            >
+              <a-input-number
+                v-model="model.cost"
+                :min="1"
+                placeholder="请输入金额"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="每人可领取张数"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              :min="1"
+              prop="klqzs"
+            >
+              <a-input-number
+                v-model="model.klqzs"
+                placeholder="请输入可领取张数"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="说明"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="introduce"
+            >
+              <a-input
+                v-model="model.introduce"
+                placeholder="请输入说明"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="使用说明"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="ruleDec"
+            >
+              <a-input
+                v-model="model.ruleDec"
+                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: "BusMarketCouponsCashForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    var validateConditions = (rule, value, callback) => {
+      console.log(22);
+      if (!this.model.conditions && this.model.type === 2) {
+        callback("请输入满多少元!");
+      } else {
+        callback();
+      }
+    };
+    return {
+      roomLayouts: [],
+      model: { type: 1 },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        name: [{ required: true, message: "请输入名称!" }],
+        startTime: [{ required: true, message: "请输入开始时间!" }],
+        endTime: [{ required: true, message: "请输入结束时间!" }],
+        type: [{ required: true, message: "请输入优惠条件!" }],
+        conditions: [
+          { required: true, validator: validateConditions, trigger: "change" },
+        ],
+        ksyzs: [{ required: true, message: "请输入每单可使用张数!" }],
+        cost: [{ required: true, message: "请输入金额!" }],
+        introduce: [{ required: true, message: "请输入说明!" }],
+        klqzs: [{ required: true, message: "请输入每人可领取张数!" }],
+      },
+      url: {
+        add: "/business/busMarketCouponsCash/add",
+        edit: "/business/busMarketCouponsCash/edit",
+        queryById: "/business/busMarketCouponsCash/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: {
+    handleChange(e) {
+      // this.$nextTick(() => {
+      //   this.form.validateFields(["conditions"], { force: true });
+      // });
+      if (this.model.conditions) {
+        this.$refs.form.clearValidate(["conditions"]);
+      }
+    },
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      console.log("record", record);
+      var roomLayouts = (record.roomIds || "").split(",");
+      this.model = Object.assign({}, record, { roomLayouts: roomLayouts });
+      this.visible = true;
+      getAction("/rooms/cesRoomLayout/list", { pageNo: 1, pageSize: 100 })
+        .then((res) => {
+          if (res.success) {
+            this.roomLayouts = res.result.records;
+            var data = [];
+            res.result.records.forEach((item) => {
+              data.push({ label: item.name, value: item.id });
+            });
+            this.roomLayouts = data;
+          }
+        })
+        .finally(() => {});
+    },
+    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/markets/modules/couponsCash/BusMarketCouponsCashModal.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="关闭">
+    <bus-market-coupons-cash-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-market-coupons-cash-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMarketCouponsCashForm from './BusMarketCouponsCashForm'
+  export default {
+    name: 'BusMarketCouponsCashModal',
+    components: {
+      BusMarketCouponsCashForm
+    },
+    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>

+ 145 - 0
src/views/markets/modules/couponsCash/BusMarketCouponsCashUsedGenerateForm.vue

@@ -0,0 +1,145 @@
+<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" v-show="false">
+            <a-form-model-item
+              label="免房券id"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="couponsId"
+            >
+            <a-input-number
+                v-model="model.couponsId"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="已生成数量"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <p>{{ total }}</p>
+            </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: "BusMarketCouponsCashUsedForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      total: 0,
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        //  couponsId: [
+        //     { required: true, message: '请输入免房券id!'},
+        //  ],
+        num: [{ required: true, message: "请输入生成数量!" }],
+      },
+      url: {
+        add: "/business/busMarketCouponsCashUsed/generate",
+        edit: "/business/busMarketCouponsCashUsed/edit",
+        queryById: "/business/busMarketCouponsCashUsed/queryById",
+      },
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    add(total, couponsId) {
+      this.total = total;
+      this.modelDefault.couponsId = couponsId;
+      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/markets/modules/couponsCash/BusMarketCouponsCashUsedGenerateFormModal.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="关闭">
+    <bus-market-coupons-cash-used-generate-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-market-coupons-cash-used-generate-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMarketCouponsCashUsedGenerateForm from './BusMarketCouponsCashUsedGenerateForm'
+  export default {
+    name: 'BusMarketCouponsCashUsedGenerateFormModal',
+    components: {
+      BusMarketCouponsCashUsedGenerateForm
+    },
+    data () {
+      return {
+        title:'',
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add (total,couponsId) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add(total,couponsId);
+        })
+      },
+      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>

+ 61 - 25
src/views/markets/modules/Provide/UserList.vue

@@ -6,8 +6,13 @@
         <a-row :gutter="24">
           <a-col :span="6">
             <a-form-item label="">
+              <j-input placeholder="券号" v-model="queryParam.code"></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
               <j-input
-                placeholder="会员名称"
+                placeholder="姓名"
                 v-model="queryParam.user_name"
               ></j-input>
             </a-form-item>
@@ -15,11 +20,26 @@
           <a-col :span="6">
             <a-form-item label="">
               <j-input
-                placeholder="会员手机号"
+                placeholder="手机号"
                 v-model="queryParam.mobile"
               ></j-input>
             </a-form-item>
           </a-col>
+          <a-col :span="4">
+            <a-form-item label="">
+              <a-select
+                v-model="queryParam.status"
+                style="width: 120px"
+                placeholder="请选择状态"
+                :allowClear="true"
+              >
+                <a-select-option value="0">未领取</a-select-option>
+                <a-select-option value="1">已领取</a-select-option>
+                <a-select-option value="2">已使用</a-select-option>
+                <a-select-option value="3">已作废</a-select-option>
+              </a-select>
+            </a-form-item>
+          </a-col>
           <a-col :md="6" :sm="8">
             <span
               style="float: left; overflow: hidden"
@@ -28,15 +48,26 @@
               <a-button type="primary" @click="searchQuery" icon="search"
                 >查询</a-button
               >
-
+              <a-button
+                type="primary"
+                @click="searchReset"
+                icon="reload"
+                style="margin-left: 8px"
+                >重置</a-button
+              >
               <a-button
                 @click="handleAdd"
+                type="danger"
+                style="margin-left: 8px"
+                >生成优惠券</a-button
+              >
+              <a-button
                 type="primary"
-                icon="plus"
+                icon="delete"
                 style="margin-left: 8px"
-                >发放</a-button
+                @click="batchDel"
+                >批量删除</a-button
               >
-
             </span>
           </a-col>
         </a-row>
@@ -96,15 +127,17 @@
         </template>
 
         <span slot="action" slot-scope="text, record">
-          <a v-if="record.statusName!=='已作废'" @click="handleEdit(record)">作废</a>
+          <a v-if="record.statusName !== '已作废'" @click="handleEdit(record)"
+            >作废</a
+          >
         </span>
       </a-table>
     </div>
 
-    <!-- <bus-market-coupons-used-generate-form-modal
+    <bus-market-coupons-cash-used-generate-form-modal
       ref="modalForm"
       @ok="modalFormOk"
-    ></bus-market-coupons-used-generate-form-modal> -->
+    ></bus-market-coupons-cash-used-generate-form-modal>
   </a-card>
 </template>
 
@@ -112,14 +145,14 @@
 import "@/assets/less/TableExpand.less";
 import { mixinDevice } from "@/utils/mixin";
 import { JeecgListMixin } from "@/mixins/JeecgListMixin";
-// import BusMarketCouponsUsedGenerateFormModal from "./BusMarketCouponsUsedGenerateFormModal";
+import BusMarketCouponsCashUsedGenerateFormModal from "./BusMarketCouponsCashUsedGenerateFormModal";
 import { httpAction, getAction } from "@/api/manage";
 
 export default {
   name: "BusMarketCouponsUsedList",
   mixins: [JeecgListMixin, mixinDevice],
   components: {
-    // BusMarketCouponsUsedGenerateFormModal,
+    BusMarketCouponsCashUsedGenerateFormModal,
   },
   props: {
     couponsId: {
@@ -172,17 +205,17 @@ export default {
           title: "领取时间",
           align: "center",
           dataIndex: "gainTime",
-          customRender: function (text) {
-            return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
-          },
+          // customRender: function (text) {
+          //   return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
+          // },
         },
         {
           title: "使用时间",
           align: "center",
           dataIndex: "usedTime",
-          customRender: function (text) {
-            return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
-          },
+          // customRender: function (text) {
+          //   return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
+          // },
         },
         {
           title: "状态",
@@ -194,16 +227,17 @@ export default {
           dataIndex: "action",
           align: "center",
           fixed: "right",
-          width: 147,
+          width: 80,
           scopedSlots: { customRender: "action" },
         },
       ],
       url: {
-        list: "/business/busMarketCouponsUsed/list?couponsId=" + this.couponsId,
-        delete: "/business/busMarketCouponsUsed/delete",
-        deleteBatch: "/business/busMarketCouponsUsed/deleteBatch",
-        exportXlsUrl: "/business/busMarketCouponsUsed/exportXls",
-        importExcelUrl: "business/busMarketCouponsUsed/importExcel",
+        list:
+          "/business/busMarketCouponsCashUsed/list?couponsId=" + this.couponsId,
+        delete: "/business/busMarketCouponsCashUsed/delete",
+        deleteBatch: "/business/busMarketCouponsCashUsed/deleteBatch",
+        exportXlsUrl: "/business/busMarketCouponsCashUsed/exportXls",
+        importExcelUrl: "business/busMarketCouponsCashUsed/importExcel",
       },
       dictOptions: {},
       superFieldList: [],
@@ -225,7 +259,7 @@ export default {
         content: "是否作废?",
         onOk: function () {
           httpAction(
-            "/business/busMarketCouponsUsed/voided",
+            "/business/busMarketCouponsCashUsed/voided",
             { id: item.id },
             "put"
           )
@@ -310,7 +344,9 @@ export default {
       this.superFieldList = fieldList;
     },
     handleAdd() {
-
+      this.$refs.modalForm.add(this.ipagination.total, this.couponsId);
+      this.$refs.modalForm.title = "优惠券生成";
+      this.$refs.modalForm.disableSubmit = false;
     },
   },
 };

+ 64 - 0
src/views/markets/modules/couponsCash/BusMarketCouponsCashUsedListModal.vue

@@ -0,0 +1,64 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭1">
+    <bus-market-coupons-cash-used-list :couponsId="couponsId" ref="modalCouponsCashUsedListModal"></bus-market-coupons-cash-used-list>
+  </j-modal>
+</template>
+
+<script>
+  import BusMarketCouponsCashUsedList from "./BusMarketCouponsCashUsedList";
+  export default {
+    name: 'BusMarketCouponsCashUsedListModal',
+    components: {
+      BusMarketCouponsCashUsedList
+    },
+    props: {
+      couponsId: {
+        type: String,
+        default: ''
+      }
+    },
+    data () {
+      return {
+        title:'',
+        width:1200,
+        visible: false,
+        disableSubmit: false,
+        // eventId:'',
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.modalCouponsCashUsedListModal.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.modalCouponsCashUsedListModal.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>

+ 352 - 0
src/views/markets/modules/couponsProvide/BusMemberCardList.vue

@@ -0,0 +1,352 @@
+<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-form-item label="">
+              <j-input
+                placeholder="会员名称"
+                v-model="queryParam.name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <j-input
+                placeholder="会员手机号"
+                v-model="queryParam.mobile"
+              ></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-input-number
+                style="margin-left: 8px"
+                v-model="num"
+                :min="1"
+                :max="10"
+              />
+              <a-button
+                @click="handleAdd"
+                type="danger"
+                :disabled="selectedRowKeys.length <= 0"
+                >发放</a-button
+              > -->
+              <a-input-search
+                style="width: 200px; margin-left: 8px"
+                placeholder="请输入每人发放张数"
+                enter-button="发放"
+                v-model="num"
+                type="danger"
+                :disabled="selectedRowKeys.length <= 0"
+                @search="handleAdd"
+              />
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="avatar" slot-scope="text">
+          <a-avatar v-if="text" :src="text" />
+          <a-avatar v-else icon="user" />
+        </template>
+        <template slot="imgSlot" slot-scope="text, record">
+          <span v-if="!text" style="font-size: 12px; font-style: italic"
+            >无图片</span
+          >
+          <img
+            v-else
+            :src="getImgView(text)"
+            :preview="record.id"
+            height="25px"
+            alt=""
+            style="max-width: 80px; font-size: 12px; font-style: italic"
+          />
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px; font-style: italic"
+            >无文件</span
+          >
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)"
+          >
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm
+                  title="确定删除吗?"
+                  @confirm="() => handleDelete(record.id)"
+                >
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+      </a-table>
+    </div>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import { httpAction } from "@/api/manage";
+export default {
+  name: "BusMemberCardList",
+  mixins: [JeecgListMixin, mixinDevice],
+  props: {
+    couponsId: {
+      type: String,
+      default: "",
+    },
+    couponsType: {
+      type: Number,
+      default: 1,
+    },
+  },
+  data() {
+    const hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+    return {
+      hotelId: "",
+      num: 1,
+      description: "bus_member_card管理页面",
+      // 表头
+      columns: [
+        {
+          title: "商家",
+          align: "center",
+          dataIndex: "hotelName",
+        },
+        {
+          title: "头像",
+          align: "center",
+          dataIndex: "avatar",
+          scopedSlots: { customRender: "avatar" },
+        },
+        {
+          title: "会员姓名",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "手机号",
+          align: "center",
+          dataIndex: "mobile",
+        },
+        {
+          title: "性别",
+          align: "center",
+          dataIndex: "sex",
+          customRender: function (text) {
+            return text === 1 ? "男" : "女";
+          },
+        },
+        {
+          title: "会员卡号",
+          align: "center",
+          dataIndex: "cardNo",
+        },
+        {
+          title: "等级类型",
+          align: "center",
+          dataIndex: "gradeName",
+        },
+        {
+          title: "证件号",
+          align: "center",
+          dataIndex: "certificateNo",
+        },
+        {
+          title: "推荐员工",
+          align: "center",
+          dataIndex: "staffId",
+        },
+        {
+          title: "可用积分",
+          align: "center",
+          dataIndex: "integral",
+        },
+        {
+          title: "可用余额",
+          align: "center",
+          dataIndex: "balance",
+        },
+        // {
+        //   title: '操作',
+        //   dataIndex: 'action',
+        //   align:"center",
+        //   fixed:"right",
+        //   width:147,
+        //   scopedSlots: { customRender: 'action' }
+        // }
+      ],
+      url: {
+        list:
+          hotelInfo && hotelInfo.id
+            ? "/business/busMemberCard/list?hotelId=" + hotelInfo.id
+            : "/business/busMemberCard/list",
+        delete: "/business/busMemberCard/delete",
+        deleteBatch: "/business/busMemberCard/deleteBatch",
+        exportXlsUrl: "/business/busMemberCard/exportXls",
+        importExcelUrl: "business/busMemberCard/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    };
+  },
+  created() {
+    this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    handleAdd() {
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return;
+      }
+      if (this.num <= 0) {
+        this.$message.warning("发放数量不能小于0!");
+        return;
+      }
+      var that = this;
+      that.confirmLoading = true;
+      var url = "/business/busMarketCouponsUsed/gainCouponsUsedToMember";
+      if (this.couponsType === 2) {
+        url = "/business/busMarketCouponsCashUsed/gainCouponsCashUsedToMember";
+      }
+      httpAction(
+        url,
+        {
+          couponsId: this.couponsId,
+          num: this.num,
+          memberIds: this.selectedRowKeys,
+        },
+        "post"
+      )
+        .then((res) => {
+          if (res.success) {
+            that.$message.success(res.message);
+            that.$emit("ok");
+          } else {
+            that.$message.warning(res.message);
+          }
+        })
+        .finally(() => {
+          that.confirmLoading = false;
+        });
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({ type: "string", value: "tenantId", text: "关联租户" });
+      fieldList.push({ type: "string", value: "hotelId", text: "关联酒店" });
+      fieldList.push({ type: "string", value: "mobile", text: "手机号" });
+      fieldList.push({ type: "string", value: "cardNo", text: "会员卡号" });
+      fieldList.push({ type: "string", value: "cardInnerNo", text: "卡内码" });
+      fieldList.push({ type: "string", value: "gradeId", text: "等级类型" });
+      fieldList.push({ type: "number", value: "memberFee", text: "会员费" });
+      fieldList.push({ type: "int", value: "payType", text: "付款类型" });
+      fieldList.push({ type: "int", value: "paymentMethod", text: "付款方式" });
+      fieldList.push({ type: "string", value: "name", text: "会员姓名" });
+      fieldList.push({ type: "string", value: "avatar", text: "头像" });
+      fieldList.push({ type: "int", value: "sex", text: "性别" });
+      fieldList.push({
+        type: "int",
+        value: "certificateType",
+        text: "证件类型",
+      });
+      fieldList.push({
+        type: "string",
+        value: "certificateNo",
+        text: "证件号",
+      });
+      fieldList.push({ type: "string", value: "address", text: "地址" });
+      fieldList.push({
+        type: "string",
+        value: "consumePassword",
+        text: "消费密码",
+      });
+      fieldList.push({ type: "int", value: "validity", text: "有效期" });
+      fieldList.push({
+        type: "date",
+        value: "validityEndTime",
+        text: "有效期截止日期",
+      });
+      fieldList.push({ type: "string", value: "remark", text: "备注" });
+      fieldList.push({ type: "string", value: "staffId", text: "推荐员工" });
+      fieldList.push({ type: "int", value: "integral", text: "可用积分" });
+      fieldList.push({ type: "number", value: "balance", text: "可用余额" });
+      this.superFieldList = fieldList;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+/deep/ .ant-input-search-button {
+  background-color: #ff4d4f;
+  border-color: #ff4d4f;
+}
+/deep/ .ant-input-search-button[disabled]:hover {
+  opacity: 0.7;
+  background-color: #ff4d4f;
+  border-color: #ff4d4f;
+}
+/deep/ .ant-input-search-button[disabled] {
+  opacity: 0.7;
+  color: #ffffff;
+}
+</style>

+ 10 - 5
src/views/markets/modules/Provide/MobileForm.vue

@@ -81,6 +81,11 @@ export default {
       default: "",
       required: true,
     },
+    couponsType: {
+      type: Number,
+      default: 1,
+      required: true,
+    },
   },
   data() {
     return {
@@ -120,11 +125,11 @@ export default {
       this.$refs.form.validate((valid) => {
         if (valid) {
           that.confirmLoading = true;
-          httpAction(
-            "/business/busMarketCouponsUsed/gainCouponsUsedToNoMember",
-            this.model,
-            "post"
-          )
+          var url = "/business/busMarketCouponsUsed/gainCouponsUsedToNoMember";
+          if (this.couponsType === 2) {
+            url = "/business/busMarketCouponsCashUsed/gainCouponsCashUsedToNoMember";
+          }
+          httpAction(url, this.model, "post")
             .then((res) => {
               if (res.success) {
                 that.$message.success(res.message);

+ 23 - 16
src/views/markets/modules/Provide/index.vue

@@ -10,15 +10,24 @@
     cancelText="关闭"
   >
     <a-card :bordered="false">
-      <a-tabs default-active-key="1">
+      <a-tabs default-active-key="1" @tabClick="tabClick">
         <a-tab-pane key="1">
           <span slot="tab"> 会员 </span>
-          <!-- <user-list :couponsId="couponsId" ref="userList"></user-list> -->
-          会员功能开发中,请体验非会员...
+          <bus-member-card-list
+            :couponsId="couponsId"
+            :couponsType="couponsType"
+            ref="busMemberCardList"
+            @ok="submitCallback"
+          ></bus-member-card-list>
         </a-tab-pane>
         <a-tab-pane key="2">
           <span slot="tab"> 非会员 </span>
-          <mobile-form :couponsId="couponsId" ref="mobileForm" @ok="submitCallback" ></mobile-form>
+          <mobile-form
+            :couponsId="couponsId"
+            :couponsType="couponsType"
+            ref="mobileForm"
+            @ok="submitCallback"
+          ></mobile-form>
         </a-tab-pane>
       </a-tabs>
     </a-card>
@@ -26,11 +35,11 @@
 </template>
 
 <script>
-import UserList from "./UserList";
+import BusMemberCardList from "./BusMemberCardList";
 import MobileForm from "./MobileForm";
 export default {
   components: {
-    UserList,
+    BusMemberCardList,
     MobileForm,
   },
   props: {
@@ -38,20 +47,18 @@ export default {
       type: String,
       default: "",
     },
+    couponsType: {
+      type: Number,
+      default: 1,
+    },
   },
   data() {
     return { title: "", width: 1200, visible: false, disableSubmit: false };
   },
   methods: {
-    // add() {
-    //   this.visible = true;
-    // },
-    // edit(record) {
-    //   this.visible = true;
-    //   this.$nextTick(() => {
-    //     this.$refs.mobileForm.edit(record);
-    //   });
-    // },
+    tabClick(e) {
+      this.disableSubmit = e !== '2';
+    },
     close() {
       this.$emit("close");
       this.visible = false;
@@ -60,7 +67,7 @@ export default {
       this.$refs.mobileForm.submitForm();
     },
     submitCallback() {
-      console.log('submitCallback')
+      console.log("submitCallback");
       this.$emit("ok");
       this.visible = false;
     },

+ 212 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsForm.vue

@@ -0,0 +1,212 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model
+        ref="form"
+        :model="model"
+        :rules="validatorRules"
+        slot="detail"
+      >
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item
+              label="名称"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="name"
+            >
+              <a-input v-model="model.name" placeholder="请输入名称"></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="餐券类型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="type"
+            >
+            <a-select
+                v-model="model.type"
+                style="width: 100%"
+                placeholder="请选择餐券类型"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in mealCouponTypeList"
+                  :key="index"
+                  :value="item.value"
+                  >{{ item.label }}</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="cost"
+            >
+              <a-input-number
+                v-model="model.cost"
+                placeholder="请输入金额"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="说明"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="introduce"
+            >
+              <a-input
+                v-model="model.introduce"
+                placeholder="请输入说明"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="消费项目"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="consumeProjectId"
+            >
+              <a-select
+                v-model="model.consumeProjectId"
+                style="width: 100%"
+                placeholder="请选择消费项目"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in stockTypeList"
+                  :key="index"
+                  :value="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: "BusMarketMealCouponsForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        name: [{ required: true, message: "请输入名称!" }],
+        type: [{ required: true, message: "请输入餐券类型!" }],
+        cost: [{ required: true, message: "请输入金额!" }],
+        introduce: [{ required: true, message: "请输入说明!" }],
+        consumeProjectId: [{ required: true, message: "请输入消费项目!" }],
+      },
+      url: {
+        add: "/business/busMarketMealCoupons/add",
+        edit: "/business/busMarketMealCoupons/edit",
+        queryById: "/business/busMarketMealCoupons/queryById",
+      },
+      stockTypeList: [],
+      mealCouponTypeList:[]
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    const hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+    if (hotelInfo) {
+      this.model.hotelId = hotelInfo.id;
+    }
+    httpAction(
+      "/rooms/cesStockType/getTopTypes",
+      { hotelId: hotelInfo.id },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.stockTypeList = res.result;
+      }
+    });
+    httpAction(
+      "/rooms/cesMealCoupon/fetch",
+      { hotelId: hotelInfo.id },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.mealCouponTypeList = res.result;
+      }
+    });
+    //备份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>

+ 145 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsGenerateForm.vue

@@ -0,0 +1,145 @@
+<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" v-show="false">
+            <a-form-model-item
+              label="免房券id"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="couponsId"
+            >
+            <a-input-number
+                v-model="model.couponsId"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="已生成数量"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <p>{{ total }}</p>
+            </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: "BusMarketMealCouponsGenerateForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      total: 0,
+      model: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        //  couponsId: [
+        //     { required: true, message: '请输入免房券id!'},
+        //  ],
+        num: [{ required: true, message: "请输入生成数量!" }],
+      },
+      url: {
+        add: "/business/busMarketMealCouponsUsed/generate",
+        edit: "/business/busMarketMealCouponsUsed/edit",
+        queryById: "/business/busMarketMealCouponsUsed/queryById",
+      },
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    add(total, couponsId) {
+      this.total = total;
+      this.modelDefault.couponsId = couponsId;
+      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/markets/modules/mealCoupons/BusMarketMealCouponsGenerateFormModal.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="关闭">
+    <bus-market-meal-coupons-generate-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-market-meal-coupons-generate-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMarketMealCouponsGenerateForm from './BusMarketMealCouponsGenerateForm'
+  export default {
+    name: 'BusMarketMealCouponsGenerateFormModal',
+    components: {
+      BusMarketMealCouponsGenerateForm
+    },
+    data () {
+      return {
+        title:'',
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add (total,couponsId) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add(total,couponsId);
+        })
+      },
+      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>

+ 84 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsModal.Style#Drawer.vue

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

+ 60 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsModal.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="关闭">
+    <bus-market-meal-coupons-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-market-meal-coupons-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMarketMealCouponsForm from './BusMarketMealCouponsForm'
+  export default {
+    name: 'BusMarketMealCouponsModal',
+    components: {
+      BusMarketMealCouponsForm
+    },
+    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>

+ 352 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedList.vue

@@ -0,0 +1,352 @@
+<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-form-item label="">
+              <j-input placeholder="券号" v-model="queryParam.code"></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <j-input
+                placeholder="姓名"
+                v-model="queryParam.user_name"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <j-input
+                placeholder="手机号"
+                v-model="queryParam.mobile"
+              ></j-input>
+            </a-form-item>
+          </a-col>
+          <a-col :span="4">
+            <a-form-item label="">
+              <a-select
+                v-model="queryParam.status"
+                style="width: 120px"
+                placeholder="请选择状态"
+                :allowClear="true"
+              >
+                <a-select-option value="0">未领取</a-select-option>
+                <a-select-option value="1">已领取</a-select-option>
+                <a-select-option value="2">已使用</a-select-option>
+                <a-select-option value="3">已作废</a-select-option>
+              </a-select>
+            </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
+              >
+              <a-button
+                @click="handleAdd"
+                type="danger"
+                style="margin-left: 8px"
+                >生成餐券</a-button
+              >
+              <a-button
+                type="primary"
+                icon="delete"
+                style="margin-left: 8px"
+                @click="batchDel"
+                >批量删除</a-button
+              >
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="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 v-if="record.statusName !== '已作废'" @click="handleEdit(record)"
+            >作废</a
+          >
+        </span>
+      </a-table>
+    </div>
+
+    <bus-market-meal-coupons-generate-form-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-market-meal-coupons-generate-form-modal>
+
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import BusMarketMealCouponsGenerateFormModal from "./BusMarketMealCouponsGenerateFormModal";
+import { httpAction, getAction } from "@/api/manage";
+
+export default {
+  name: "BusMarketCouponsUsedList",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    BusMarketMealCouponsGenerateFormModal,
+  },
+  props: {
+    couponsId: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      description: "餐券领取使用表管理页面",
+      // 表头
+      columns: [
+        {
+          title: "券号",
+          align: "center",
+          dataIndex: "code",
+        },
+        {
+          title: "餐券名称",
+          align: "center",
+          dataIndex: "couponsName",
+        },
+        {
+          title: "姓名",
+          align: "center",
+          dataIndex: "userName",
+        },
+
+        {
+          title: "房间号",
+          align: "center",
+          dataIndex: "roomNumber",
+        },
+        {
+          title: "入住单号",
+          align: "center",
+          dataIndex: "checkedInNo",
+        },
+        {
+          title: "手机号",
+          align: "center",
+          dataIndex: "mobile",
+        },
+        {
+          title: "领取时间",
+          align: "center",
+          dataIndex: "gainTime",
+          // customRender: function (text) {
+          //   return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
+          // },
+        },
+        {
+          title: "使用时间",
+          align: "center",
+          dataIndex: "usedTime",
+          // customRender: function (text) {
+          //   return !text ? "" : text.length > 10 ? text.substr(0, 10) : text;
+          // },
+        },
+        {
+          title: "状态",
+          align: "center",
+          dataIndex: "statusName",
+        },
+        // {
+        //   title: "操作",
+        //   dataIndex: "action",
+        //   align: "center",
+        //   fixed: "right",
+        //   width: 80,
+        //   scopedSlots: { customRender: "action" },
+        // },
+      ],
+      url: {
+        list:
+          "/business/busMarketMealCouponsUsed/list?couponsId=" + this.couponsId,
+        delete: "/business/busMarketMealCouponsUsed/delete",
+        deleteBatch: "/business/busMarketMealCouponsUsed/deleteBatch",
+        exportXlsUrl: "/business/busMarketMealCouponsUsed/exportXls",
+        importExcelUrl: "business/busMarketMealCouponsUsed/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    };
+  },
+  created() {
+    this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    handleEdit(item) {
+      var that = this;
+      this.$confirm({
+        title: "确认作废",
+        content: "是否作废?",
+        onOk: function () {
+          httpAction(
+            "/business/busMarketMealCouponsUsed/voided",
+            { id: item.id },
+            "put"
+          )
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                item.statusName = "已作废";
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {});
+        },
+        onCancel: function () {},
+      });
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({
+        type: "string",
+        value: "tenantId",
+        text: "关联租户",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "hotelId",
+        text: "关联酒店",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "couponsId",
+        text: "餐券id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "code",
+        text: "券号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "int",
+        value: "status",
+        text: "状态 0未领取 1已领取 2已使用 3已作废",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userid",
+        text: "会员id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userName",
+        text: "姓名",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "roomNumber",
+        text: "房间号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "checkedInNo",
+        text: "入住单号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "mobile",
+        text: "手机号",
+        dictCode: "",
+      });
+      fieldList.push({ type: "date", value: "gainTime", text: "领取时间" });
+      fieldList.push({ type: "date", value: "usedTime", text: "使用时间" });
+      this.superFieldList = fieldList;
+    },
+    handleAdd() {
+      this.$refs.modalForm.add(this.ipagination.total, this.couponsId);
+      this.$refs.modalForm.title = "优惠券生成";
+      this.$refs.modalForm.disableSubmit = false;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 64 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedListModal.vue

@@ -0,0 +1,64 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <bus-market-meal-coupons-used-list :couponsId="couponsId" ref="modalMealCouponsUsedListModal"></bus-market-meal-coupons-used-list>
+  </j-modal>
+</template>
+
+<script>
+  import BusMarketMealCouponsUsedList from "./BusMarketMealCouponsUsedList";
+  export default {
+    name: 'BusMarketCouponsCashUsedListModal',
+    components: {
+      BusMarketMealCouponsUsedList
+    },
+    props: {
+      couponsId: {
+        type: String,
+        default: ''
+      }
+    },
+    data () {
+      return {
+        title:'',
+        width:1200,
+        visible: false,
+        disableSubmit: false,
+        // eventId:'',
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.modalMealCouponsUsedListModal.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.modalMealCouponsUsedListModal.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>

+ 276 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedVerify.vue

@@ -0,0 +1,276 @@
+<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-form-item label="">
+              <a-input placeholder="房间号" v-model="queryParam.roomNumber"></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 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 -->
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="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
+          >
+        </span>
+      </a-table>
+    </div>
+
+    <!-- <bus-market-meal-coupons-generate-form-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-market-meal-coupons-generate-form-modal> -->
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+// import BusMarketMealCouponsGenerateFormModal from "./BusMarketMealCouponsGenerateFormModal";
+import { httpAction, getAction } from "@/api/manage";
+
+export default {
+  name: "BusMarketCouponsUsedList",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    // BusMarketMealCouponsGenerateFormModal,
+  },
+  props: {
+    couponsId: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      description: "餐券领取使用表管理页面",
+      // 表头
+      columns: [
+        {
+          title: "券号",
+          align: "center",
+          dataIndex: "code",
+        },
+        {
+          title: "餐券名称",
+          align: "center",
+          dataIndex: "couponsName",
+        },
+        {
+          title: "金额",
+          align: "center",
+          dataIndex: "cost",
+        },
+        {
+          title: "房间号",
+          align: "center",
+          dataIndex: "roomNumber",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 80,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list: "/business/busMarketMealCouponsUsed/list?status=1",
+        delete: "/business/busMarketMealCouponsUsed/delete",
+        deleteBatch: "/business/busMarketMealCouponsUsed/deleteBatch",
+        exportXlsUrl: "/business/busMarketMealCouponsUsed/exportXls",
+        importExcelUrl: "business/busMarketMealCouponsUsed/importExcel",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    };
+  },
+  created() {
+    this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    handleEdit(item) {
+      var that = this;
+      this.$confirm({
+        title: "确认核销",
+        content: "是否核销?",
+        onOk: function () {
+          httpAction(
+            "/business/busMarketMealCouponsUsed/verify",
+            { id: item.id },
+            "post"
+          )
+            .then((res) => {
+              if (res.success) {
+                that.$message.success(res.message);
+                that.reCalculatePage(1)
+                that.loadData();
+                that.$emit('fatherLoadData');
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {});
+        },
+        onCancel: function () {},
+      });
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({
+        type: "string",
+        value: "tenantId",
+        text: "关联租户",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "hotelId",
+        text: "关联酒店",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "couponsId",
+        text: "餐券id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "code",
+        text: "券号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "int",
+        value: "status",
+        text: "状态 0未领取 1已领取 2已使用 3已作废",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userid",
+        text: "会员id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userName",
+        text: "姓名",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "roomNumber",
+        text: "房间号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "checkedInNo",
+        text: "入住单号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "mobile",
+        text: "手机号",
+        dictCode: "",
+      });
+      fieldList.push({ type: "date", value: "gainTime", text: "领取时间" });
+      fieldList.push({ type: "date", value: "usedTime", text: "使用时间" });
+      this.superFieldList = fieldList;
+    },
+    handleAdd() {
+      this.$refs.modalForm.add(this.ipagination.total, this.couponsId);
+      this.$refs.modalForm.title = "优惠券生成";
+      this.$refs.modalForm.disableSubmit = false;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 71 - 0
src/views/markets/modules/mealCoupons/BusMarketMealCouponsUsedVerifyModal.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="关闭"
+  >
+    <bus-market-meal-coupons-used-verify
+      @fatherLoadData="fatherLoadData"
+      ref="modalMarketMealCouponsUsedVerifyModal"
+    ></bus-market-meal-coupons-used-verify>
+  </j-modal>
+</template>
+
+<script>
+import BusMarketMealCouponsUsedVerify from "./BusMarketMealCouponsUsedVerify";
+export default {
+  name: "BusMarketCouponsCashUsedListModal",
+  components: {
+    BusMarketMealCouponsUsedVerify,
+  },
+  props: {
+    couponsId: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      title: "",
+      width: 1200,
+      visible: false,
+      disableSubmit: false,
+      // eventId:'',
+    };
+  },
+  methods: {
+    fatherLoadData() {
+      console.log(1)
+      this.$emit("fatherLoadData");
+    },
+    add() {
+      this.visible = true;
+    },
+    edit(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.modalMarketMealCouponsUsedVerifyModal.edit(record);
+      });
+    },
+    close() {
+      this.$emit("close");
+      this.visible = false;
+    },
+    handleOk() {
+      this.$refs.modalMarketMealCouponsUsedVerifyModal.submitForm();
+    },
+    submitCallback() {
+      this.$emit("ok");
+      this.visible = false;
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

+ 181 - 0
src/views/markets/modules/meetingRoom/BusMeetingRoomForm.vue

@@ -0,0 +1,181 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-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="spec">
+              <a-input v-model="model.spec" placeholder="请输入规格"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="面积" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="area">
+              <a-input-number v-model="model.area" placeholder="请输入面积" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="人数" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="number">
+              <a-input-number v-model="model.number" placeholder="请输入人数" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="管理员姓名" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="adminName">
+              <a-input v-model="model.adminName" placeholder="请输入管理员姓名"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="地址" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="address">
+              <a-input v-model="model.address" placeholder="请输入地址"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="设备" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="facility">
+              <a-input v-model="model.facility" placeholder="请输入设备"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="排序" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="sort">
+              <a-input-number v-model="model.sort" placeholder="请输入排序" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="描述" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
+              <a-textarea v-model="model.remark" rows="4" placeholder="请输入描述" />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'BusMeetingRoomForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        confirmLoading: false,
+        validatorRules: {
+           tenantId: [
+              { required: true, message: '请输入关联租户!'},
+           ],
+           hotelId: [
+              { required: true, message: '请输入关联酒店!'},
+           ],
+           name: [
+              { required: true, message: '请输入名称!'},
+           ],
+           spec: [
+              { required: true, message: '请输入规格!'},
+           ],
+           area: [
+              { required: true, message: '请输入面积!'},
+           ],
+           number: [
+              { required: true, message: '请输入人数!'},
+           ],
+           adminName: [
+              { required: true, message: '请输入管理员姓名!'},
+           ],
+           address: [
+              { required: true, message: '请输入地址!'},
+           ],
+           facility: [
+              { required: true, message: '请输入设备!'},
+           ],
+           sort: [
+              { required: true, message: '请输入排序!'},
+           ],
+           status: [
+              { required: true, message: '请输入状态!'},
+           ],
+        },
+        url: {
+          add: "/business/busMeetingRoom/add",
+          edit: "/business/busMeetingRoom/edit",
+          queryById: "/business/busMeetingRoom/queryById"
+        }
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+      var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      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>

+ 84 - 0
src/views/markets/modules/meetingRoom/BusMeetingRoomModal.Style#Drawer.vue

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

+ 60 - 0
src/views/markets/modules/meetingRoom/BusMeetingRoomModal.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="关闭">
+    <bus-meeting-room-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-meeting-room-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMeetingRoomForm from './BusMeetingRoomForm'
+  export default {
+    name: 'BusMeetingRoomModal',
+    components: {
+      BusMeetingRoomForm
+    },
+    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>

+ 400 - 0
src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleConfirm.vue

@@ -0,0 +1,400 @@
+<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="24">
+            <a-divider orientation="left">档期</a-divider></a-col
+          >
+          <a-col :span="6">
+            <a-form-item label="">
+              <a-select
+                v-model="model.detail.meetingRoomId"
+                style="width: 100%"
+                placeholder="会议室"
+                disabled
+              >
+                <a-select-option
+                  v-for="(item, index) in meetingRoomList"
+                  :key="index"
+                  :value="item.id"
+                  >{{ item.name }}</a-select-option
+                >
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <j-date
+                disabled
+                placeholder="请选择开始时间"
+                v-model="model.detail.meetingDate"
+                style="width: 100%"
+              />
+            </a-form-item>
+          </a-col>
+          <a-col :span="6">
+            <a-form-item label="">
+              <a-select
+                disabled
+                v-model="model.detail.timeSpan"
+                style="width: 100%"
+                placeholder="会议室"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in timeSpanList"
+                  :key="index"
+                  :value="item.id"
+                  >{{ item.name }}</a-select-option
+                >
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <span
+              style="float: left; overflow: hidden"
+              class="table-page-search-submitButtons"
+            >
+            <!--先不实现增加预定功能-->
+              <!-- <a-button v-if="model.roomSchedule.billStatus==0"
+                @click="handleAdd"
+                type="danger"
+                style="margin-left: 8px"
+                >增加预定</a-button
+              > -->
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+    <a-divider orientation="left">档期</a-divider>
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        class="j-table-force-nowrap"
+      >
+        <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="handleDetail(record)">全部档期</a>
+          <a-divider type="vertical" />
+          <template v-if="record.status != 0 && record.billStatus == 0">
+            <a @click="handleSettle(record)">结账</a>
+            <a-divider type="vertical"
+          /></template>
+          <template v-if="record.status == 0">
+          <a @click="handleEdit(record)">修改</a>
+          <a-divider type="vertical" /></template>
+          <template v-if="record.status == 0">
+            <a @click="batchConfirm(record)">确认</a>
+            <a-divider type="vertical" />
+          </template>
+          <a v-if="record.status == 0" @click="handleEdit(record)">删除</a>
+        </span>
+      </a-table>
+    </div>
+    <bus-meeting-room-schedule-edit-modal
+      ref="modalForm"
+      @ok="modalFormOk2($event)"
+    ></bus-meeting-room-schedule-edit-modal>
+    <meeting-room-schedule-detail-modal
+      ref="modalMeetingRoomScheduleDetail"
+      :meetingRoomScheduleId="meetingRoomScheduleId"
+      @ok="modalFormOk"
+    ></meeting-room-schedule-detail-modal>
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+import BusMeetingRoomScheduleEditModal from "./BusMeetingRoomScheduleEditModal";
+import meetingRoomScheduleDetailModal from "./meetingRoomScheduleDetail/meetingRoomScheduleDetailModal";
+
+import { httpAction, getAction, postAction } from "@/api/manage";
+
+export default {
+  name: "BusMarketCouponsUsedList",
+  // mixins: [ mixinDevice],
+  components: {
+    BusMeetingRoomScheduleEditModal,
+    meetingRoomScheduleDetailModal,
+  },
+  props: {
+    couponsId: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      meetingRoomScheduleId: "",
+      description: "",
+      model: {
+        detail: { meetingRoomId: "", meetingDate: "", meetingDatev: "" },
+      },
+      dataSource: [],
+      // 表头
+      columns: [
+        {
+          title: "会议主题",
+          align: "center",
+          dataIndex: "theme",
+        },
+        {
+          title: "公司名称",
+          align: "center",
+          dataIndex: "name",
+        },
+        {
+          title: "预定人",
+          align: "center",
+          dataIndex: "destinedName",
+        },
+
+        {
+          title: "联系电话",
+          align: "center",
+          dataIndex: "mobile",
+        },
+        {
+          title: "账单状态",
+          align: "center",
+          dataIndex: "billStatus",
+          customRender: function (text) {
+            var msg = "未结账";
+            if (text == 1) {
+              msg = "已挂账";
+            } else if (text == 2) {
+              msg = "已结账";
+            }
+            return msg;
+          },
+        },
+        {
+          title: "备注",
+          align: "center",
+          dataIndex: "gainTime",
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 80,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        confirmBatch: "/business/busMeetingRoomScheduleDetail/confirmBatchByMeetingRoomScheduleId",
+      },
+      dictOptions: {},
+      superFieldList: [],
+      meetingRoomList: [],
+      timeSpanList: [
+        { id: 1, name: "上午" },
+        { id: 2, name: "下午" },
+        { id: 3, name: "晚上" },
+      ],
+    };
+  },
+  created() {
+    getAction("/business/busMeetingRoom/list", {
+      pageNo: 1,
+      pageSize: 100,
+      stauts: 1,
+    }).then((res) => {
+      if (res.success) {
+        this.meetingRoomList = res.result.records;
+      }
+    });
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    handleSettle(){
+      this.$message.error("结账功能暂无实现");
+    },
+    handleAdd(){
+
+    },
+    batchConfirm(record) {
+      if (!this.url.confirmBatch) {
+        this.$message.error("请设置url.confirmBatch!");
+        return;
+      }
+
+      var that = this;
+      that.loading = true;
+      postAction(that.url.confirmBatch, {
+        id: record.id,
+      })
+        .then((res) => {
+          if (res.success) {
+            that.$message.success(res.message);
+            that.dataSource = [
+              Object.assign({}, that.model.roomSchedule, {
+                status: 1,
+              }),
+            ];
+            that.$emit("ok");
+          } else {
+            that.$message.warning(res.message);
+          }
+        })
+        .finally(() => {
+          that.loading = false;
+        });
+    },
+    modalFormOk2(record) {
+      console.log("record", record);
+      this.dataSource = [Object.assign({}, record)];
+      this.$emit("ok");
+    },
+    modalFormOk(){
+
+    },
+    add() {
+      this.edit(this.modelDefault);
+    },
+    edit(record) {
+      this.model = Object.assign({}, record);
+      delete this.model.roomSchedule.createTime;
+      this.dataSource = [
+        Object.assign({}, this.model.roomSchedule, {
+          status: this.model.detail.status,
+        }),
+      ];
+      this.visible = true;
+    },
+    handleEdit(record) {
+      this.$refs.modalForm.edit(record);
+      this.$refs.modalForm.title = "编辑";
+      this.$refs.modalForm.disableSubmit = false;
+    },
+    handleDetail(record) {
+      console.log("record", record);
+      this.meetingRoomScheduleId = record.id;
+      this.$refs.modalMeetingRoomScheduleDetail.add(record);
+      this.$refs.modalMeetingRoomScheduleDetail.title = "档期列表预定确认";
+      this.$refs.modalMeetingRoomScheduleDetail.disableSubmit = true;
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({
+        type: "string",
+        value: "tenantId",
+        text: "关联租户",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "hotelId",
+        text: "关联酒店",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "couponsId",
+        text: "免房券id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "code",
+        text: "券号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "int",
+        value: "status",
+        text: "状态 0未领取 1已领取 2已使用 3已作废",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userid",
+        text: "会员id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userName",
+        text: "姓名",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "roomNumber",
+        text: "房间号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "checkedInNo",
+        text: "入住单号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "mobile",
+        text: "手机号",
+        dictCode: "",
+      });
+      fieldList.push({ type: "date", value: "gainTime", text: "领取时间" });
+      fieldList.push({ type: "date", value: "usedTime", text: "使用时间" });
+      this.superFieldList = fieldList;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 66 - 0
src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleConfirmModal.vue

@@ -0,0 +1,66 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
+    @cancel="handleCancel"
+    cancelText="关闭"
+  >
+    <bus-meeting-room-schedule-confirm
+      ref="modalBusMeetingRoomScheduleConfirmModal"
+      @ok="submitCallback"
+    ></bus-meeting-room-schedule-confirm>
+  </j-modal>
+</template>
+
+<script>
+import BusMeetingRoomScheduleConfirm from "./BusMeetingRoomScheduleConfirm";
+export default {
+  name: "BusMarketCouponsCashUsedListModal",
+  components: {
+    BusMeetingRoomScheduleConfirm,
+  },
+  props: {
+    couponsId: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      title: "",
+      width: 1200,
+      visible: false,
+      disableSubmit: false,
+      // eventId:'',
+    };
+  },
+  methods: {
+    add() {
+      this.visible = true;
+    },
+    edit(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.modalBusMeetingRoomScheduleConfirmModal.edit(record);
+      });
+    },
+    close() {
+      this.$emit("close");
+      this.visible = false;
+    },
+    handleOk() {
+      this.$refs.modalBusMeetingRoomScheduleConfirmModal.submitForm();
+    },
+    submitCallback() {
+      this.$emit("ok");
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

+ 227 - 0
src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleEditForm.vue

@@ -0,0 +1,227 @@
+<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="theme"
+            >
+              <a-input
+                v-model="model.theme"
+                placeholder="请输入会议主题"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="预定人姓名"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="destinedName"
+            >
+              <a-input
+                v-model="model.destinedName"
+                placeholder="请输入预定人姓名"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="联系电话"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="mobile"
+            >
+              <a-input
+                v-model="model.mobile"
+                placeholder="请输入联系电话"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="备注"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="remark"
+            >
+              <a-textarea
+                v-model="model.remark"
+                rows="4"
+                placeholder="请输入备注"
+              />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+export default {
+  name: "BusMeetingRoomForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: { detailList: [{}] },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      labelCol2: {
+        xs: { span: 7 },
+        sm: { span: 10 },
+      },
+      wrapperCol2: {
+        xs: { span: 7 },
+        sm: { span: 11 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        name: [{ required: true, message: "请输入名称!" }],
+        theme: [{ required: true, message: "请输入会议主题!" }],
+        destinedName: [{ required: true, message: "请输入预定人姓名!" }],
+        mobile: [{ required: true, message: "请输入联系电话!" }],
+      },
+      url: {
+        add: "/business/busMeetingRoomSchedule/create",
+        edit: "/business/busMeetingRoomSchedule/edit",
+        queryById: "/business/busMeetingRoomSchedule/queryById",
+      },
+      meetingRoomList: [],
+      timeSpanList: [
+        { id: 1, name: "上午" },
+        { id: 2, name: "下午" },
+        { id: 3, name: "晚上" },
+      ],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    getAction("/business/busMeetingRoom/list", {
+      pageNo: 1,
+      pageSize: 100,
+      stauts: 1,
+    }).then((res) => {
+      if (res.success) {
+        this.meetingRoomList = res.result.records;
+      }
+    });
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    puls() {
+      this.model.detailList.push({ });
+    },
+    remove(index) {
+      this.model.detailList.splice(index, 1);
+    },
+    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);
+                console.log(1)
+                that.$emit("ok",this.model);
+                // that.$parent.modalFormOk2(this.model);
+              } else {
+                that.$message.warning(res.message);
+              }
+            })
+            .finally(() => {
+              that.confirmLoading = false;
+            });
+        }
+      });
+    },
+  },
+};
+</script>
+<style scoped>
+.dynamic-delete-button {
+  cursor: pointer;
+  position: relative;
+  top: 10px;
+  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/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleEditModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk($event)"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <bus-meeting-room-schedule-edit-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-meeting-room-schedule-edit-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMeetingRoomScheduleEditForm from './BusMeetingRoomScheduleEditForm'
+  export default {
+    name: 'BusMeetingRoomModal',
+    components: {
+      BusMeetingRoomScheduleEditForm
+    },
+    data () {
+      return {
+        title:'',
+        width:1000,
+        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($event){
+        this.$emit('ok',$event);
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>

+ 324 - 0
src/views/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleForm.vue

@@ -0,0 +1,324 @@
+<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="theme"
+            >
+              <a-input
+                v-model="model.theme"
+                placeholder="请输入会议主题"
+              ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="预定人姓名"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="destinedName"
+            >
+              <a-input
+                v-model="model.destinedName"
+                placeholder="请输入预定人姓名"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="联系电话"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="mobile"
+            >
+              <a-input
+                v-model="model.mobile"
+                placeholder="请输入联系电话"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="备注"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="remark"
+            >
+              <a-textarea
+                v-model="model.remark"
+                rows="4"
+                placeholder="请输入备注"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-divider orientation="left">档期</a-divider>
+          </a-col>
+          <template v-for="(item, index) in model.detailList">
+            <a-col :span="7">
+              <a-form-model-item
+                label="会议室名称"
+                :labelCol="labelCol2"
+                :wrapperCol="wrapperCol2"
+                :prop="`detailList[${index}].meetingRoomId`"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请选择会议室!',
+                    trigger: 'change',
+                  },
+                ]"
+              >
+                <a-select
+                  v-model="item.meetingRoomId"
+                  style="width: 100%"
+                  placeholder="会议室"
+                  :allowClear="true"
+                >
+                  <a-select-option
+                    v-for="(item, index) in meetingRoomList"
+                    :key="index"
+                    :value="item.id"
+                    >{{ item.name }}</a-select-option
+                  >
+                </a-select>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="7">
+              <a-form-model-item
+                label="开会日期"
+                :labelCol="labelCol2"
+                :wrapperCol="wrapperCol2"
+                :prop="`detailList[${index}].meetingDate`"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请选择开会日期!',
+                    trigger: 'change',
+                  },
+                ]"
+              >
+                <j-date
+                  placeholder="请选择开始时间"
+                  v-model="item.meetingDate"
+                  style="width: 100%"
+                />
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="7">
+              <a-form-model-item
+                label="开会时段"
+                :labelCol="labelCol2"
+                :wrapperCol="wrapperCol2"
+                :prop="`detailList[${index}].timeSpan`"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请选择开会时段!',
+                    trigger: 'change',
+                  },
+                ]"
+              >
+                <a-select
+                  v-model="item.timeSpan"
+                  style="width: 100%"
+                  placeholder="会议室"
+                  :allowClear="true"
+                >
+                  <a-select-option
+                    v-for="(item, index) in timeSpanList"
+                    :key="index"
+                    :value="item.id"
+                    >{{ item.name }}</a-select-option
+                  >
+                </a-select>
+              </a-form-model-item>
+            </a-col>
+            <a-col :span="2">
+              <a-icon
+                v-if="model.detailList.length - 1 == index"
+                type="plus-circle"
+                class="dynamic-delete-button"
+                @click="puls()"
+              />
+              <a-icon
+                type="minus-circle"
+                style="color: #f56c6c"
+                class="dynamic-delete-button"
+                v-if="model.detailList.length > 1"
+                @click="() => remove(index)"
+              />
+            </a-col>
+          </template>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+export default {
+  name: "BusMeetingRoomForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: { detailList: [{}] },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      labelCol2: {
+        xs: { span: 7 },
+        sm: { span: 10 },
+      },
+      wrapperCol2: {
+        xs: { span: 7 },
+        sm: { span: 11 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        name: [{ required: true, message: "请输入名称!" }],
+        theme: [{ required: true, message: "请输入会议主题!" }],
+        destinedName: [{ required: true, message: "请输入预定人姓名!" }],
+        mobile: [{ required: true, message: "请输入联系电话!" }],
+      },
+      url: {
+        add: "/business/busMeetingRoomSchedule/create",
+        edit: "/business/busMeetingRoomSchedule/edit",
+        queryById: "/business/busMeetingRoomSchedule/queryById",
+      },
+      meetingRoomList: [],
+      timeSpanList: [
+        { id: 1, name: "上午" },
+        { id: 2, name: "下午" },
+        { id: 3, name: "晚上" },
+      ],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    getAction("/business/busMeetingRoom/list", {
+      pageNo: 1,
+      pageSize: 100,
+      stauts: 1,
+    }).then((res) => {
+      if (res.success) {
+        this.meetingRoomList = res.result.records;
+      }
+    });
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    puls() {
+      this.model.detailList.push({ });
+    },
+    remove(index) {
+      this.model.detailList.splice(index, 1);
+    },
+    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>
+<style scoped>
+.dynamic-delete-button {
+  cursor: pointer;
+  position: relative;
+  top: 10px;
+  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/markets/modules/meetingRoomSchedule/BusMeetingRoomScheduleModal.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="关闭">
+    <bus-meeting-room-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-meeting-room-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMeetingRoomForm from './BusMeetingRoomScheduleForm'
+  export default {
+    name: 'BusMeetingRoomModal',
+    components: {
+      BusMeetingRoomForm
+    },
+    data () {
+      return {
+        title:'',
+        width:1000,
+        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>

+ 310 - 0
src/views/markets/modules/meetingRoomSchedule/meetingRoomScheduleDetail/meetingRoomScheduleDetailList.vue

@@ -0,0 +1,310 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-row :gutter="24">
+        <a-col :md="6" :sm="8">
+          <span
+            style="float: left; overflow: hidden"
+            class="table-page-search-submitButtons"
+          >
+            <a-button
+              @click="batchConfirm"
+              type="danger"
+              style="margin-left: 8px"
+              >批量确认</a-button
+            >
+            <a-button type="primary" style="margin-left: 8px" @click="batchDel"
+              >批量删除</a-button
+            >
+          </span>
+        </a-col>
+      </a-row>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- table区域-begin -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{ x: true }"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{
+          selectedRowKeys: selectedRowKeys,
+          onChange: onSelectChange,
+        }"
+        class="j-table-force-nowrap"
+        @change="handleTableChange"
+      >
+        <template slot="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 v-if="record.status == 0" @click="handleEdit(record)">确认</a>
+          <a-divider type="vertical" />
+          <a @click="handleDelete(record.id)">删除</a>
+        </span>
+      </a-table>
+    </div>
+
+    <!-- <bus-market-coupons-cash-used-generate-form-modal
+      ref="modalForm"
+      @ok="modalFormOk"
+    ></bus-market-coupons-cash-used-generate-form-modal> -->
+  </a-card>
+</template>
+
+<script>
+import "@/assets/less/TableExpand.less";
+import { mixinDevice } from "@/utils/mixin";
+import { JeecgListMixin } from "@/mixins/JeecgListMixin";
+// import BusMarketCouponsCashUsedGenerateFormModal from "./BusMarketCouponsCashUsedGenerateFormModal";
+import { httpAction, postAction } from "@/api/manage";
+
+export default {
+  name: "meetingRoomScheduleDetailList",
+  mixins: [JeecgListMixin, mixinDevice],
+  components: {
+    // BusMarketCouponsCashUsedGenerateFormModal,
+  },
+  props: {
+    meetingRoomScheduleId: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      description: "免房券领取使用表管理页面",
+      // 表头
+      columns: [
+        {
+          title: "会议室",
+          align: "center",
+          dataIndex: "meetingRoomName",
+        },
+        {
+          title: "会议主题",
+          align: "center",
+          dataIndex: "theme",
+        },
+
+        {
+          title: "开会日期",
+          align: "center",
+          dataIndex: "meetingDate",
+        },
+        {
+          title: "开会时段",
+          align: "center",
+          dataIndex: "timeSpan",
+          customRender: function (text) {
+            var msg = "";
+            if (text == 1) {
+              msg = "上午";
+            } else if (text == 2) {
+              msg = "下午";
+            } else if (text == 3) {
+              msg = "晚上";
+            }
+            return msg;
+          },
+        },
+        {
+          title: "状态",
+          align: "center",
+          dataIndex: "status",
+          customRender: function (text) {
+            return text == 0 ? "未确认" : "已确认";
+          },
+        },
+        {
+          title: "操作",
+          dataIndex: "action",
+          align: "center",
+          fixed: "right",
+          width: 80,
+          scopedSlots: { customRender: "action" },
+        },
+      ],
+      url: {
+        list:
+          "/business/busMeetingRoomScheduleDetail/list?meetingRoomScheduleId=" +
+          this.meetingRoomScheduleId,
+        delete: "/business/busMeetingRoomScheduleDetail/delete",
+        deleteBatch: "/business/busMeetingRoomScheduleDetail/deleteBatch",
+        exportXlsUrl: "/business/busMeetingRoomScheduleDetail/exportXls",
+        importExcelUrl: "business/busMeetingRoomScheduleDetail/importExcel",
+        confirmBatch: "/business/busMeetingRoomScheduleDetail/confirmBatch",
+      },
+      dictOptions: {},
+      superFieldList: [],
+    };
+  },
+  created() {
+    this.getSuperFieldList();
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG["domianURL"]}/${this.url.importExcelUrl}`;
+    },
+  },
+  methods: {
+    batchConfirm() {
+      if (!this.url.confirmBatch) {
+        this.$message.error("请设置url.confirmBatch!");
+        return;
+      }
+      if (this.selectedRowKeys.length <= 0) {
+        this.$message.warning("请选择一条记录!");
+        return;
+      } else {
+        var ids = "";
+        for (var a = 0; a < this.selectedRowKeys.length; a++) {
+          ids += this.selectedRowKeys[a] + ",";
+        }
+        var that = this;
+        that.loading = true;
+        postAction(that.url.confirmBatch, { ids: ids })
+          .then((res) => {
+            if (res.success) {
+              that.$message.success(res.message);
+              that.loadData();
+              that.onClearSelected();
+            } else {
+              that.$message.warning(res.message);
+            }
+          })
+          .finally(() => {
+            that.loading = false;
+          });
+      }
+    },
+    handleEdit(item) {
+      var that = this;
+      postAction("/business/busMeetingRoomScheduleDetail/confirm", {
+        id: item.id,
+      })
+        .then((res) => {
+          if (res.success) {
+            that.$message.success(res.message);
+            item.status = 1;
+          } else {
+            that.$message.warning(res.message);
+          }
+        })
+        .finally(() => {});
+    },
+    initDictConfig() {},
+    getSuperFieldList() {
+      let fieldList = [];
+      fieldList.push({
+        type: "string",
+        value: "tenantId",
+        text: "关联租户",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "hotelId",
+        text: "关联酒店",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "couponsId",
+        text: "免房券id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "code",
+        text: "券号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "int",
+        value: "status",
+        text: "状态 0未领取 1已领取 2已使用 3已作废",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userid",
+        text: "会员id",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "userName",
+        text: "姓名",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "roomNumber",
+        text: "房间号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "checkedInNo",
+        text: "入住单号",
+        dictCode: "",
+      });
+      fieldList.push({
+        type: "string",
+        value: "mobile",
+        text: "手机号",
+        dictCode: "",
+      });
+      fieldList.push({ type: "date", value: "gainTime", text: "领取时间" });
+      fieldList.push({ type: "date", value: "usedTime", text: "使用时间" });
+      this.superFieldList = fieldList;
+    },
+    handleAdd() {
+      this.$refs.modalForm.add(this.ipagination.total, this.couponsId);
+      this.$refs.modalForm.title = "优惠券生成";
+      this.$refs.modalForm.disableSubmit = false;
+    },
+  },
+};
+</script>
+<style scoped>
+@import "~@assets/less/common.less";
+</style>

+ 66 - 0
src/views/markets/modules/meetingRoomSchedule/meetingRoomScheduleDetail/meetingRoomScheduleDetailModal.vue

@@ -0,0 +1,66 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
+    @cancel="handleCancel"
+    cancelText="关闭"
+  >
+    <meeting-room-schedule-detail-list
+      :meetingRoomScheduleId="meetingRoomScheduleId"
+      ref="modalMeetingRoomScheduleDetailListModal"
+    ></meeting-room-schedule-detail-list>
+  </j-modal>
+</template>
+
+<script>
+import meetingRoomScheduleDetailList from "./meetingRoomScheduleDetailList";
+export default {
+  name: "meetingRoomScheduleDetailListModal",
+  components: {
+    meetingRoomScheduleDetailList,
+  },
+  props: {
+    meetingRoomScheduleId: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      title: "",
+      width: 1200,
+      visible: false,
+      disableSubmit: false,
+    };
+  },
+  methods: {
+    add() {
+      this.visible = true;
+    },
+    edit(record) {
+      this.visible = true;
+      this.$nextTick(() => {
+        this.$refs.modalMeetingRoomScheduleDetailListModal.edit(record);
+      });
+    },
+    close() {
+      this.$emit("close");
+      this.visible = false;
+    },
+    handleOk() {
+      this.$refs.modalMeetingRoomScheduleDetailListModal.submitForm();
+    },
+    submitCallback() {
+      this.$emit("ok");
+      this.visible = false;
+    },
+    handleCancel() {
+      this.close();
+    },
+  },
+};
+</script>

+ 316 - 0
src/views/markets/modules/memberBalance/BusMemberBalanceLogForm.vue

@@ -0,0 +1,316 @@
+<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="memberId"
+            >
+              <a-select
+                v-model="model.memberId"
+                style="width: 100%"
+                placeholder="请选择会员"
+                show-search
+                option-filter-prop="children"
+                :filter-option="filterOption"
+              >
+                <a-select-option
+                  v-for="(item, index) in memberList"
+                  :key="index"
+                  :value="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="type"
+            >
+              <a-radio-group v-model="model.type">
+                <a-radio :value="1">充值</a-radio>
+                <a-radio :value="2">扣费</a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" v-if="model.type == 1">
+            <a-form-model-item
+              label="充值配置"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-select
+                v-model="model.marketRechargeId"
+                style="width: 100%"
+                placeholder="充值配置"
+                @change="marketRechargeChage"
+              >
+                <a-select-option
+                  v-for="(item, index) in marketRechargeList"
+                  :key="index"
+                  :value="item.id"
+                  >{{ item.name }}</a-select-option
+                >
+              </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              :label="model.type == 1 ? '充值金额' : '扣费金额'"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="money"
+            >
+              <a-input-number
+                v-model="model.money"
+                placeholder="请输入充值金额"
+                :min="1"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" v-if="model.type == 1">
+            <a-form-model-item
+              label="赠送金额"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              :min="0"
+              prop="giveMoney"
+            >
+              <a-input-number
+                v-model="model.giveMoney"
+                placeholder="请输入赠送金额"
+                style="width: 100%"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="备注"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="remarks"
+            >
+              <a-textarea
+                v-model="model.remarks"
+                rows="4"
+                placeholder="请输入备注"
+              />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" v-if="model.type == 1">
+            <a-form-model-item
+              label="推荐员工"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="staffId"
+            >
+              <a-select
+                v-model="model.staffId"
+                style="width: 100%"
+                placeholder="推荐员工"
+              >
+                <a-select-option
+                  v-for="(item, index) in staffList"
+                  :key="index"
+                  :value="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="paymentMethod"
+            >
+              <a-select
+                v-model="model.paymentMethod"
+                style="width: 100%"
+                placeholder="支付方式"
+              >
+                <a-select-option
+                  v-for="(item, index) in paymentMethodList"
+                  :key="index"
+                  :value="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="payMoney"
+            >
+              <a-input-number
+                v-model="model.payMoney"
+                placeholder="请输入支付金额"
+                style="width: 100%"
+                :min="0"
+              />
+            </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: "BusMemberBalanceLogForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: { type: 1 },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        memberId: [{ required: true, message: "请选择会员!" }],
+        type: [{ required: true, message: "请输入类型!" }],
+        money: [{ required: true, message: "请输入充值金额!" }],
+        balance: [{ required: true, message: "请输入金额余额!" }],
+        giveMoney: [{ required: true, message: "请输入赠送金额!" }],
+        paymentMethod: [{ required: true, message: "请输入支付方式!" }],
+        payMoney: [{ required: true, message: "请输入支付金额!" }],
+        code: [{ required: true, message: "请输入流水号!" }],
+      },
+      url: {
+        add: "/business/busMemberBalanceLog/add",
+        edit: "/business/busMemberBalanceLog/edit",
+        queryById: "/business/busMemberBalanceLog/queryById",
+      },
+      memberList: [],
+      marketRechargeList: [],
+      staffList: [],
+      paymentMethodList: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    httpAction(
+      "/business/busMemberCard/list",
+      { pageNo: 1, pageSize: 1000 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.memberList = res.result.records;
+      }
+    });
+    httpAction(
+      "/business/busMarketRecharge/list",
+      { pageNo: 1, pageSize: 1000 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.marketRechargeList = res.result.records;
+      }
+    });
+    httpAction(
+      "/business/busRoomPayType/queryList",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.paymentMethodList = res.result;
+      }
+    });
+    var _info = JSON.parse(localStorage.getItem("storeInfo"));
+    if (_info) {
+      this.model.hotelId = _info.id;
+    }
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    marketRechargeChage(e) {
+      var item = this.marketRechargeList.find((t) => t.id === e);
+      this.model.money = item.money;
+      this.model.giveMoney = item.returnRoney;
+    },
+    filterOption(input, option) {
+      return (
+        option.componentOptions.children[0].text
+          .toLowerCase()
+          .indexOf(input.toLowerCase()) >= 0
+      );
+    },
+    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>

+ 84 - 0
src/views/markets/modules/memberBalance/BusMemberBalanceLogModal.Style#Drawer.vue

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

+ 60 - 0
src/views/markets/modules/memberBalance/BusMemberBalanceLogModal.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="关闭">
+    <bus-member-balance-log-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-member-balance-log-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMemberBalanceLogForm from './BusMemberBalanceLogForm'
+  export default {
+    name: 'BusMemberBalanceLogModal',
+    components: {
+      BusMemberBalanceLogForm
+    },
+    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>

+ 286 - 0
src/views/markets/modules/memberCard/BusMemberCardForm.vue

@@ -0,0 +1,286 @@
+<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="mobile">
+              <a-input v-model="model.mobile" placeholder="请输入手机号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="会员卡号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="cardNo">
+              <a-input v-model="model.cardNo" placeholder="请输入会员卡号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="卡内码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="cardInnerNo">
+              <a-input v-model="model.cardInnerNo" placeholder="请输入卡内码"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="等级类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="gradeId">
+              <a-select
+                v-model:value="model.gradeId"
+                style="width: 100%"
+                placeholder="会员等级"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in gradeList"
+                  :key="index"
+                  :value="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="memberFee">
+              <a-input-number v-model="model.memberFee" placeholder="请输入会员费" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="付款类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="payType">
+              <a-radio-group v-model="model.payType">
+                <a-radio :value="1">现付</a-radio>
+                <a-radio :value="2" disabled>转房帐</a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" v-if="model.payType==1">
+            <a-form-model-item label="付款方式" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="paymentMethod">
+              <a-select
+                v-model="model.paymentMethod"
+                style="width: 100%"
+                placeholder="付款方式"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in paymentMethodList"
+                  :key="index"
+                  :value="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="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="avatar">
+              <a-input v-model="model.avatar" placeholder="请输入头像"  ></a-input>
+            </a-form-model-item>
+          </a-col> -->
+          <a-col :span="24">
+            <a-form-model-item label="性别" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="sex">
+              <a-radio-group v-model="model.sex">
+                <a-radio :value="1">男</a-radio>
+                <a-radio :value="2">女</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="certificateType">
+              <a-select
+                v-model="model.certificateType"
+                style="width: 100%"
+                placeholder="证件类型"
+                :allowClear="true"
+              >
+                <a-select-option :value="1" >身份证</a-select-option>
+              </a-select>
+            </a-form-model-item>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="证件号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="certificateNo">
+              <a-input v-model="model.certificateNo" placeholder="请输入证件号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="地址" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="address">
+              <a-input v-model="model.address" placeholder="请输入地址"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="消费密码" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="consumePassword">
+              <a-input-password  v-model="model.consumePassword" placeholder="请输入消费密码"></a-input-password>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="有效期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="validity">
+              <a-radio-group v-model="model.validity">
+                <a-radio :value="1">无限制</a-radio>
+                <a-radio :value="2">有限制</a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24" v-if="model.validity==2">
+            <a-form-model-item label="有效期截止日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="validityEndTime" :rules="[
+                                        {
+                                            required: true,
+                                            message: '请输入有效期截止日期',
+                                            trigger: 'change',
+                                        },
+                                    ]">
+              <j-date placeholder="请选择有效期截止日期" v-model="model.validityEndTime"  style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
+              <a-textarea v-model="model.remark" rows="4" placeholder="请输入备注" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="推荐员工" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="staffId">
+              <a-select
+                v-model="model.staffId"
+                style="width: 100%"
+                placeholder="推荐员工"
+                :allowClear="true"
+              >
+                <a-select-option
+                  v-for="(item, index) in staffList"
+                  :key="index"
+                  :value="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: "BusMemberCardForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: { payType: 1 },
+      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: "请输入付款方式!" }],
+        name: [{ required: true, message: "请输入会员姓名!" }],
+        sex: [{ required: true, message: "请输入性别!" }],
+        certificateType: [{ required: true, message: "请输入证件类型!" }],
+        validity: [{ required: true, message: "请输入有效期!" }],
+      },
+      url: {
+        add: "/business/busMemberCard/add",
+        edit: "/business/busMemberCard/edit",
+        queryById: "/business/busMemberCard/queryById",
+      },
+      gradeList: [],
+      paymentMethodList: [],
+      staffList: [],
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    httpAction(
+      "/org.jeecg.modules.business/busMarketMember/list",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.gradeList = res.result.records;
+      }
+    });
+    httpAction(
+      "/business/busRoomPayType/queryList",
+      { pageNo: 1, pageSize: 100 },
+      "get"
+    ).then((res) => {
+      if (res.success) {
+        this.paymentMethodList = res.result;
+      }
+    });
+    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>

+ 84 - 0
src/views/markets/modules/memberCard/BusMemberCardModal.Style#Drawer.vue

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

+ 60 - 0
src/views/markets/modules/memberCard/BusMemberCardModal.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="关闭">
+    <bus-member-card-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-member-card-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMemberCardForm from './BusMemberCardForm'
+  export default {
+    name: 'BusMemberCardModal',
+    components: {
+      BusMemberCardForm
+    },
+    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>

+ 170 - 0
src/views/markets/modules/memberPoint/BusMemberPointLogForm.vue

@@ -0,0 +1,170 @@
+<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"
+            >
+              <span>{{ model.name }}</span>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="卡号"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <span>{{ model.cardNo }}</span>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="积分"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <span>{{ model.integral || 0 }}</span>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="类型"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+            >
+              <a-radio-group v-model="model.type">
+                <a-radio :value="1">充值</a-radio>
+                <a-radio :value="2">扣除</a-radio>
+                <a-radio :value="3">清空</a-radio>
+              </a-radio-group>
+            </a-form-model-item>
+          </a-col>
+
+          <a-col :span="24" v-if="model.type != 3">
+            <a-form-model-item
+              label="充值积分"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="num"
+            >
+              <a-input-number v-model="model.num" style="width: 100%" :min="1" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item
+              label="备注"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              prop="remarks"
+            >
+              <a-textarea
+                v-model="model.remarks"
+                rows="4"
+                placeholder="请输入备注"
+              />
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+import { httpAction, getAction } from "@/api/manage";
+import { validateDuplicateValue } from "@/utils/util";
+
+export default {
+  name: "BusMemberPointLogForm",
+  components: {},
+  props: {
+    //表单禁用
+    disabled: {
+      type: Boolean,
+      default: false,
+      required: false,
+    },
+  },
+  data() {
+    return {
+      model: { type: 1, num: 1 },
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 },
+      },
+      confirmLoading: false,
+      validatorRules: {
+        type: [{ required: true, message: "请输入类型!" }],
+        num: [{ required: true, message: "请输入积分数量!" }],
+      },
+      url: {
+        add: "/business/busMemberPointLog/add",
+        edit: "/business/busMemberPointLog/edit",
+        queryById: "/business/busMemberPointLog/queryById",
+      },
+    };
+  },
+  computed: {
+    formDisabled() {
+      return this.disabled;
+    },
+  },
+  created() {
+    //备份model原始值
+    this.modelDefault = JSON.parse(JSON.stringify(this.model));
+  },
+  methods: {
+    add(record) {
+      this.modelDefault = Object.assign({}, record,this.modelDefault);
+      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>

+ 84 - 0
src/views/markets/modules/memberPoint/BusMemberPointLogModal.Style#Drawer.vue

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

+ 60 - 0
src/views/markets/modules/memberPoint/BusMemberPointLogModal.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="关闭">
+    <bus-member-point-log-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></bus-member-point-log-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import BusMemberPointLogForm from './BusMemberPointLogForm'
+  export default {
+    name: 'BusMemberPointLogModal',
+    components: {
+      BusMemberPointLogForm
+    },
+    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>

+ 208 - 0
src/views/settings/components/modules/printTemplateForm.vue

@@ -0,0 +1,208 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <div class="container">
+      <div class="left">
+        <j-form-container :disabled="formDisabled">
+          <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail" layout="vertical">
+            <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="specs">
+                  <j-dict-select-tag type="radio" v-model="model.specs" placeholder="请选择规格" dictCode="print_template_specs"
+                                     @change="e=>onSpecsChange(e)"/>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remarks">
+                  <a-textarea :rows="4" v-model="model.remarks" placeholder="请输入备注"/>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item label="" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="preview">
+                  <a-checkbox v-model="model.preview">不显示打印预览窗口,直接打印小票</a-checkbox>
+                </a-form-model-item>
+              </a-col>
+
+              <a-col :span="24">
+                <a-form-model-item label="默认打印机" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="defaultPrint">
+                  <a-input v-model="model.defaultPrint" placeholder="请输入默认打印机"  ></a-input>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item label="打印类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="printType">
+                  <j-dict-select-tag type="radio" v-model="model.printType" placeholder="请选择打印类型" dictCode="print_template_type"/>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item label="是否显示退菜" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="isShowRefund">
+                  <j-dict-select-tag type="radio" v-model="model.isShowRefund" placeholder="请选择是否显示退菜" dictCode="print_template_refund"/>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item label="打印份数" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="printSum">
+                  <a-input-number v-model="model.printSum" placeholder="请输入打印份数" style="width: 100%" />
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item label="打印时内容宽度偏差" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="printContentOffset">
+                  <a-input v-model="model.printContentOffset" placeholder="请输入打印时内容宽度偏差"  ></a-input>
+                </a-form-model-item>
+              </a-col>
+              <a-col :span="24">
+                <a-form-model-item label="打印时纸张宽度偏差" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="printPaperOffset">
+                  <a-input v-model="model.printPaperOffset" placeholder="请输入打印时纸张宽度偏差"  ></a-input>
+                </a-form-model-item>
+              </a-col>
+            </a-row>
+          </a-form-model>
+        </j-form-container>
+      </div>
+      <div class="right">
+        <a-card class="template" :style="{width:width}">
+          <p>Card content</p>
+          <p>Card content</p>
+          <p>Card content</p>
+        </a-card>
+      </div>
+    </div>
+
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'printTemplateForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+        },
+        wrapperCol: {
+        },
+        confirmLoading: false,
+        validatorRules: {
+           name: [
+              { required: true, message: '请输入打印模板名称!'},
+           ],
+           specs: [
+              { required: true, message: '请输入规格!'},
+           ],
+          remarks: [
+            { required: true, message: '请输入备注!'},
+          ],
+          printSum: [
+            { required: true, message: '请输入打印份数!'},
+          ],
+          printContentOffset: [
+            { required: true, message: '请输入打印时内容宽度偏差!'},
+          ],
+          printPaperOffset: [
+            { required: true, message: '请输入打印时纸张宽度偏差!'},
+          ],
+        },
+        url: {
+          add: "/business/busPrintTemplate/add",
+          edit: "/business/busPrintTemplate/edit",
+          queryById: "/business/busPrintTemplate/queryById"
+        },
+        width:"94%"
+      }
+    },
+    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.width = record.specs;
+        if (record.specs === 'A5'){
+          // this.width = '210mm';
+        }
+        this.visible = true;
+      },
+      submitForm () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+              var info = JSON.parse(localStorage.getItem("storeInfo"));
+              this.model.hotelId = info.id;
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+
+        })
+      },
+      onSpecsChange(val){
+        console.log('规格切换  ————  '+val)
+        this.width = val;
+        console.log(this.width)
+        if (val === 'A5'){
+          // this.width = '210mm';
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+  .container{
+    display: flex;
+    flex-direction: row;
+  }
+  .left{
+    flex: 2;
+  }
+  .right{
+    flex: 3;
+  }
+  .template{
+    margin-left: 10px;
+  }
+</style>

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

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

+ 60 - 0
src/views/settings/components/modules/printTemplateModal.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="关闭">
+    <print-template-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></print-template-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import printTemplateForm from './printTemplateForm'
+  export default {
+    name: 'printTemplateModal',
+    components: {
+      printTemplateForm
+    },
+    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(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>

+ 203 - 4
src/views/settings/components/printTemplate.vue

@@ -1,13 +1,212 @@
 <template>
-    <div>打印模板</div>
+    <a-card :bordered="false">
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline" @keyup.enter.native="searchQuery">
+                <a-row :gutter="24">
+                    <a-col :md="4" :sm="6">
+                        <a-form-item>
+                            <j-input placeholder="参数名" v-model="queryParam.name"></j-input>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="4" :sm="6">
+                        <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+                          <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                        </span>
+                    </a-col>
+                </a-row>
+            </a-form>
+        </div>
+        <!-- 查询区域-END -->
+
+        <!-- 操作按钮区域 -->
+        <div class="table-operator">
+            <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+<!--            <a-button type="primary" icon="download" @click="handleExportXls('打印模板')">导出</a-button>-->
+<!--            <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">-->
+<!--                <a-button type="primary" icon="import">导入</a-button>-->
+<!--            </a-upload>-->
+<!--            &lt;!&ndash; 高级查询区域 &ndash;&gt;-->
+<!--            <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>-->
+<!--            <a-dropdown v-if="selectedRowKeys.length > 0">-->
+<!--                <a-menu slot="overlay">-->
+<!--                    <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>-->
+<!--                </a-menu>-->
+<!--                <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>-->
+<!--            </a-dropdown>-->
+        </div>
+
+        <!-- table区域-begin -->
+        <div>
+            <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+                <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+                <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+            </div>
+
+            <a-table
+                    ref="table"
+                    size="middle"
+                    :scroll="{x:true}"
+                    bordered
+                    rowKey="id"
+                    :columns="columns"
+                    :dataSource="dataSource"
+                    :pagination="ipagination"
+                    :loading="loading"
+                    :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+                    class="j-table-force-nowrap"
+                    @change="handleTableChange">
+
+                <template slot="htmlSlot" slot-scope="text">
+                    <div v-html="text"></div>
+                </template>
+                <template slot="imgSlot" slot-scope="text,record">
+                    <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+                    <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+                </template>
+                <template slot="fileSlot" slot-scope="text">
+                    <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+                    <a-button
+                            v-else
+                            :ghost="true"
+                            type="primary"
+                            icon="download"
+                            size="small"
+                            @click="downloadFile(text)">
+                        下载
+                    </a-button>
+                </template>
+
+                <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+<!--          <a-divider type="vertical" />-->
+<!--          <a-dropdown>-->
+<!--            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>-->
+<!--            <a-menu slot="overlay">-->
+<!--              <a-menu-item>-->
+<!--                <a @click="handleDetail(record)">详情</a>-->
+<!--              </a-menu-item>-->
+<!--              <a-menu-item>-->
+<!--                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">-->
+<!--                  <a>删除</a>-->
+<!--                </a-popconfirm>-->
+<!--              </a-menu-item>-->
+<!--            </a-menu>-->
+<!--          </a-dropdown>-->
+        </span>
+
+            </a-table>
+        </div>
+
+        <print-template-modal ref="modalForm" @ok="modalFormOk"></print-template-modal>
+    </a-card>
 </template>
 
 <script>
+
+    import '@/assets/less/TableExpand.less'
+    import { mixinDevice } from '@/utils/mixin'
+    import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+    import printTemplateModal from "./modules/printTemplateModal";
+
     export default {
-        name: "printTemplate"
+        name: 'printTemplate',
+        mixins:[JeecgListMixin, mixinDevice],
+        components: {
+            printTemplateModal,
+        },
+        data () {
+            return {
+                description: '打印模板管理页面',
+                // 表头
+                columns: [
+                    {
+                        title: '',
+                        dataIndex: '',
+                        key:'rowIndex',
+                        width:60,
+                        align:"center",
+                        customRender:function (t,r,index) {
+                            return parseInt(index)+1;
+                        }
+                    },
+                    {
+                        title:'打印单据名',
+                        align:"center",
+                        dataIndex: 'name'
+                    },
+                    {
+                        title:'规格',
+                        align:"center",
+                        dataIndex: 'specs'
+                    },
+                    {
+                        title:'打印份数',
+                        align:"center",
+                        dataIndex: 'printSum'
+                    },
+                    {
+                        title:'打印时内容宽度偏差',
+                        align:"center",
+                        dataIndex: 'printContentOffset'
+                    },
+                    {
+                        title:'打印时纸张宽度偏差',
+                        align:"center",
+                        dataIndex: 'printPaperOffset'
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align:"center",
+                        fixed:"right",
+                        width:147,
+                        scopedSlots: { customRender: 'action' }
+                    }
+                ],
+                url: {
+                    list: "/business/busPrintTemplate/list",
+                    delete: "/business/busPrintTemplate/delete",
+                    deleteBatch: "/business/busPrintTemplate/deleteBatch",
+                    exportXlsUrl: "/business/busPrintTemplate/exportXls",
+                    importExcelUrl: "business/busPrintTemplate/importExcel",
+
+                },
+                dictOptions:{},
+                superFieldList:[],
+            }
+        },
+        created() {
+            this.getSuperFieldList();
+        },
+        computed: {
+            importExcelUrl: function(){
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            },
+        },
+        methods: {
+            initDictConfig(){
+            },
+            getSuperFieldList(){
+                let fieldList=[];
+                fieldList.push({type:'string',value:'tenantId',text:'关联租户'})
+                fieldList.push({type:'string',value:'hotelId',text:'关联酒店'})
+                fieldList.push({type:'string',value:'name',text:'打印模板名称'})
+                fieldList.push({type:'string',value:'specs',text:'规格'})
+                fieldList.push({type:'string',value:'remarks',text:'备注'})
+                fieldList.push({type:'string',value:'defaultPrint',text:'默认打印机'})
+                fieldList.push({type:'int',value:'printType',text:'打印类型(1-明细;2-汇总)'})
+                fieldList.push({type:'int',value:'printSum',text:'打印份数'})
+                fieldList.push({type:'string',value:'preview',text:'打印预览'})
+                fieldList.push({type:'string',value:'printContentOffset',text:'打印时内容宽度偏差'})
+                fieldList.push({type:'string',value:'printPaperOffset',text:'打印时纸张宽度偏差'})
+                fieldList.push({type:'int',value:'isShowRefund',text:'状态(0-关闭;1-开启)'})
+                this.superFieldList = fieldList
+            }
+        }
     }
 </script>
-
 <style scoped>
-
+    @import '~@assets/less/common.less';
 </style>

+ 537 - 124
src/views/settings/components/roomModules/roomGen.vue

@@ -1,148 +1,561 @@
 <template>
-    <div  style="display: flex;">
-        <div style="flex: 3">
-            <a-form :form="form">
-                酒店名称<a-select
-                        show-search
-                        placeholder="请选择酒店"
-                        option-filter-prop="children"
-                        style="width: 200px"
-                        @change="hotelChange"
-                >
-                    <a-select-option v-for="(item, index) in hotelId" :key="index">
-                        {{item.name}}
-                    </a-select-option>
-                </a-select>
-                <div></div>
-                楼栋名称<a-select
-                    show-search
-                    placeholder="请选择楼栋"
-                    option-filter-prop="children"
-                    style="width: 200px"
-                    @change="floorChange"
+  <div style="display: flex" v-if="step == 1">
+    <div style="flex: 3">
+      <a-form :form="form">
+        <!-- <a-form-model-item
+          label="酒店名称"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="layoutId"
+        >
+          <a-select
+            show-search
+            placeholder="请选择酒店"
+            option-filter-prop="children"
+            @change="hotelChange"
+          >
+            <a-select-option v-for="(item, index) in hotelId" :key="index">
+              {{ item.name }}
+            </a-select-option>
+          </a-select>
+        </a-form-model-item> -->
+
+        <a-form-model-item
+          label="楼栋名称"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="layoutId"
+        >
+          <a-select
+            show-search
+            placeholder="请选择楼栋"
+            v-model="buildingId"
+            option-filter-prop="children"
+            @change="floorChange"
+          >
+            <a-select-option v-for="item in buildingTreeData" :key="item.id">
+              {{ item.name }}
+            </a-select-option>
+          </a-select>
+        </a-form-model-item>
+
+        <a-form-model-item
+          label="层数最高"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="layoutId"
+        >
+          <a-input-number
+            placeholder="输入楼层数"
+            v-model="model.floorCount"
+            :min="1"
+            style="width: 120px"
+          />层
+        </a-form-model-item>
+        <a-form-model-item
+          label="每层房间数量"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="layoutId"
+        >
+          <a-input-number
+            placeholder="输入每层房间数"
+            v-model="model.roomCount"
+            :min="1"
+            style="width: 120px"
+          />间
+        </a-form-model-item>
+
+        <a-form-model-item
+          label="设置前缀"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="layoutId"
+        >
+          <a-input placeholder="输入房号前缀" v-model="model.prefix" />
+        </a-form-model-item>
+        <a-form-model-item
+          label="设置前缀"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          prop="layoutId"
+        >
+          <a-checkbox v-model="model.isExpectEnd"> 尾号排除 </a-checkbox>
+          <a-input
+            :disabled="!model.isExpectEnd"
+            placeholder="输入排除的其他尾号"
+            v-model="tailNumber"
+          />
+        </a-form-model-item>
+        <a-button type="primary" @click="genRooms"> 批量生成 </a-button>
+      </a-form>
+    </div>
+    <div style="flex: 7">
+      <div v-if="roomTree.length > 0">
+        <div v-for="(item, index) in roomTree" :key="index" style="width: 100%">
+          <div style="font-width: 600; font-size: 20px" @click="sele(item)">
+            <a-input
+              placeholder="请填写楼层名"
+              v-model="item.name"
+              class="floor-input"
+            ></a-input>
+            <a-button
+              @click="delFloor(index)"
+              type="danger"
+              shape="circle"
+              size="small"
+              icon="minus"
+              style="margin-left: 5px"
+            />
+          </div>
+          <div
+            style="display: flex;justify-content: start;margin: 20px;flex-wrap: wrap;"
+          >
+            <div
+              v-for="(room, indexs) in item.children"
+              :key="indexs"
+              style="width: 25%; margin-top: 10px"
             >
-                <a-select-option v-for="(item, index) in buildId" :key="index">
-                    {{item.name}}
-                </a-select-option>
-            </a-select>
-                <div>设置最高层数 最高<a-input placeholder="输入楼层数" v-model="floor"/>层</div>
-                <div>每层房间数量<a-input placeholder="输入每层房间数" v-model="roomsFromOneFloor" />间</div>
-                <div>设置前缀<a-input placeholder="输入房号前缀" v-model="prefixName"/></div>
-                <a-form-item :label-col="formTailLayout.labelCol" :wrapper-col="formTailLayout.wrapperCol">
-                    <div>
-                        <a-checkbox :checked="checkNick" @change="tailNumberExclude">
-                            尾号排除
-                        </a-checkbox>
-                        <a-input placeholder="输入排除的其他尾号" v-model="tailNumber"/>
-                    </div>
-                </a-form-item>
-                <a-form-item :label-col="formTailLayout.labelCol" :wrapper-col="formTailLayout.wrapperCol">
-                    <a-button type="primary" @click="check">
-                        批量生成
-                    </a-button>
-                </a-form-item>
-            </a-form>
+              <input :value="room.name" style="width: 50%; margin: auto" />
+              <a-button
+                @click="delRoom(index, indexs)"
+                type="danger"
+                shape="circle"
+                size="small"
+                icon="minus"
+                style="margin-left: 5px"
+              />
+            </div>
+          </div>
+          <div>
+            <a-button
+              @click="addRoom(index)"
+              type="primary"
+              shape="circle"
+              size="small"
+              icon="plus"
+              style="margin-left: 20px; margin: 0 20px 20px"
+            />
+          </div>
         </div>
-        <div style="flex: 7">
-<!--            <a-collapse v-model="activeKey">-->
-<!--                <a-collapse-panel key="1" :header="item.name" v-for="(item, index) in floor" :key="index">-->
-<!--&lt;!&ndash;                    <p>{{ item.name }}</p>&ndash;&gt;-->
-<!--                    <div style="display: flex; justify-content: space-between">-->
-<!--                        <div v-for="(items, indexs) in item.chil" :key="indexs">-->
-<!--                            {{items.name}}-->
-<!--                        </div>-->
-<!--                    </div>-->
-<!--                </a-collapse-panel>-->
-<!--            </a-collapse>-->
-                <div v-for="(item, index) in floor" :key="index">
-                    <div style="font-width: 600; font-size: 20px" @click="sele(item)">
-                        {{item.name}}
-                    </div>
-                    <div v-if="item.show" style="display: flex; justify-content: space-around; padding: 20px">
-                        <div v-for="(items, indexs) in item.chil" :key="indexs" style="width: 25%;">
-                            <input :value="items.name" style="width: 50%; margin: auto"><a-button type="danger" shape="circle" size="small" icon="minus" style="margin-left: 5px;" />
-                        </div>
-                    </div>
-                    <div>
-                        <a-button type="primary" shape="circle" size="small" icon="plus" style="margin-left: 20px;" />添加房间
-                    </div>
-                </div>
-
+      </div>
+      <div v-else class="empty-tree">
+        <a-empty description="请在左侧生成房间" />
+      </div>
+      <div class="bottom-btns">
+        <a-button @click="back">取消</a-button>
+        <a-button @click="save" type="primary">保存</a-button>
+      </div>
+    </div>
+  </div>
+  <div v-else class="room-layout-settings">
+    <div class="layout-rooms-item" v-for="(item, layoutIndex) in layouts" :key="item.id">
+      <div class="title-laytou">
+        {{ item.name }}
+        
+      </div>
+      <div class="room-items">
+        <div v-for="(element, roomIndex) in item.rooms" :key="element.id" class="layout-room-item">
+          {{ element.name }}
+          <a-button
+          @click="delLayoutRoom(element, layoutIndex, roomIndex)"
+          type="danger"
+          shape="circle"
+          size="small"
+          icon="minus"
+          style="margin-left: 5px"
+        />
         </div>
+      </div>
+    </div>
+    <div class="wait-select-title">
+      <div class="color-title">待配置房间</div>
+    </div>
+    <div
+      v-for="(item, index) in roomTree"
+      :key="index"
+      style="width: 100%; padding-left: 30px"
+    >
+      <div style="font-width: 600; font-size: 20px" @click="sele(item)">
+        {{ item.name }}
+      </div>
+      <div
+        style="display: flex;justify-content: start;margin: 20px;flex-wrap: wrap;"
+      >
+        <div
+          v-for="(room, indexs) in item.children"
+          :key="indexs"
+          class="select-room-item"
+          :class="[room.checked ? 'checked-room' : '']"
+          @click="room.checked = !room.checked"
+          style="width: 80px; margin-top: 10px"
+        >
+          {{ room.name }}
+        </div>
+      </div>
+      
+    </div>
+    <div class="bottom-sele-btn">
+        <a-popover placement="topRight" v-if="canMove.can">
+          <template slot="content">
+            <a-button
+              type="link"
+              v-for="(item, index) in layouts"
+              :key="item.id"
+              @click="moveTo(index)"
+            >
+              {{ item.name }}
+            </a-button>
+          </template>
+          <template slot="title">
+            <span>要移动到的目标房型</span>
+          </template>
+          <a-button :disabled="false" type="primary"
+            >移动到房型({{ canMove.count }})</a-button
+          >
+        </a-popover>
+        <a-button v-else :disabled="true" type="primary"
+          >移动到房型(0)</a-button
+        >
+        <a-button :disabled="saveLoading" :loading="saveLoading" @click="back" type="primary"
+          >取消</a-button
+        >
+        <a-button :disabled="saveLoading" :loading="saveLoading" @click="save" type="primary"
+          >保存并查看房间列表</a-button
+        >
+
     </div>
+  </div>
 </template>
 
 <script>
-    const formItemLayout = {
-        labelCol: { span: 4 },
-        wrapperCol: { span: 8 },
-    };
-    const formTailLayout = {
-        labelCol: { span: 4 },
-        wrapperCol: { span: 8, offset: 4 },
-    };
+import draggable from "vuedraggable";
+import { buildingTree, saveBatch } from "@/api/roomBuildingApi";
+import { getAllLayouts } from "@/api/roomLayout";
 export default {
-    name: 'HotelSaasTenantFrontendRoomGen',
+  name: "HotelSaasTenantFrontendRoomGen",
+  inject: ["closeCurrent"],
+  components: {
+    draggable,
+  },
+  data() {
+    return {
+        saveLoading: false,
+      myArray: [
+        {
+          id: 1,
+          name: "12",
+        },
+        {
+          id: 2,
+          name: "33",
+        },
+      ],
+      step: 1,
+      layouts: [],
+      buildingId: undefined,
+      buildingTreeData: [],
+      hotelId: [{ name: "A酒店" }, { name: "B酒店" }, { name: "C酒店" }],
+      labelCol: {
+        xs: { span: 12 },
+        sm: { span: 5 },
+      },
+      wrapperCol: {
+        xs: { span: 10 },
+        sm: { span: 16 },
+      },
+      roomTree: [],
+      model: {
+        floorCount: 1,
+        roomCount: 10,
+        prefix: "",
+        isExpectEnd: false,
+      },
 
-    data() {
-        return {
-            hotelId: [{name: 'A酒店'}, {name: 'B酒店'}, {name: 'C酒店'}],
-            buildId: [{name: 'A栋'},{name: 'B栋'},{name: 'C栋'}],
-            floor: [
-                {name: '第一层', show: true,
-                    chil:[{name: '101'},{name: '102'},{name: '103'},{name: '104'}]
-                },
-                {name: '第二层', show: true,
-                    chil:[{name: '101'},{name: '102'},{name: '103'},{name: '104'}]
-                },
-                {name: '第三层', show: true,
-                    chil:[{name: '101'},{name: '102'},{name: '103'},{name: '104'}]
-                }
-                ],
+      prefixName: "room",
+      roomsFromOneFloor: 6,
+      tailNumber: "",
+      checkNick: false,
+      form: this.$form.createForm(this, { name: "dynamic_rule" }),
+      seleShow: "", // 用于切换折叠
+    };
+  },
 
+  computed: {
+    canMove() {
+      let canMove = {
+        can: false,
+        count: 0,
+      };
+      this.roomTree.forEach((floor) => {
+        floor.children.forEach((room) => {
+          if (room.checked) {
+            (canMove.can = true), canMove.count++;
+          }
+        });
+      });
+      return canMove;
+    },
+  },
+  mounted() {
+    buildingTree().then((res) => {
+      if (res.code == 200) {
+        this.buildingTreeData = res.result;
+      }
+    });
+    getAllLayouts().then((res) => {
+      if (res.code == 200) {
+        res.result.records.forEach((s) => {
+          s["rooms"] = [];
+        });
+        this.layouts = res.result.records;
+      }
+    });
+  },
 
+  methods: {
+    delLayoutRoom(item, layoutIndex, roomIndex) {
+        this.roomTree[item.floorIndex].children.push({
+            checked: false,
+            name: item.name,
+            floorIndex: item.floorIndex
+        })
+        this.layouts[layoutIndex].rooms.splice(roomIndex,1)
+    },
+    moveTo(idx) {
+      let roomItems = [];
+      let rmvObject = {};
+      this.roomTree.forEach((floor, floorIndex) => {
+        rmvObject["" + floorIndex] = [];
+        floor.children.forEach((room, roomIndex) => {
+          if (room.checked) {
+            rmvObject["" + floorIndex].push(roomIndex);
+            roomItems.push({
+              floorIndex: floorIndex,
+              floorName: floor.name,
+              name: room.name,
+            });
+          }
+        });
+      });
 
+      let objKeys = Object.keys(rmvObject);
+      objKeys.forEach((item) => {
+        if (rmvObject[item].length > 0) {
+          rmvObject[item].reverse().forEach((index) => {
+            this.roomTree[parseInt(item)].children.splice(index, 1);
+          });
+        }
+      });
+      let origItems = JSON.parse(JSON.stringify(this.layouts[idx].rooms));
 
-            prefixName: 'room',
-            roomsFromOneFloor: 6,
-            tailNumber: 4,
-            activeKey: ['1'],
-            checkNick: false,
-            formItemLayout,
-            formTailLayout,
-            form: this.$form.createForm(this, { name: 'dynamic_rule' }),
-            seleShow: '', // 用于切换折叠
-        };
+      origItems = origItems.concat(roomItems);
+      this.$set(this.layouts[idx], "rooms", origItems);
     },
-
-    mounted() {
-        
+    onDrag(e) {
+      debugger;
+    },
+    onRoomSelect(index, subIndex) {
+      this.$set(this.roomTree[index].children[subIndex], "checked", true);
     },
+    save() {
+      let result = [];
+      let param = {
+        hotelId: null,
+        buildId: null,
+        children: [],
+      };
+      let hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+      if (!this.buildingId) {
+        this.$message.error("请选择楼栋");
+        return;
+      }
 
-    methods: {
-        hotelChange(value) {
-            console.log(`selected ${value}`);
-        },
-        floorChange(value) {
-            console.log(`selected ${value}`);
-        },
-        tailNumberExclude() {
-            console.log(`selected ${value}`);
-        },
-        activeKey(key) {
-            console.log(key);
-        },
-        sele(data) {
-            data.show = !data.show
-        },
-        check() {
+      if (this.model.roomCount <= 0) {
+        this.$message.error("房间数不正确");
+        return;
+      }
 
-        },
+      if (this.step == 1) {
+        this.step = 2;
+        return;
+      }
+      let treeData = this.getParams();
+      this.saveLoading = true
+      saveBatch(treeData).then(res => {
+        if(res.code == 200) {
+            this.$message.success("批量保存成功")
+            this.closeCurrent()
+        }
+      }).finally(_ => {
+        this.saveLoading = false
+      })
+    },
+    getParams() {
+        let param = {
+            hotelId: null,
+            buildId: null,
+            children: [],
+        };
+        let hotelInfo = JSON.parse(localStorage.getItem("storeInfo"));
+        param.buildId = this.buildingId;
+        param.hotelId = hotelInfo.id;
+        let roomTree = JSON.parse(JSON.stringify(this.roomTree))
+        roomTree.forEach(a => {
+            param.children.push({
+                floorName: a.name,
+                children: []
+            })
+        })
+        this.layouts.forEach(layout => {
+            layout.rooms.forEach(room => {
+                param.children[room.floorIndex].children.push({
+                    hotelId: hotelInfo.id,
+                    buildId: this.buildingId,
+                    layoutId: layout.id,
+                    name: room.name,
+                    prefix: this.model.prefix,
+                })
+            })
+        })
 
+        return param
+    },
+    addRoom(index) {
+      this.roomTree[index].children.push({
+        name: "",
+        floorIndex: index,
+        checked: false,
+      });
     },
+    delFloor(index) {
+      this.roomTree.splice(index, 1);
+    },
+    delRoom(index, roomIndex) {
+      this.roomTree[index].children.splice(roomIndex, 1);
+    },
+    hotelChange(value) {
+      console.log(`selected ${value}`);
+    },
+    floorChange(value) {
+      console.log(`selected ${value}`);
+    },
+    tailNumberExclude() {
+      console.log(`selected ${value}`);
+    },
+    sele(data) {
+      data.show = !data.show;
+    },
+    back() {
+      this.closeCurrent();
+    },
+    check() {},
+    genRooms() {
+      let floors = [];
+      let model = this.model;
+      for (let i = 0; i < model.floorCount; i++) {
+        let children = [];
+        for (let r = 0; r < model.roomCount; r++) {
+          let expectEndArr = [];
+          if (model.isExpectEnd) {
+            expectEndArr = (this.tailNumber || "").split(",");
+          }
+
+          let numStr = (r + 1).toString();
+          let lastChar = numStr[numStr.length - 1];
+          if (!expectEndArr.includes(lastChar)) {
+            children.push({
+              checked: false,
+              floorIndex: i,
+              name:
+                (i + 1).toString() +
+                "0" +
+                numStr.padStart(this.model.roomCount.toString().length, "0"),
+            });
+          }
+        }
+        floors.push({
+          name: `第${i + 1}层`,
+          children: children,
+        });
+      }
+      this.roomTree = floors;
+    },
+  },
 };
 </script>
 
-<style lang="stylus" scoped>
-
+<style lang="css" scoped>
+.empty-tree {
+  width: 100%;
+  height: 300px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.bottom-btns {
+  display: flex;
+  justify-content: center;
+  margin-bottom: 20px;
+}
+.floor-input {
+  width: 200px;
+}
+.room-items {
+    display: inline-block;
+  border: 1px solid #cccccc77;
+  height: 200px;
+  overflow-y: auto;
+  width: 90%;
+  border-radius: 10px;
+  margin-bottom: 30px;
+}
+.title-laytou {
+  font-size: 17px;
+  font-weight: bold;
+  width: 100px;
+  text-align: center;
+  height: 25px;
+  line-height: 25px;
+  background-color: antiquewhite;
+}
+.room-items-dr {
+  border: 1px solid #f00 !important;
+}
+.wait-select-title {
+  border-bottom: 4px solid #1cb1ac;
+}
+.color-title {
+  background-color: #1cb1ac;
+  color: white;
+  width: 100px;
+  height: 30px;
+  line-height: 30px;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  text-align: center;
+}
+.select-room-item {
+  border: 1px solid #cccccc77;
+  border-radius: 4px;
+  margin-right: 4px;
+  height: 80px;
+  text-align: center;
+  line-height: 80px;
+  background-color: white;
+  cursor: pointer;
+}
+.checked-room {
+  background-color: #1cb1ac !important;
+  color: white !important;
+  border: none !important;
+}
+.bottom-sele-btn {
+  padding-bottom: 30px;
+}
+.layout-room-item{
+    display: inline-block;
+    width: fit-content;
+    padding: 10px 12px;
+}
 </style>

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

@@ -36,11 +36,7 @@
                 <a-button
                   style="font-size: 12px"
                   type="link"
-                  @click="
-                    () => {
-                      $message.success(item.name);
-                    }
-                  "
+                  @click="filterSearch(item)"
                   >{{ item.name }}</a-button
                 >
                 <div style="flex: 1; height: 1px"></div>
@@ -76,7 +72,7 @@
         </div>
       </div>
       <div class="right-wrapper">
-        <room-num-table></room-num-table>
+        <room-num-table ref="numtable"></room-num-table>
       </div>
     </div>
     <!-- 添加楼层 -->
@@ -130,6 +126,10 @@ export default {
     this.loadBuildingTreeData();
   },
   methods: {
+    // 点击 触发搜索
+    filterSearch(item) {
+
+    },
     // 获取楼栋树
     loadBuildingTreeData() {
       buildingTree().then((res) => {

+ 3 - 1
src/views/settings/components/roomModules/roomNumSettings/roomNumTable.vue

@@ -178,7 +178,9 @@ export default {
       return "";
     },
     // 批量添加按钮
-    onAddBatch() {},
+    onAddBatch() {
+        this.$router.push('/tenant/gen/rooms');
+    },
     // 全部删除
     onDelAll() {},
     // 显示图片弹窗

+ 1 - 1
vue.config.js

@@ -115,5 +115,5 @@ module.exports = {
     }
   },
 
-  lintOnSave: undefined
+  lintOnSave: false
 }