Browse Source

二期新增

MONSTER-ygh 8 months ago
parent
commit
fc3b1dd5d8
20 changed files with 3322 additions and 195 deletions
  1. 2 0
      package.json
  2. 382 0
      src/views/tourism/membershipManagement/electronicMembership/formBox/makeCradForm.vue
  3. 17 1
      src/views/tourism/membershipManagement/electronicMembership/memberInformation.vue
  4. 0 0
      src/views/tourism/membershipManagement/physicalCard copy/detailsBox/physicalCardAllocationDetails.vue
  5. 296 0
      src/views/tourism/membershipManagement/physicalCard copy/detailsBox/physicalCardManagementDetails.vue
  6. 0 0
      src/views/tourism/membershipManagement/physicalCard copy/formBox/physicalCardAllocationForm.vue
  7. 422 0
      src/views/tourism/membershipManagement/physicalCard copy/formBox/physicalCardManagementForm.vue
  8. 0 0
      src/views/tourism/membershipManagement/physicalCard copy/formBox/setIntegralForm.vue
  9. 0 0
      src/views/tourism/membershipManagement/physicalCard copy/formBox/setStoredValue.vue
  10. 0 0
      src/views/tourism/membershipManagement/physicalCard copy/physicalCardAllocation.vue
  11. 404 0
      src/views/tourism/membershipManagement/physicalCard copy/physicalCardManagement.vue
  12. 16 13
      src/views/tourism/membershipManagement/physicalCard/detailsBox/physicalCardManagementDetails.vue
  13. 379 0
      src/views/tourism/membershipManagement/physicalCard/detailsBox/physicalCardTemplateDetails.vue
  14. BIN
      src/views/tourism/membershipManagement/physicalCard/formBox/fm.jpg
  15. 78 38
      src/views/tourism/membershipManagement/physicalCard/formBox/physicalCardManagementForm.vue
  16. 457 0
      src/views/tourism/membershipManagement/physicalCard/formBox/physicalCardTemplateForm.vue
  17. 536 0
      src/views/tourism/membershipManagement/physicalCard/formBox/printForm.vue
  18. BIN
      src/views/tourism/membershipManagement/physicalCard/formBox/zm.jpg
  19. 70 143
      src/views/tourism/membershipManagement/physicalCard/physicalCardManagement.vue
  20. 263 0
      src/views/tourism/membershipManagement/physicalCard/physicalCardTemplate.vue

+ 2 - 0
package.json

@@ -50,6 +50,7 @@
     "html2canvas": "^1.4.1",
     "js-beautify": "1.13.0",
     "js-cookie": "3.0.1",
+    "jsbarcode": "^3.11.6",
     "jsencrypt": "3.0.0-rc.1",
     "moment": "^2.30.1",
     "nprogress": "0.2.0",
@@ -59,6 +60,7 @@
     "screenfull": "5.0.2",
     "sortablejs": "1.10.2",
     "vue": "2.6.12",
+    "vue-barcode": "^1.3.0",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
     "vue-meta": "2.4.0",

+ 382 - 0
src/views/tourism/membershipManagement/electronicMembership/formBox/makeCradForm.vue

@@ -0,0 +1,382 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="open"
+    width="40%"
+    append-to-body
+    :close-on-click-modal="false"
+    @close="cancel"
+  >
+    <div class="form-dialog-box"
+    v-loading="loading"
+    :element-loading-text="loadingText"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0)">
+      <div
+        v-loading="loading"
+        :element-loading-text="''"
+        element-loading-spinner="''"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+        >
+        <el-form :model="form" ref="form" :rules="rules" label-width="100px">
+          <el-form-item label="持卡人:" prop="memberId">
+            <span>{{ form.name }}</span>
+          </el-form-item>
+          <el-form-item label="卡类型:" prop="cardType">
+            <el-select style="width: 100%;" v-model="form.cardType" @change="selectUser" clearable placeholder="请选择卡类型">
+              <el-option
+                v-for="dict in [{name: '副卡',id: 0},{name: '主卡',id: 1}]"
+                :key="dict.id"
+                :label="dict.name"
+                :value="dict.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="卡号:" prop="cardNo">
+            <el-input v-model="form.cardNo" maxlength="20" show-word-limit autocomplete="off" placeholder="请输入卡号"></el-input>
+          </el-form-item>
+          <el-form-item label="模板:" prop="templateId">
+            <el-select style="width: 100%;" v-model="form.templateId" clearable placeholder="请选择模板">
+              <el-option
+                v-for="dict in mobanList"
+                :key="dict.id"
+                :label="dict.name"
+                :value="dict.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus==1">
+      <el-button @click="cancel">取消</el-button>
+      <el-button
+        type="primary"
+        @click="submitForm"
+        :loading="loading"
+        element-loading-text="提交中..."
+        element-loading-spinner="el-icon-loading"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+      > 
+        {{ loading ? '提交中...' : '保存' }}
+      </el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import { 
+  getTableDeatilsByIdApi,
+  updateTableApi,
+  addTableApi,
+  listTableApi,
+ } from '@/api/CURD'
+
+export default {
+  name: "addAndEdit",
+  dicts: [],
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        add: '/merchant/memberEntitycard/insertOrUpdate', // 新增地址
+        details: '/member/memberInfo/detail', // 详情地址
+        edit: '/merchant/memberEntitycard/insertOrUpdate', // 编辑地址
+        list: '/merchant/merchantEntitycardConfig/pageList', // 实体卡类型
+        codeList: '/merchant/merchantAuth/getVerifyCode', // 获取验证码
+        merchantRealAuth: '/merchant/merchantAuth/merchantRealAuth', // 验证
+        moban: '/merchant/templateEntitycard/pageList',
+      },
+      form: {
+        id: undefined,
+      },
+      rules: {
+        cardType: [{ required: true, message: "请选择卡类型", trigger: ["change","blur"] }],
+        cardNo: [
+          { required: true, message: "请输入卡号", trigger: ["change","blur"] },
+          { pattern: /^[0-9]*$/, message: '卡号必须全为数字', trigger: ["change","blur"]}
+        ],
+        memberId: [{ required: true, message: "请输入持卡人", trigger: ["change","blur"] }],
+        templateId: [{ required: true, message: "请选择模板", trigger: ["change","blur"] }],
+      },
+      scenicAreaProducts: [],// 景点产品关联
+
+      tableList: [], // 实体卡类型
+      tableUseList: [], // 用户
+      mobanList: [], // 模板list
+      phoneCodeLoading: 0,
+      
+    };
+  },
+  created() {
+    this.getMobanList()
+  },
+  methods: {
+    /** 查询体卡类型列表 */
+    getMobanList() {
+      listTableApi(
+        this.configUrl.moban,
+        this.addDateRange({
+          pageNum: 1,
+          pageSize: 9999,
+        })).then(response => {
+              this.mobanList = response.data.rows;
+          }
+        ).catch (error=>{
+          this.mobanList = [];
+        }) 
+    },
+    async initData(title , model,row){
+      this.title = title
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.actionUrlLoading = false
+      this.model = model
+      this.formStatus = 0
+      this.phoneCodeLoading = 0
+      if(model=='ADD') { // 新增
+        this.$set(this,'form',{...row,logo:[]})
+        this.formStatus = 1
+      }else if(model=='EDIT') { // 新增
+        let obj = {
+          ...row,
+          logo: row.logo?row.logo.split(','):[]
+        }
+        this.$set(this,'form',obj)
+        this.formStatus = 1
+      }else if(model=='EDITInit') { // 新增
+        await this.getTableDeatilsFun(row)
+      }
+      this.loading = false
+      this.$nextTick(()=>{
+        if(this.$refs["form"]) {
+          this.$refs["form"].clearValidate();
+        }
+      })
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details,{id})
+        if(res.code == 200) {
+          let obj = {
+            ...res.data,
+        }
+          this.$set(this,'form',{
+            memberId: res.data.id,
+            name: res.data.name
+          })
+          this.formStatus = 1
+        }else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+          this.open = false;
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!',error)
+        this.formStatus = 2
+        this.loading = false
+        this.open = false;
+      }
+    },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    submitForm() {
+      this.$refs["form"].validate(async valid => {
+        if (valid) {
+          this.loadingText = "提交数据中..."
+          this.loading = true
+          try {
+            let res = await addTableApi(this.configUrl.edit,{...this.form})
+              if(res.code == 200) {
+                this.$modal.msgSuccess("制卡成功");
+                this.loading = false
+                this.open = false;
+                this.$emit('refresh')
+              }else {
+                this.$message.error("制卡失败!!!");
+                this.loading = false
+              }
+          } catch (error) {
+            this.$message.error(`制卡失败!!!`);
+            this.loading = false
+          }
+          
+        }
+      });
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if(this.$refs["form"]) {
+        this.$refs["form"].clearValidate();
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+  .form-title {
+    padding: 0 0 10px 0;
+    span {
+      display: flex;
+      color: rgba(65,80,88,1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+    
+  }
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+.el-table{
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+    .el-input__inner {
+      display: none !important;
+    }
+    span.el-input__suffix {
+      position: inherit !important;
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 100px;
+    height: 100px;
+    display: block;
+  }
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

+ 17 - 1
src/views/tourism/membershipManagement/electronicMembership/memberInformation.vue

@@ -134,6 +134,13 @@
                   @click="handleDetails(scope.row)"
                   v-hasPermi="configPermi.details"
                 >详情</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleMakeCrad(scope.row)"
+                  v-hasPermi="configPermi.make"
+                >制卡</el-button>
                 <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
                     <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
                     <el-dropdown-menu slot="dropdown">
@@ -162,6 +169,7 @@
       <setIntegralForm ref="setIntegralForm" @refresh="getList" />
 
       <setStoredValue ref="setStoredValue" @refresh="getList" />
+      <makeCradForm ref="makeCradForm" @refresh="getList" />
     </div>
   </template>
   
@@ -174,10 +182,11 @@
   import detailsBox from "./detailsBox/memberInformationDetails.vue"
   import setIntegralForm from "./formBox/setIntegralForm.vue"
   import setStoredValue from "./formBox/setStoredValue.vue"
+  import makeCradForm from "./formBox/makeCradForm.vue";
   export default {
     name: "User",
     dicts: ['tourism_memberInformation_user_type','tourism_memberInformation_status','tourism_memberInformation_sex'],
-    components: {detailsBox,setIntegralForm,setStoredValue},
+    components: {detailsBox,setIntegralForm,setStoredValue,makeCradForm},
     data() {
       return {
         title: "会员信息",// 通用标题
@@ -190,6 +199,7 @@
           export: ['electronicMembership:memberInformation:export'],// 导出权限
           resetPwd: ['electronicMembership:memberInformation:resetPwd'], // 设置积分
           AuthRole: ['electronicMembership:memberInformation:AuthRole'], // 设置储值
+          make: ['electronicMembership:memberInformation:make'],
         },
         configUrl: {
           list: '/member/memberInfo/list', // 列表地址
@@ -315,6 +325,12 @@
           this.$refs.detailsBox.initData(this.title + '详情', "EDITInit",{...row})
         }
       },
+      /** 制卡  */
+      handleMakeCrad(row) {
+        if(this.$refs.makeCradForm) {
+          this.$refs.makeCradForm.initData(this.title + '--制卡', "EDITInit",{...row})
+        }
+      },
       /** 删除按钮操作 */
       handleDelete(row) {
         const ids = row.id || this.ids;

src/views/tourism/membershipManagement/physicalCard/detailsBox/physicalCardAllocationDetails.vue → src/views/tourism/membershipManagement/physicalCard copy/detailsBox/physicalCardAllocationDetails.vue


+ 296 - 0
src/views/tourism/membershipManagement/physicalCard copy/detailsBox/physicalCardManagementDetails.vue

@@ -0,0 +1,296 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="open"
+    width="50%"
+    append-to-body
+    :close-on-click-modal="false"
+    @close="cancel"
+  >
+    <div class="form-dialog-box"
+    v-loading="loading"
+    :element-loading-text="loadingText"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0)">
+      <div
+        v-loading="loading"
+        :element-loading-text="''"
+        element-loading-spinner="''"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+        >
+        <el-form :model="form" ref="form" :rules="rules" label-width="200px">
+          <div class="form-title"><span>基本信息</span></div>
+          <el-form-item label="实体卡号:" prop="cardNo">
+            <span>{{ form.cardNo }}</span>
+          </el-form-item>
+          <el-form-item label="办卡类型:" prop="cardName">
+            <span>{{ form.cardName }}</span>
+          </el-form-item>
+          <el-form-item label="持卡人:" prop="userName">
+            <span>{{ form.userName }}</span>
+          </el-form-item>
+          <el-form-item label="身份证号:" prop="idCard">
+            <span>{{ form.idCard }}</span>
+          </el-form-item>
+          <el-form-item label="手机号:" prop="phone">
+            <span>{{ form.phone }}</span>
+          </el-form-item>
+          <el-form-item label="可退金额:" prop="refundAmount">
+            <span>{{ form.refundAmount }}</span>
+          </el-form-item>
+          <el-form-item label="余额:" prop="amount">
+            <span>{{ form.amount }}</span>
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus==1">
+      <el-button @click="cancel">关闭</el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import { 
+  getTableDeatilsByIdApi,
+ } from '@/api/CURD'
+
+export default {
+  name: "addAndEdit",
+  dicts: ['tourism_memberInformation_sex','tourism_memberInformation_user_type'],
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        add: '', // 新增地址
+        details: '/merchant/merchantEntitycard/selectById', // 详情地址
+        edit: '', // 编辑地址
+      },
+      form: {
+        id: undefined,
+      },
+      rules: {},
+      scenicAreaProducts: [],// 景点产品关联
+    };
+  },
+  methods: {
+    async initData(title , model,row){
+      this.title = title
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.actionUrlLoading = false
+      this.model = model
+      this.formStatus = 0
+      if(model=='ADD') { // 新增
+        this.$set(this,'form',{...row})
+        this.formStatus = 1
+      }else if(model=='EDIT') { // 新增
+        let obj = {
+          ...row,
+        }
+        this.$set(this,'form',obj)
+        this.formStatus = 1
+      }else if(model=='EDITInit') { // 新增
+        await this.getTableDeatilsFun(row)
+      }
+      this.loading = false
+      this.$nextTick(()=>{
+        if(this.$refs["form"]) {
+          this.$refs["form"].clearValidate();
+        }
+      })
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details,{id})
+        if(res.code == 200) {
+          let obj = {
+            ...res.data,
+        }
+          this.$set(this,'form',JSON.parse(JSON.stringify(obj)))
+          this.formStatus = 1
+        }else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+          this.open = false;
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!',error)
+        this.formStatus = 2
+        this.loading = false
+        this.open = false;
+      }
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if(this.$refs["form"]) {
+        this.$refs["form"].clearValidate();
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+  .form-title {
+    padding: 0 0 10px 0;
+    span {
+      display: flex;
+      color: rgba(65,80,88,1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+    
+  }
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+.el-table{
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+    .el-input__inner {
+      display: none !important;
+    }
+    span.el-input__suffix {
+      position: inherit !important;
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 100px;
+    height: 100px;
+    display: block;
+  }
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

src/views/tourism/membershipManagement/physicalCard/formBox/physicalCardAllocationForm.vue → src/views/tourism/membershipManagement/physicalCard copy/formBox/physicalCardAllocationForm.vue


+ 422 - 0
src/views/tourism/membershipManagement/physicalCard copy/formBox/physicalCardManagementForm.vue

@@ -0,0 +1,422 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="open"
+    width="50%"
+    append-to-body
+    :close-on-click-modal="false"
+    @close="cancel"
+  >
+    <div class="form-dialog-box"
+    v-loading="loading"
+    :element-loading-text="loadingText"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0)">
+      <div
+        v-loading="loading"
+        :element-loading-text="''"
+        element-loading-spinner="''"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+        >
+        <el-form :model="form" ref="form" :rules="rules" label-width="200px">
+          <div class="form-title"><span>基本信息</span></div>
+          <el-form-item label="办卡类型:" prop="entityCardConfigId">
+            <el-select style="width: 100%;" v-model="form.entityCardConfigId" clearable placeholder="请选择卡类型">
+              <el-option
+                v-for="dict in tableList"
+                :key="dict.id"
+                :label="dict.cardName"
+                :value="dict.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="持卡人:" prop="userName">
+            <el-input v-model="form.userName" controls-position="right" placeholder="请输入持卡人"></el-input>
+          </el-form-item>
+          <el-form-item label="身份证号:" prop="idCard">
+            <el-input v-model="form.idCard" controls-position="right" placeholder="请输入身份证号"></el-input>
+          </el-form-item>
+          <el-form-item label="手机号:" prop="phone">
+            <div style="display: flex;">
+              <el-input v-model="form.phone" controls-position="right" placeholder="请输入手机号"></el-input>
+              <el-button @click="getCode" style="margin-left: 20px;" type="primary" :loading="phoneCodeLoading == 1">{{ phoneCodeLoading == 1 ? '获取中...' : phoneCodeLoading == 0 ? '获取验证码' : '已发送成功,重新获取' }}</el-button>
+            </div>
+          </el-form-item>
+          <el-form-item label="短信验证码:" prop="code">
+            <el-input v-model="form.code" controls-position="right" placeholder="请输入短信验证码"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus==1">
+      <el-button @click="cancel">取消</el-button>
+      <el-button
+        type="primary"
+        @click="submitForm"
+        :loading="loading"
+        element-loading-text="提交中..."
+        element-loading-spinner="el-icon-loading"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+      > 
+        {{ loading ? '提交中...' : '保存' }}
+      </el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import { 
+  getTableDeatilsByIdApi,
+  updateTableApi,
+  addTableApi,
+  listTableApi,
+ } from '@/api/CURD'
+
+export default {
+  name: "addAndEdit",
+  dicts: [],
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        add: '/merchant/merchantEntitycard/insertOrUpdate', // 新增地址
+        details: '/merchant/merchantEntitycard/selectById', // 详情地址
+        edit: '/merchant/merchantEntitycard/insertOrUpdate', // 编辑地址
+        list: '/merchant/merchantEntitycardConfig/pageList', // 实体卡类型
+        codeList: '/merchant/merchantAuth/getVerifyCode', // 获取验证码
+        merchantRealAuth: '/merchant/merchantAuth/merchantRealAuth', // 验证
+      },
+      form: {
+        id: undefined,
+      },
+      rules: {
+        entityCardConfigId: [{ required: true, message: "请选择办卡类型", trigger: ["change","blur"] }],
+        userName: [{ required: true, message: "请输入持卡人", trigger: ["change","blur"] }],
+        idCard: [{ required: true, message: "请输入身份证号", trigger: ["change","blur"] }],
+        phone: [
+          { required: true, trigger: ["change","blur"], message: "请输入您的账号" },
+          { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: ["change","blur"] }
+        ],
+        code: [{ required: true, message: "请输入短信验证码", trigger: ["change","blur"] }],
+      },
+      scenicAreaProducts: [],// 景点产品关联
+
+      tableList: [], // 实体卡类型
+
+      phoneCodeLoading: 0
+    };
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 查询体卡类型列表 */
+    getList() {
+      listTableApi(
+        this.configUrl.list,
+        this.addDateRange({
+          pageNum: 1,
+          pageSize: 9999,
+        })).then(response => {
+              this.tableList = response.data.rows;
+          }
+        ).catch (error=>{
+          this.tableList = [];
+        }) 
+    },
+    async initData(title , model,row){
+      this.title = title
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.actionUrlLoading = false
+      this.model = model
+      this.formStatus = 0
+      this.phoneCodeLoading = 0
+      if(model=='ADD') { // 新增
+        this.$set(this,'form',{...row,logo:[]})
+        this.formStatus = 1
+      }else if(model=='EDIT') { // 新增
+        let obj = {
+          ...row,
+          logo: row.logo?row.logo.split(','):[]
+        }
+        this.$set(this,'form',obj)
+        this.formStatus = 1
+      }else if(model=='EDITInit') { // 新增
+        await this.getTableDeatilsFun(row)
+      }
+      this.loading = false
+      this.$nextTick(()=>{
+        if(this.$refs["form"]) {
+          this.$refs["form"].clearValidate();
+        }
+      })
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details,{id})
+        if(res.code == 200) {
+          let obj = {
+            ...res.data,
+        }
+          this.$set(this,'form',JSON.parse(JSON.stringify(obj)))
+          this.formStatus = 1
+        }else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+          this.open = false;
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!',error)
+        this.formStatus = 2
+        this.loading = false
+        this.open = false;
+      }
+    },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    submitForm() {
+      this.$refs["form"].validate(async valid => {
+        if (valid) {
+          this.loadingText = "提交数据中..."
+          this.loading = true
+          try {
+            let resCode = await addTableApi(
+              this.configUrl.merchantRealAuth,
+              this.addDateRange({
+                idCard: this.form.idCard,
+                userName: this.form.userName,
+            }))
+            if(resCode.code == 200) {
+
+            }else {
+              return
+            }
+            if (this.model != 'ADD') {
+              let res = await addTableApi(this.configUrl.edit,{...this.form})
+              if(res.code == 200) {
+                this.$modal.msgSuccess("修改成功");
+                this.loading = false
+                this.open = false;
+                this.$emit('refresh')
+              }else {
+                this.$message.error("修改失败!!!");
+                this.loading = false
+              }
+            } else {
+              let res = await addTableApi(this.configUrl.edit,{...this.form})
+              if(res.code == 200) {
+                this.$modal.msgSuccess("新增成功");
+                this.loading = false
+                this.open = false;
+                this.$emit('refresh')
+              }else {
+                this.$message.error("新增失败!!!");
+                this.loading = false
+              }
+            }
+          } catch (error) {
+            this.$message.error(`${this.form.id?'修改':'新增'}失败!!!`);
+            this.loading = false
+          }
+          
+        }
+      });
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if(this.$refs["form"]) {
+        this.$refs["form"].clearValidate();
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+    /**
+     * 获取验证码
+     */
+     getCode() {
+      if(this.phoneCodeLoading == 1) return
+      let reg = /^1[3-9]\d{9}$/
+      if(!reg.test(this.form.phone)) {
+        this.$message.error("手机号输入不正确!!!");
+        return
+      }
+      this.phoneCodeLoading = 1
+      addTableApi(
+        this.configUrl.codeList,
+        this.addDateRange({
+          phone: this.form.phone,
+        })).then(response => {
+          this.phoneCodeLoading = 2
+        }).catch (error=>{
+          this.phoneCodeLoading = 0
+        }) 
+     },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+  .form-title {
+    padding: 0 0 10px 0;
+    span {
+      display: flex;
+      color: rgba(65,80,88,1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+    
+  }
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+.el-table{
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+    &-text {
+      margin-top: -10px;
+    }
+  }
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+    .el-input__inner {
+      display: none !important;
+    }
+    span.el-input__suffix {
+      position: inherit !important;
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+::v-deep .avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  ::v-deep .avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  ::v-deep .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+  }
+  ::v-deep .avatar {
+    width: 100px;
+    height: 100px;
+    display: block;
+  }
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

src/views/tourism/membershipManagement/physicalCard/formBox/setIntegralForm.vue → src/views/tourism/membershipManagement/physicalCard copy/formBox/setIntegralForm.vue


src/views/tourism/membershipManagement/physicalCard/formBox/setStoredValue.vue → src/views/tourism/membershipManagement/physicalCard copy/formBox/setStoredValue.vue


src/views/tourism/membershipManagement/physicalCard/physicalCardAllocation.vue → src/views/tourism/membershipManagement/physicalCard copy/physicalCardAllocation.vue


+ 404 - 0
src/views/tourism/membershipManagement/physicalCard copy/physicalCardManagement.vue

@@ -0,0 +1,404 @@
+<template>
+    <div class="app-container">
+      <el-row :gutter="20">
+        <!--用户数据-->
+        <el-col :span="24" :xs="24">
+          <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+            <el-form-item label="卡号" prop="cardNo">
+              <el-input
+                v-model="queryParams.cardNo"
+                placeholder="请输入卡号"
+                clearable
+                style="width: 240px"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+            <el-form-item label="持卡人" prop="userName">
+              <el-input
+                v-model="queryParams.userName"
+                placeholder="请输入持卡人"
+                clearable
+                style="width: 240px"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+            <el-form-item label="手机号" prop="phone">
+              <el-input
+                v-model="queryParams.phone"
+                placeholder="请输入手机号"
+                clearable
+                style="width: 240px"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+            <el-form-item label="卡类型" prop="entityCardConfigId">
+              <el-select v-model="queryParams.entityCardConfigId" clearable placeholder="请选择卡类型">
+                <el-option
+                  v-for="dict in tableListCopy"
+                  :key="dict.id"
+                  :label="dict.cardName"
+                  :value="dict.id">
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+              <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+  
+          <el-row :gutter="10" class="mb8">
+            <el-col :span="1.5">
+              <el-button
+                type="primary"
+                plain
+                icon="el-icon-plus"
+                size="mini"
+                @click="handleAdd"
+                v-hasPermi="configPermi.add"
+              >添加新卡</el-button>
+            </el-col>
+            <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
+          </el-row>
+  
+          <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
+            <el-table-column type="index" label="序号" align="center"  />
+            <el-table-column label="卡号" align="center" key="cardNo" prop="cardNo" v-if="columns[0].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="持卡人" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="手机号" align="center" key="phone" prop="phone" v-if="columns[2].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="卡类型" align="center" key="cardName" prop="cardName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="激活时间" align="center" key="effectiveDate" prop="effectiveDate" v-if="columns[4].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="使用期限" align="center" key="useType" prop="useType" v-if="columns[5].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <span>{{ setUseType(scope.row) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="卡余额" align="center" key="amount" prop="amount" v-if="columns[6].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="卡积分" align="center" key="credit" prop="credit" v-if="columns[7].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="充值余额" align="center" key="storageAmount" prop="storageAmount" v-if="columns[8].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="卡状态" align="center" key="cardStatus" prop="cardStatus" v-if="columns[9].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <dict-tag :options="dict.type.tourism_physicalCardManagement_cardStatus" :value="scope.row.cardStatus"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="禁用/启用" align="center" key="status1" prop="status1" v-if="columns[10].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                <switchBox 
+                :defaultChecked="true" 
+                v-model="scope.row.status" 
+                @changeFun="openAttraction(scope.row)" 
+                :disabled="false"
+                :active-value="1"
+                :inactive-value="0"
+                 />
+              </template>
+            </el-table-column>
+            <el-table-column label="最近消费时间" align="center" key="newOrderTime" prop="newOrderTime" v-if="columns[11].visible" :show-overflow-tooltip="true" />
+            <el-table-column
+              label="操作"
+              align="center"
+              width="160"
+              class-name="small-padding fixed-width"
+            >
+              <template slot-scope="scope" >
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-document"
+                  @click="handleDetails(scope.row)"
+                  v-hasPermi="configPermi.details"
+                >详情</el-button>
+                <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
+                    <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
+                    <el-dropdown-menu slot="dropdown">
+                        <el-dropdown-item command="handleResetPwd" icon="el-icon-key"
+                        v-hasPermi="configPermi.resetPwd">设置积分</el-dropdown-item>
+                        <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check"
+                        v-hasPermi="configPermi.AuthRole">设置储值</el-dropdown-item>
+                        <el-dropdown-item command="handleEdit" icon="el-icon-circle-check"
+                        v-hasPermi="configPermi.edit">编辑</el-dropdown-item>
+                        <el-dropdown-item command="handleResetPassword" icon="el-icon-circle-check"
+                        v-hasPermi="configPermi.Password">重置密码</el-dropdown-item>
+                    </el-dropdown-menu>
+                </el-dropdown>
+              </template>
+            </el-table-column>
+          </el-table>
+  
+          <pagination
+            v-show="total>0"
+            :total="total"
+            :page.sync="queryParams.pageNum"
+            :limit.sync="queryParams.pageSize"
+            @pagination="getList"
+          />
+        </el-col>
+      </el-row>
+      <!--  新增或修改  -->
+      <addAndEdit ref="addAndEdit" @refresh="getList" />
+      <!--  详情 -->
+      <detailsBox ref="detailsBox" />
+
+      <setIntegralForm ref="setIntegralForm" @refresh="getList" />
+
+      <setStoredValue ref="setStoredValue" @refresh="getList" />
+    </div>
+  </template>
+  
+  <script>
+  import { 
+    listTableApi, 
+    delTableParamsApi,
+    updateTableApi
+  } from "@/api/CURD";
+  import addAndEdit from "./formBox/physicalCardManagementForm.vue"
+  import detailsBox from "./detailsBox/physicalCardManagementDetails.vue"
+  import setIntegralForm from "./formBox/setIntegralForm.vue"
+  import setStoredValue from "./formBox/setStoredValue.vue"
+  export default {
+    name: "User",
+    dicts: ['tourism_IntegralRecord_cardType','tourism_physicalCardManagement_cardStatus'],
+    components: {addAndEdit,detailsBox,setIntegralForm,setStoredValue},
+    data() {
+      return {
+        title: "实体卡管理",// 通用标题
+        configPermi: {
+          add: ['physicalCard:physicalCardManagement:add'], // 新增权限
+          details: ['physicalCard:physicalCardManagement:details'], // 详情权限
+          delect: ['physicalCard:physicalCardManagement:delect'], // 删除权限
+          edit: ['physicalCard:physicalCardManagement:edit'], // 编辑权限
+          upload: [''],// 导入权限
+          export: [''],// 导出权限
+          resetPwd: ['physicalCard:physicalCardManagement:resetPwd'],// 设置积分
+          AuthRole: ['physicalCard:physicalCardManagement:AuthRole'],// 设置储值
+          Password: ['physicalCard:physicalCardManagement:Password'], // 重置密码
+        },
+        configUrl: {
+          list: '/merchant/merchantEntitycard/pageList', // 列表地址
+          delect: '', // 删除地址
+          upload: '',// 导入地址
+          download:'', // 下载模板地址
+          export: '',// 导出地址
+          updateStatus: '/merchant/merchantEntitycard/updateStatus', // 编辑地址
+          resetPassword: '/merchant/merchantEntitycard/resetPassword',
+          listCopy: '/merchant/merchantEntitycardConfig/pageList'
+        },
+        // 遮罩层
+        loading: true,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 总条数
+        total: 0,
+        // 用户表格数据
+        tableList: null,
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+        },
+        dateRange: [],
+        // 控制列表是否显示
+        columns: [
+          { key: 0, label: `卡号`, visible: true },
+          { key: 1, label: `持卡人`, visible: true },
+          { key: 2, label: `手机号`, visible: true },
+          { key: 3, label: `卡类型`, visible: true },
+          { key: 4, label: `身份证号`, visible: true },
+          { key: 5, label: `激活时间`, visible: true },
+          { key: 6, label: `卡余额`, visible: true },
+          { key: 7, label: `卡积分`, visible: true },
+          { key: 8, label: `充值余额`, visible: true },
+          { key: 9, label: `状态`, visible: true },
+          { key: 10, label: `禁用/启用`, visible: true },
+          { key: 11, label: `最近消费时间`, visible: true },
+        ],
+        tableListCopy: []// 实体卡类型
+      };
+    },
+    created() {
+      this.getListCopy()
+      this.getList();
+    },
+    methods: {
+      /** 查询实体卡类型列表 */
+      getListCopy() {
+        listTableApi(
+          this.configUrl.listCopy,
+          this.addDateRange(
+            this.queryParams, 
+            this.dateRange)).then(response => {
+              this.tableListCopy = response.data.rows;
+          }
+        ).catch (error=>{
+          console.error('获取列表失败!!!!',error)
+          this.tableListCopy = [];
+        }) 
+      },
+      /** 查询用户列表 */
+      getList() {
+        this.loading = true;
+        listTableApi(
+          this.configUrl.list,
+          this.addDateRange(
+            this.queryParams, 
+            this.dateRange)).then(response => {
+              this.tableList = response.data.rows;
+              this.total = response.data.total;
+              this.loading = false;
+          }
+        ).catch (error=>{
+          console.error('获取列表失败!!!!',error)
+          this.tableList = [];
+          this.total = 0;
+          this.loading = false
+        }) 
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.dateRange = [];
+        this.queryParams = {
+          pageNum: 1,
+          pageSize: 10,
+        }
+        this.handleQuery();
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map(item => item.id);
+        this.single = selection.length != 1;
+        this.multiple = !selection.length;
+      },
+      /** 新增按钮操作 */
+      handleAdd() {
+        if(this.$refs.addAndEdit) {
+          this.$refs.addAndEdit.initData(this.title + '新增', "ADD",{})
+        }
+      },
+      /** 修改按钮操作 */
+      handleUpdate(row) {
+        if(this.$refs.addAndEdit) {
+          this.$refs.addAndEdit.initData(this.title + '编辑', "EDITInit",{...row})
+        }
+      },
+      handleDetails(row){
+        if(this.$refs.detailsBox) {
+          this.$refs.detailsBox.initData(this.title + '详情', "EDITInit",{...row})
+        }
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        const ids = row.id || this.ids;
+        this.$modal.confirm('是否确认删除数据项?').then( () => {
+          return delTableParamsApi(this.configUrl.delect,{
+            id: ids
+          });
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        }).catch((e) => {
+          console.error("删除失败====",e)
+        });
+      },
+      /** 导出按钮操作 */
+      handleExport() {
+        this.download(this.configUrl.export, {
+          ...this.queryParams
+        }, `${this.title }_${new Date().getTime()}.xlsx`)
+      },
+      /** 导入按钮操作 */
+      handleImport() {
+        if(this.$refs.upload) {
+          this.$refs.upload.initData({
+            width: '400px',
+            // 弹出层标题(用户导入)
+            title: this.title + "导入",
+            // 下载模板地址
+            importTemplate: this.configUrl.download,
+            // 上传的地址
+            url: this.configUrl.upload
+          })
+        }
+      },
+      /** 开/闭 园 */
+      openAttraction(row) {
+        this.$modal.confirm(`是否确认${row.status == 0 ? '启用' : '禁用'} ${row.cardNo||''}吗?`).then( () => {
+          return updateTableApi(this.configUrl.updateStatus,{
+            id: row.id,
+            status: row.status == 1 ? 0 : 1
+          });
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess(`${row.status == 0 ? '启用' : '禁用'}成功`);
+        }).catch((e) => {
+          console.error("失败====",e)
+        });
+      },
+      /**  重置密码   */
+      handleResetPassword(row){
+        this.$modal.confirm(`是否确认重置卡号 ${row.cardNo||''}的密码为000000吗?`).then( () => {
+          return updateTableApi(this.configUrl.resetPassword,{
+            id: row.id,
+          });
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess(`重置成功`);
+        }).catch((e) => {
+          console.error("失败====",e)
+        });
+      },
+        handleResetPwd(row) {
+            if(this.$refs.setIntegralForm) {
+            this.$refs.setIntegralForm.initData('设置积分', "EDIT",{...row})
+            }
+        },
+        handleAuthRole(row) {
+            if(this.$refs.setStoredValue) {
+            this.$refs.setStoredValue.initData('设置储值', "EDIT",{...row})
+            }
+        },
+        // 更多操作触发
+        handleCommand(command, row) {
+          switch (command) {
+              case "handleResetPwd":
+              this.handleResetPwd(row);
+              break;
+              case "handleAuthRole":
+              this.handleAuthRole(row);
+              break;
+              case "handleEdit":
+              this.handleUpdate(row);
+              break;
+              case "handleResetPassword":
+              this.handleResetPassword(row);
+              break;
+              default:
+              break;
+          }
+        },
+        /** 设置使用期限  */
+        setUseType(row){
+          if(row.useType == 1) {
+            return '永久生效'
+          }else if(row.useType == 2) {
+            return '' + (row.useDay || '') + '天有效'
+          }else if(row.useType == 3) {
+            return '' + row.useEndDay + '内有效'
+          }else{
+            return '--'
+          }
+        },
+    }
+  };
+  </script>
+  

+ 16 - 13
src/views/tourism/membershipManagement/physicalCard/detailsBox/physicalCardManagementDetails.vue

@@ -23,23 +23,26 @@
           <el-form-item label="实体卡号:" prop="cardNo">
             <span>{{ form.cardNo }}</span>
           </el-form-item>
-          <el-form-item label="办卡类型:" prop="cardName">
-            <span>{{ form.cardName }}</span>
+          <el-form-item label="卡类型:" prop="cardType">
+            <span>{{ form.cardType==0 ? '副卡': form.cardType==1 ? '主卡': '--'}}</span>
           </el-form-item>
-          <el-form-item label="持卡人:" prop="userName">
-            <span>{{ form.userName }}</span>
+          <el-form-item label="持卡人:" prop="name">
+            <span>{{ form.name }}</span>
           </el-form-item>
-          <el-form-item label="身份证号:" prop="idCard">
-            <span>{{ form.idCard }}</span>
+          <el-form-item label="身份证号:" prop="idcard">
+            <span>{{ form.idcard }}</span>
           </el-form-item>
-          <el-form-item label="手机号:" prop="phone">
-            <span>{{ form.phone }}</span>
+          <el-form-item label="手机号:" prop="mobile">
+            <span>{{ form.mobile }}</span>
           </el-form-item>
-          <el-form-item label="可退金额:" prop="refundAmount">
-            <span>{{ form.refundAmount }}</span>
+          <el-form-item label="制卡时间:" prop="lastProductTime">
+            <span>{{ form.lastProductTime }}</span>
           </el-form-item>
-          <el-form-item label="余额:" prop="amount">
-            <span>{{ form.amount }}</span>
+          <el-form-item label="最后一次消费时间:" prop="lastConsumeTime">
+            <span>{{ form.lastConsumeTime }}</span>
+          </el-form-item>
+          <el-form-item label="模板名称:" prop="templateName">
+            <span>{{ form.templateName }}</span>
           </el-form-item>
         </el-form>
       </div>
@@ -69,7 +72,7 @@ export default {
       formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
       configUrl: {
         add: '', // 新增地址
-        details: '/merchant/merchantEntitycard/selectById', // 详情地址
+        details: '/merchant/memberEntitycard/selectById', // 详情地址
         edit: '', // 编辑地址
       },
       form: {

+ 379 - 0
src/views/tourism/membershipManagement/physicalCard/detailsBox/physicalCardTemplateDetails.vue

@@ -0,0 +1,379 @@
+<template>
+  <el-dialog 
+  :title="title" 
+  :visible.sync="open" 
+  width="70%" 
+  append-to-body 
+  :close-on-click-modal="false"
+    @close="cancel">
+    <div class="form-dialog-box" v-loading="loading" :element-loading-text="loadingText"
+      element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0)">
+      <div class="form-make">
+        <div class="form-make_zm">
+          <div class="form-make_zm-title">正面</div>
+          <div class="form-make_zm-info">
+            <!-- 工具  -->
+            <div class="form-make_zm-title"></div>
+            <!-- 样式  -->
+            <div class="form-make_zm-style">
+
+            </div>
+          </div>
+        </div>
+
+      </div>
+      
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus == 1">
+      <el-button @click="cancel" :loading="loading">关闭</el-button>
+      <el-button 
+      type="primary" 
+      @click="submitForm(true)" 
+      :loading="loading">
+              {{ loading ? '提交中...' : '提交' }}
+      </el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import {
+  getTableDeatilsByIdApi,
+  updateTableApi,
+  addTableApi
+} from '@/api/CURD'
+
+export default {
+  name: "addAndEdit",
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        add: '/merchant/merchantEntitycardConfig/insertOrUpdate', // 新增地址
+        details: '/merchant/merchantEntitycardConfig/selectById', // 规格详情
+        edit: '/merchant/merchantEntitycardConfig/insertOrUpdate', // 编辑地址
+      },
+      performId: null,
+      form: {
+        id: undefined,
+      },
+      rules: {},
+
+    };
+  },
+  methods: {
+    async initData(title, model, row) {
+      this.title = title
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.actionUrlLoading = false
+      this.model = model
+      this.formStatus = 0
+      if(model=='ADD') { // 新增
+        this.$set(this,'form',{
+          ...row,
+        })
+        this.formStatus = 1
+      }else if(model=='EDIT') { // 新增
+        let obj = {
+          ...row
+        }
+        this.$set(this,'form',obj)
+        this.formStatus = 1
+      }else if(model=='EDITInit') { // 新增
+        await this.getTableDeatilsFun(row)
+      }
+      this.loading = false
+      this.$nextTick(()=>{
+        if(this.$refs["form"]) {
+          this.$refs["form"].clearValidate();
+        }
+      })
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details, { id })
+        if (res.code == 200) {
+          let obj = {
+            ...res.data,
+          }
+          this.$set(this, 'form', JSON.parse(JSON.stringify(obj)))
+          this.formStatus = 1
+        } else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!', error)
+        this.formStatus = 2
+        this.loading = false
+      }
+    },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    submitForm(type) {
+      console.log("dsfsfds=======", type, this.form)
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.loadingText = "提交数据中..."
+          this.loading = true
+          let params = JSON.parse(JSON.stringify(this.form))
+          addTableApi(this.configUrl.edit, {
+            ...params,
+            activationRule: params.activationRule?params.activationRule.join(','):null,
+          }).then(response => {
+            this.$modal.msgSuccess(`${this.form.id ? '编辑' : '新增'}成功`);
+            this.loading = false
+            this.$set(this, 'form', {activationRule:[]})
+            this.$nextTick(() => {
+              this.$refs.form.clearValidate();
+            })
+            this.open = false;
+            this.$emit('refresh')
+          }).catch(() => {
+            this.$message.error(`${this.form.id ? '编辑' : '新增'}失败!!!`);
+            this.loading = false
+          })
+        }
+      });
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if (this.$refs["form"]) {
+        //this.$refs["form"].resetFields();
+        this.$set(this, 'form', {activationRule:[]})
+        this.$nextTick(() => {
+          this.$refs["form"].clearValidate();
+        })
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+
+  .form-title {
+    padding: 0 0 10px 0;
+
+    span {
+      display: flex;
+      color: rgba(65, 80, 88, 1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+
+  }
+
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.el-table {
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+
+    .el-input__inner {
+      display: none !important;
+    }
+
+    span.el-input__suffix {
+      position: inherit !important;
+
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+
+::v-deep .avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+::v-deep .avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+
+::v-deep .avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 100px;
+  height: 100px;
+  line-height: 100px;
+  text-align: center;
+}
+
+::v-deep .avatar {
+  width: 100px;
+  height: 100px;
+  display: block;
+}
+
+
+.form-make {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+  .form-make_zm {
+    display: flex;
+    height: 600px;
+    .form-make_zm-title {
+      width: 20px;
+      height: 100%;
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: center;
+      font-size: 24px;
+      font-family: 600;
+      padding: 20px 20px;
+      box-sizing: border-box;
+    }
+    .form-make_zm-info {
+      width: 860px;
+      height: 100%;
+      .form-make_zm-title{
+
+      }
+      .form-make_zm-style {
+        width: 100%;
+        height: 540px;
+        border: 1px dashed #000;
+      }
+    }
+  }
+}
+
+
+
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

BIN
src/views/tourism/membershipManagement/physicalCard/formBox/fm.jpg


+ 78 - 38
src/views/tourism/membershipManagement/physicalCard/formBox/physicalCardManagementForm.vue

@@ -20,23 +20,40 @@
         >
         <el-form :model="form" ref="form" :rules="rules" label-width="200px">
           <div class="form-title"><span>基本信息</span></div>
-          <el-form-item label="办卡类型:" prop="entityCardConfigId">
-            <el-select style="width: 100%;" v-model="form.entityCardConfigId" clearable placeholder="请选择卡类型">
+          <el-form-item label="卡类型:" prop="cardType">
+            <el-select style="width: 100%;" v-model="form.cardType" @change="selectUser" clearable placeholder="请选择卡类型">
               <el-option
-                v-for="dict in tableList"
+                v-for="dict in [{name: '副卡',id: 0},{name: '主卡',id: 1}]"
                 :key="dict.id"
-                :label="dict.cardName"
+                :label="dict.name"
                 :value="dict.id">
               </el-option>
             </el-select>
           </el-form-item>
-          <el-form-item label="持卡人:" prop="userName">
-            <el-input v-model="form.userName" controls-position="right" placeholder="请输入持卡人"></el-input>
+          <el-form-item label="卡号:" prop="cardNo">
+            <el-input v-model="form.cardNo" controls-position="right" placeholder="请输入卡号"></el-input>
           </el-form-item>
-          <el-form-item label="身份证号:" prop="idCard">
-            <el-input v-model="form.idCard" controls-position="right" placeholder="请输入身份证号"></el-input>
+          <el-form-item label="持卡人:" prop="memberId">
+            <el-select style="width: 100%;" v-model="form.memberId" clearable placeholder="请选择持卡人">
+              <el-option
+                v-for="dict in tableUseList"
+                :key="dict.id"
+                :label="dict.name"
+                :value="dict.id">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="模板:" prop="templateId">
+            <el-select style="width: 100%;" v-model="form.templateId" clearable placeholder="请选择持卡人">
+              <el-option
+                v-for="dict in mobanList"
+                :key="dict.id"
+                :label="dict.name"
+                :value="dict.id">
+              </el-option>
+            </el-select>
           </el-form-item>
-          <el-form-item label="手机号:" prop="phone">
+          <!-- <el-form-item label="手机号:" prop="phone">
             <div style="display: flex;">
               <el-input v-model="form.phone" controls-position="right" placeholder="请输入手机号"></el-input>
               <el-button @click="getCode" style="margin-left: 20px;" type="primary" :loading="phoneCodeLoading == 1">{{ phoneCodeLoading == 1 ? '获取中...' : phoneCodeLoading == 0 ? '获取验证码' : '已发送成功,重新获取' }}</el-button>
@@ -44,7 +61,7 @@
           </el-form-item>
           <el-form-item label="短信验证码:" prop="code">
             <el-input v-model="form.code" controls-position="right" placeholder="请输入短信验证码"></el-input>
-          </el-form-item>
+          </el-form-item> -->
         </el-form>
       </div>
     </div>
@@ -85,49 +102,64 @@ export default {
       loadingText: "拼命加载数据中...",
       formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
       configUrl: {
-        add: '/merchant/merchantEntitycard/insertOrUpdate', // 新增地址
-        details: '/merchant/merchantEntitycard/selectById', // 详情地址
-        edit: '/merchant/merchantEntitycard/insertOrUpdate', // 编辑地址
+        add: '/merchant/memberEntitycard/insertOrUpdate', // 新增地址
+        details: '/merchant/memberEntitycard/selectById', // 详情地址
+        edit: '/merchant/memberEntitycard/insertOrUpdate', // 编辑地址
         list: '/merchant/merchantEntitycardConfig/pageList', // 实体卡类型
         codeList: '/merchant/merchantAuth/getVerifyCode', // 获取验证码
         merchantRealAuth: '/merchant/merchantAuth/merchantRealAuth', // 验证
+        useCode: '/member/memberInfo/list', // 
+        moban: '/merchant/templateEntitycard/pageList',
       },
       form: {
         id: undefined,
       },
       rules: {
-        entityCardConfigId: [{ required: true, message: "请选择办卡类型", trigger: ["change","blur"] }],
-        userName: [{ required: true, message: "请输入持卡人", trigger: ["change","blur"] }],
-        idCard: [{ required: true, message: "请输入身份证号", trigger: ["change","blur"] }],
-        phone: [
-          { required: true, trigger: ["change","blur"], message: "请输入您的账号" },
-          { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: ["change","blur"] }
-        ],
-        code: [{ required: true, message: "请输入短信验证码", trigger: ["change","blur"] }],
+        cardType: [{ required: true, message: "请选择卡类型", trigger: ["change","blur"] }],
+        cardNo: [{ required: true, message: "请输入卡号", trigger: ["change","blur"] }],
+        memberId: [{ required: true, message: "请输入持卡人", trigger: ["change","blur"] }],
+        templateId: [{ required: true, message: "请选择模板", trigger: ["change","blur"] }],
       },
       scenicAreaProducts: [],// 景点产品关联
 
       tableList: [], // 实体卡类型
-
-      phoneCodeLoading: 0
+      tableUseList: [], // 用户
+      mobanList: [], // 模板list
+      phoneCodeLoading: 0,
+      
     };
   },
   created() {
-    this.getList()
+    this.getUseList()
+    this.getMobanList()
   },
   methods: {
     /** 查询体卡类型列表 */
-    getList() {
+    getUseList() {
       listTableApi(
-        this.configUrl.list,
+        this.configUrl.useCode,
         this.addDateRange({
           pageNum: 1,
           pageSize: 9999,
         })).then(response => {
-              this.tableList = response.data.rows;
+              this.tableUseList = response.data.rows;
           }
         ).catch (error=>{
-          this.tableList = [];
+          this.tableUseList = [];
+        }) 
+    },
+    /** 查询体卡类型列表 */
+    getMobanList() {
+      listTableApi(
+        this.configUrl.useCode,
+        this.addDateRange({
+          pageNum: 1,
+          pageSize: 9999,
+        })).then(response => {
+              this.mobanList = response.data.rows;
+          }
+        ).catch (error=>{
+          this.mobanList = [];
         }) 
     },
     async initData(title , model,row){
@@ -196,17 +228,17 @@ export default {
           this.loadingText = "提交数据中..."
           this.loading = true
           try {
-            let resCode = await addTableApi(
-              this.configUrl.merchantRealAuth,
-              this.addDateRange({
-                idCard: this.form.idCard,
-                userName: this.form.userName,
-            }))
-            if(resCode.code == 200) {
+            // let resCode = await addTableApi(
+            //   this.configUrl.merchantRealAuth,
+            //   this.addDateRange({
+            //     idcard: this.form.idcard,
+            //     name: this.form.name,
+            // }))
+            // if(resCode.code == 200) {
 
-            }else {
-              return
-            }
+            // }else {
+            //   return
+            // }
             if (this.model != 'ADD') {
               let res = await addTableApi(this.configUrl.edit,{...this.form})
               if(res.code == 200) {
@@ -278,6 +310,14 @@ export default {
           this.phoneCodeLoading = 0
         }) 
      },
+     selectUser(value) {
+      console.log(value)
+      this.tableUseList.forEach((item,index) => {
+        if(item.id == value) {
+          this.$set(this.form,'name',item.name)
+        }
+      });
+    }
   },
 };
 </script>

+ 457 - 0
src/views/tourism/membershipManagement/physicalCard/formBox/physicalCardTemplateForm.vue

@@ -0,0 +1,457 @@
+<template>
+  <el-dialog 
+  :title="title" 
+  :visible.sync="open" 
+  width="80%" 
+  append-to-body 
+  :close-on-click-modal="false"
+    @close="cancel">
+    <div class="form-dialog-box" v-loading="loading" :element-loading-text="loadingText"
+      element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0)">
+      <div class="form-make" :style="{ '--crad-zm': form.mainBg ? `url(${form.mainBg})`:none }">
+        <div class="form-make_zm">
+          <div class="form-make_zm-title">正面</div>
+          <div class="form-make_zm-info">
+            <!-- 工具  -->
+            <div class="form-make_zm-tool">
+              <el-upload
+                class="upload-demo"
+                :action="actionUrl"
+                :data="{
+                  bucket: 'tourism'
+                }"
+                :show-file-list="false"
+                :before-upload="beforeAvatarUpload"
+                :on-success="(response, file, fileList)=>handleAvatarSuccess(response, file, fileList,'mainBg')"
+                :on-progress="handleAvatarProgress"
+                :disabled="actionUrlLoading"
+                :on-error="handleAvatarError"
+                :loading="actionUrlLoading"
+                >
+                <el-button size="small" type="primary">上传底图</el-button>
+              </el-upload>
+              <el-button style="margin-left: 10px;" size="small" type="primary" @click="addText('zm')">添加文本</el-button>
+              <el-button size="small" type="primary" @click="addImage('zm')">添加图片</el-button>
+              <el-button size="small" type="primary" @click="addQR('zm')">添加二维</el-button>
+            </div>
+            <!-- 样式  -->
+            <div class="form-make_zm-style">
+            </div>
+          </div>
+        </div>
+
+      </div>
+      
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus == 1">
+      <el-button @click="cancel" :loading="loading">关闭</el-button>
+      <el-button 
+      type="primary" 
+      @click="submitForm(true)" 
+      :loading="loading">
+              {{ loading ? '提交中...' : '提交' }}
+      </el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import {
+  getTableDeatilsByIdApi,
+  updateTableApi,
+  addTableApi
+} from '@/api/CURD'
+
+export default {
+  name: "addAndEdit",
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        add: '/merchant/merchantEntitycardConfig/insertOrUpdate', // 新增地址
+        details: '/merchant/merchantEntitycardConfig/selectById', // 规格详情
+        edit: '/merchant/merchantEntitycardConfig/insertOrUpdate', // 编辑地址
+      },
+      performId: null,
+      form: {
+        id: undefined,
+        mainBg: null,
+        backBg: null,
+      },
+      rules: {},
+      //  上传文件
+      actionUrl: process.env.VUE_APP_BASE_API + process.env.VUE_APP_UPLOAD_IMAGE,
+      actionUrlLoading: false,
+    };
+  },
+  methods: {
+    async initData(title, model, row) {
+      this.title = title
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.actionUrlLoading = false
+      this.model = model
+      this.formStatus = 0
+      if(model=='ADD') { // 新增
+        this.$set(this,'form',{
+          ...row,
+        })
+        this.formStatus = 1
+      }else if(model=='EDIT') { // 新增
+        let obj = {
+          ...row
+        }
+        this.$set(this,'form',obj)
+        this.formStatus = 1
+      }else if(model=='EDITInit') { // 新增
+        await this.getTableDeatilsFun(row)
+      }
+      this.loading = false
+      this.$nextTick(()=>{
+        if(this.$refs["form"]) {
+          this.$refs["form"].clearValidate();
+        }
+      })
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details, { id })
+        if (res.code == 200) {
+          let obj = {
+            ...res.data,
+          }
+          this.$set(this, 'form', JSON.parse(JSON.stringify(obj)))
+          this.formStatus = 1
+        } else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!', error)
+        this.formStatus = 2
+        this.loading = false
+      }
+    },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    submitForm(type) {
+      console.log("dsfsfds=======", type, this.form)
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.loadingText = "提交数据中..."
+          this.loading = true
+          let params = JSON.parse(JSON.stringify(this.form))
+          addTableApi(this.configUrl.edit, {
+            ...params,
+            activationRule: params.activationRule?params.activationRule.join(','):null,
+          }).then(response => {
+            this.$modal.msgSuccess(`${this.form.id ? '编辑' : '新增'}成功`);
+            this.loading = false
+            this.$set(this, 'form', {activationRule:[]})
+            this.$nextTick(() => {
+              this.$refs.form.clearValidate();
+            })
+            this.open = false;
+            this.$emit('refresh')
+          }).catch(() => {
+            this.$message.error(`${this.form.id ? '编辑' : '新增'}失败!!!`);
+            this.loading = false
+          })
+        }
+      });
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if (this.$refs["form"]) {
+        //this.$refs["form"].resetFields();
+        this.$set(this, 'form', {activationRule:[]})
+        this.$nextTick(() => {
+          this.$refs["form"].clearValidate();
+        })
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+
+    /**  上传图片 单张  */
+    handleAvatarSuccess(response, file, fileList,key) {
+      console.log("res, file",response, file, fileList)
+      this.actionUrlLoading = false
+      if(response.code == 200) {
+        this.form[key] = response.data.url
+      }
+    },
+    beforeAvatarUpload(file) {
+      const isLt2M = file.size / 1024 / 1024 <= 5;
+      let testmsg = file.name.substring(file.name.lastIndexOf('.')+1)
+      let typeList = ['png','jepg','jpg']
+      const isJPG = typeList.includes(testmsg);
+      if (!isJPG) {
+        this.$message.error(`上传图片图片只能是 ${typeList} 格式!`);
+      }
+      if (!isLt2M) {
+        this.$message.error('上传图片图片大小不能超过 5MB!');
+      }
+      return isJPG && isLt2M;
+    },
+    handleAvatarProgress(){
+      this.actionUrlLoading = true
+    },
+    handleAvatarError() {
+      this.actionUrlLoading = false
+    },
+    handleRemove(index) {
+      this.form.goodsImage.splice(index,1)
+    },
+
+    addText(type){
+
+    },
+    addImage(type){
+
+    },
+    addQR(type){
+
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+
+  .form-title {
+    padding: 0 0 10px 0;
+
+    span {
+      display: flex;
+      color: rgba(65, 80, 88, 1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+
+  }
+
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.el-table {
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+
+    .el-input__inner {
+      display: none !important;
+    }
+
+    span.el-input__suffix {
+      position: inherit !important;
+
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+
+::v-deep .avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+::v-deep .avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+
+::v-deep .avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 100px;
+  height: 100px;
+  line-height: 100px;
+  text-align: center;
+}
+
+::v-deep .avatar {
+  width: 100px;
+  height: 100px;
+  display: block;
+}
+
+
+.form-make {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+  --crad-zm: none;
+  --crad-fm: none;
+  --crad-w: 860px;
+  --crad-h: 540px;
+  .form-make_zm {
+    display: flex;
+    height: 600px;
+    .form-make_zm-title {
+      width: 20px;
+      height: 100%;
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: center;
+      align-items: center;
+      font-size: 24px;
+      font-family: 600;
+      padding: 20px 20px;
+      box-sizing: border-box;
+    }
+    .form-make_zm-info {
+      width: var(--crad-w);
+      height: 100%;
+      .form-make_zm-tool{
+        display: flex;
+        align-items: center;
+        width: 100%;
+        height: calc( 100% - var(--crad-h) );
+        box-sizing: border-box;
+        ///padding-bottom: 10px;
+      }
+      .form-make_zm-style {
+        width: 100%;
+        height: var(--crad-h);
+        border: 1px dashed #000;
+        border-radius: 20px;
+        background-image: var(--crad-zm);
+        background-size: 100% 100%;
+        background-repeat: no-repeat;
+      }
+    }
+  }
+}
+
+
+
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

+ 536 - 0
src/views/tourism/membershipManagement/physicalCard/formBox/printForm.vue

@@ -0,0 +1,536 @@
+<template>
+  <el-dialog 
+  :title="title" 
+  :visible.sync="open" 
+  width="1000" 
+  append-to-body 
+  :close-on-click-modal="false"
+    @close="cancel">
+    <div class="form-dialog-box" v-loading="loading" :element-loading-text="loadingText"
+      element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0)">
+      <div class="form-make" :style="{ '--crad-zm': bgm1 ? `url(${bgm1})`:none,'--crad-fm': bgm2 ? `url(${bgm2})`:none }">
+        <div class="form-make_zm">
+          <div class="form-make_zm-title">正面</div>
+          <div class="form-make_zm-info">
+            <!-- 工具  -->
+            <div class="form-make_zm-tool">
+            </div>
+            <!-- 样式  -->
+            <div class="form-make_zm-style" ref="myElement">
+            </div>
+          </div>
+        </div>
+
+        <div class="form-make_fm">
+          <div class="form-make_fm-title">反面</div>
+          <div class="form-make_fm-info">
+            <!-- 工具  -->
+            <div class="form-make_fm-tool">
+            </div>
+            <!-- 样式  -->
+            <div class="form-make_fm-style" ref="myElement1" style="position: relative;">
+              <div 
+              v-if="isQrCode"
+              id="#barcode"
+              style="
+              width: 267px;
+              height: 93px;
+              position: absolute;
+              z-index: 99;
+              bottom: 46px;
+              background-color: #fff;
+              display: flex;
+              justify-content: center;
+              box-sizing: border-box;
+              right: 48px;">
+                <barcode :value="cardNo" format="CODE128" :width="width" height="51"></barcode>  
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      
+    </div>
+    <span slot="footer" class="dialog-footer" v-if="formStatus == 1">
+      <el-button @click="cancel" :loading="loading">关闭</el-button>
+      <el-button 
+      type="primary" 
+      @click="submitForm" 
+      :loading="loading">
+              {{ loading ? '提交中...' : '提交' }}
+      </el-button>
+    </span>
+    <!-- 添加或修改对话框 End -->
+  </el-dialog>
+</template>
+
+<script>
+import {
+  getTableDeatilsByIdApi,
+  addTableApi
+} from '@/api/CURD'
+import VueBarcode from 'vue-barcode';
+//映入注册
+// import JsBarcode from 'jsbarcode'
+import html2canvas from 'html2canvas';
+export default {
+  name: "addAndEdit",
+  components: {
+    'barcode': VueBarcode
+  },
+  data() {
+    return {
+      title: "",
+      model: "", // EDIT: 编辑模式 ADD : 新增模式  EDITInit : 编辑模式(需要请求详情)
+      open: false,
+      loading: false,
+      loadingText: "拼命加载数据中...",
+      formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
+      configUrl: {
+        print:'/zebra/card/print/io/upload'
+      },
+      isQrCode: false,
+      bgm1: require('./zm.jpg'),
+      bgm2: require('./fm.jpg'),
+      cardNo: '',
+      width: 3
+    };
+  },
+  methods: {
+    async initData(title, model, row) {
+      this.title = title
+      this.isQrCode = false
+      this.open = true
+      this.loadingText = "拼命加载数据中..."
+      this.loading = true
+      this.actionUrlLoading = false
+      this.model = model
+      this.form = JSON.parse(JSON.stringify(row))
+      this.formStatus = 0
+      this.cardNo = row.cardNo //row.cardNo
+      if(this.cardNo.length > 16 ) {
+        console.log("sdfadff",this.cardNo.length)
+        this.width = 1
+      }else if(this.cardNo.length >= 10 && this.cardNo.length <= 16) {
+        console.log("sdfadff",this.cardNo.length)
+        this.width = 2
+      }else {
+        console.log("sdfadff",this.cardNo.length)
+        this.width = 3
+      }
+      // if(model=='EDITInit') { // 新增
+      //   await this.getTableDeatilsFun(row)
+      // }
+      // if(row.cardNo != ""){
+      //   this.$nextTick(()=>{
+      //     //实例化
+      //     JsBarcode("#barcode", row.cardNo, {
+      //         format: "CODE39",  //条形码的格式
+      //         // lineColor: "#0aa",  //线条颜色
+      //         width:1, //线宽
+      //         height:40,  //条码高度
+      //         // displayValue: false //是否显示文字信息
+      //     });
+      //   })
+        
+      // }  
+      this.formStatus = 1
+      this.isQrCode = true
+      this.loading = false
+    },
+    /** 获取详情 */
+    async getTableDeatilsFun(row) {
+      const id = row.id
+      this.loading = true
+      try {
+        let res = await getTableDeatilsByIdApi(this.configUrl.details, { id })
+        if (res.code == 200) {
+          let obj = {
+            ...res.data,
+          }
+          this.$set(this, 'form', JSON.parse(JSON.stringify(obj)))
+          this.formStatus = 1
+        } else {
+          this.$message.error('获取详情失败!!!');
+          this.formStatus = 2
+          this.loading = false
+        }
+        this.loading = false
+      } catch (error) {
+        console.error('获取详情失败!!!!', error)
+        this.formStatus = 2
+        this.loading = false
+      }
+    },
+    /**
+     * 保存
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    async submitForm(type) {
+      console.log("dsfsfds=======", type, this.form)
+      try {
+        this.loadingText = "提交数据中..."
+        this.loading = true
+        let cardImgFrontFile = await this.captureCanvas('myElement')
+        let cardImgBackFile = await this.captureCanvas('myElement1')
+        const formData = new FormData();
+        formData.append("ip", '172.16.90.128');
+        formData.append("cardImgFrontFile", cardImgFrontFile);
+        formData.append("cardFontFrontFile", null);
+        formData.append("cardImgBackFile", cardImgBackFile);
+        formData.append("cardFontBackFilee", null);
+        let res1 = await fetch('https://zebra.dev.gztjy.top/zebra/card/print/io/upload', {  
+          method: 'POST', // 或者 'GET'  
+          // headers: { 
+          //   'Content-Type': 'multipart/form-data' //携带参数为json
+          // },  
+          body: formData // post请求携带的参数  
+          // params:{id:0} // get请求携带的参数  
+        })  
+        let res = await res1.json()
+        console.log("res====",res,res.data)
+        // let res = await addTableApi(this.configUrl.print, {
+        //   ...params,
+        // })
+        if(res.code == 200) {
+          this.$modal.msgSuccess(`打印成功`);
+          this.loading = false
+          this.open = false;
+          this.$emit('refresh')
+        }
+      } catch (error) {
+        console.error(error)
+        this.$message.error(`打印失败!!!`);
+        this.loading = false
+      }
+      
+    },
+    /**
+     * 重置
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    reset() {
+      if (this.$refs["form"]) {
+        //this.$refs["form"].resetFields();
+        this.$set(this, 'form', {activationRule:[]})
+        this.$nextTick(() => {
+          this.$refs["form"].clearValidate();
+        })
+      }
+    },
+    /**
+     * 关闭弹框
+     * @date 2023-11-22
+     * @returns {any}
+     */
+    cancel() {
+      this.reset();
+      this.open = false;
+    },
+
+    /**  上传图片 单张  */
+    handleAvatarSuccess(response, file, fileList,key) {
+      console.log("res, file",response, file, fileList)
+      this.actionUrlLoading = false
+      if(response.code == 200) {
+        this.form[key] = response.data.url
+      }
+    },
+    beforeAvatarUpload(file) {
+      const isLt2M = file.size / 1024 / 1024 <= 5;
+      let testmsg = file.name.substring(file.name.lastIndexOf('.')+1)
+      let typeList = ['png','jepg','jpg']
+      const isJPG = typeList.includes(testmsg);
+      if (!isJPG) {
+        this.$message.error(`上传图片图片只能是 ${typeList} 格式!`);
+      }
+      if (!isLt2M) {
+        this.$message.error('上传图片图片大小不能超过 5MB!');
+      }
+      return isJPG && isLt2M;
+    },
+    handleAvatarProgress(){
+      this.actionUrlLoading = true
+    },
+    handleAvatarError() {
+      this.actionUrlLoading = false
+    },
+    handleRemove(index) {
+      this.form.goodsImage.splice(index,1)
+    },
+
+    addText(type){
+      
+    },
+    addImage(type){
+
+    },
+    addQR(type){
+
+    },
+    async captureCanvas(el) {
+      // 选择你想要转换成图片的 DOM 元素
+      const element = this.$refs[el];
+      console.log("dsfsdfadsfasd")
+      let canvas = await html2canvas(element)
+      // canvas.toDataURL() 可以获取图片的 base64 编码
+      const dataUrl = canvas.toDataURL();
+      // 你可以将 dataUrl 设置为一个 img 标签的 src 属性,或者下载图片等
+      console.log(dataUrl);
+      let file = this.dataURLtoBlob(dataUrl,'ceshi')
+      console.log(file);
+      return file
+    },
+    base64ToFile(base64,fileName){
+      let arr = base64.split(',')
+        let mime = arr[0].match(/:(.\*?);/)[1]
+        let bstr = atob(arr[1])
+        let n = bstr.length
+        let u8arr = new Uint8Array(n)
+        while(n--) {
+          u8arr[n] = batr.charCodeAt(n)
+        }
+      return new File([u8arr],fileName,{ type: mime })
+    },
+    // 将base64转blob
+    dataURLtoBlob(dataurl,fileName) {
+        var arr = dataurl.split(','),
+        mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]),
+        n = bstr.length,
+        u8arr = new Uint8Array(n);
+        while (n--) {
+            u8arr[n] = bstr.charCodeAt(n);
+        }
+        let blob = new Blob([u8arr], { type: mime });
+        let file = new File([blob],fileName)
+        return file;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-dialog-box {
+  padding: 0 30px;
+  padding: 0 30px;
+  min-height: 50vh;
+  max-height: 65vh;
+  overflow-y: auto;
+
+  >div {
+    width: 100%;
+    min-height: 50vh;
+  }
+
+  .form-title {
+    padding: 0 0 10px 0;
+
+    span {
+      display: flex;
+      color: rgba(65, 80, 88, 1);
+      font-size: 16px;
+      font-family: SourceHanSansSC;
+      font-weight: 700;
+      line-height: 23px;
+      border-left: 4px solid rgb(22, 132, 252);
+      padding-left: 10px;
+    }
+
+  }
+
+  ::v-deep .ql-editor {
+    height: 400px;
+  }
+
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.el-table {
+  .upload-btn {
+    width: 100px;
+    height: 100px;
+    background-color: #fbfdff;
+    border: dashed 1px #c0ccda;
+    border-radius: 5px;
+
+    i {
+      font-size: 30px;
+      margin-top: 20px;
+    }
+
+    &-text {
+      margin-top: -10px;
+    }
+  }
+
+  .avatar {
+    cursor: pointer;
+  }
+}
+
+.area-container {
+  min-height: 400px;
+}
+
+::v-deep .area-wrap-city.el-cascader {
+  line-height: normal;
+
+  .el-input {
+    cursor: pointer;
+    width: 100% !important;
+    height: 28px !important;
+
+    .el-input__inner {
+      display: none !important;
+    }
+
+    span.el-input__suffix {
+      position: inherit !important;
+
+      i.el-input__icon {
+        line-height: inherit;
+        margin-left: 5px;
+      }
+    }
+
+    .el-input__wrapper {
+      box-shadow: none;
+
+      input {
+        display: none;
+      }
+    }
+  }
+
+  .el-cascader__tags {
+    display: none;
+  }
+}
+
+.area-city-popper {
+  .el-cascader-panel {
+    .el-scrollbar.el-cascader-menu {
+      .el-cascader-menu__wrap.el-scrollbar__wrap {
+        height: 315px;
+      }
+    }
+  }
+}
+
+
+.form-make {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+  --crad-zm: none;
+  --crad-fm: none;
+  --crad-w: 860px;
+  --crad-h: 540px;
+  .form-make_zm {
+    display: flex;
+    height: 600px;
+    .form-make_zm-title {
+      width: 20px;
+      height: 100%;
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: center;
+      align-items: center;
+      font-size: 24px;
+      font-family: 600;
+      padding: 20px 20px;
+      box-sizing: border-box;
+    }
+    .form-make_zm-info {
+      width: var(--crad-w);
+      height: 100%;
+      .form-make_zm-tool{
+        display: flex;
+        align-items: center;
+        width: 100%;
+        height: calc( 100% - var(--crad-h) );
+        box-sizing: border-box;
+        ///padding-bottom: 10px;
+      }
+      .form-make_zm-style {
+        width: 100%;
+        height: var(--crad-h);
+        border: 1px dashed #000;
+        border-radius: 20px;
+        background-image: var(--crad-zm);
+        background-size: 100% 100%;
+        background-repeat: no-repeat;
+      }
+    }
+  }
+  .form-make_fm {
+    display: flex;
+    height: 600px;
+    .form-make_fm-title {
+      width: 20px;
+      height: 100%;
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: center;
+      align-items: center;
+      font-size: 24px;
+      font-family: 600;
+      padding: 20px 20px;
+      box-sizing: border-box;
+    }
+    .form-make_fm-info {
+      width: var(--crad-w);
+      height: 100%;
+      .form-make_fm-tool{
+        display: flex;
+        align-items: center;
+        width: 100%;
+        height: calc( 100% - var(--crad-h) );
+        box-sizing: border-box;
+        ///padding-bottom: 10px;
+      }
+      .form-make_fm-style {
+        width: 100%;
+        height: var(--crad-h);
+        border: 1px dashed #000;
+        border-radius: 20px;
+        background-image: var(--crad-fm);
+        background-size: 100% 100%;
+        background-repeat: no-repeat;
+      }
+    }
+  }
+}
+
+
+
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+</style>

BIN
src/views/tourism/membershipManagement/physicalCard/formBox/zm.jpg


+ 70 - 143
src/views/tourism/membershipManagement/physicalCard/physicalCardManagement.vue

@@ -13,30 +13,39 @@
                 @keyup.enter.native="handleQuery"
               />
             </el-form-item>
-            <el-form-item label="持卡人" prop="userName">
+            <el-form-item label="持卡人" prop="name">
               <el-input
-                v-model="queryParams.userName"
+                v-model="queryParams.name"
                 placeholder="请输入持卡人"
                 clearable
                 style="width: 240px"
                 @keyup.enter.native="handleQuery"
               />
             </el-form-item>
-            <el-form-item label="手机号" prop="phone">
+            <el-form-item label="手机号" prop="mobile">
               <el-input
-                v-model="queryParams.phone"
+                v-model="queryParams.mobile"
                 placeholder="请输入手机号"
                 clearable
                 style="width: 240px"
                 @keyup.enter.native="handleQuery"
               />
             </el-form-item>
-            <el-form-item label="卡类型" prop="entityCardConfigId">
-              <el-select v-model="queryParams.entityCardConfigId" clearable placeholder="请选择卡类型">
+            <el-form-item label="身份证号" prop="idcard">
+              <el-input
+                v-model="queryParams.idcard"
+                placeholder="请输入身份证号"
+                clearable
+                style="width: 240px"
+                @keyup.enter.native="handleQuery"
+              />
+            </el-form-item>
+            <el-form-item label="卡类型" prop="cardType">
+              <el-select v-model="queryParams.cardType" clearable placeholder="请选择卡类型">
                 <el-option
-                  v-for="dict in tableListCopy"
+                  v-for="dict in [{name: '副卡',id: 0},{name: '主卡',id: 1}]"
                   :key="dict.id"
-                  :label="dict.cardName"
+                  :label="dict.name"
                   :value="dict.id">
                 </el-option>
               </el-select>
@@ -48,40 +57,22 @@
           </el-form>
   
           <el-row :gutter="10" class="mb8">
-            <el-col :span="1.5">
-              <el-button
-                type="primary"
-                plain
-                icon="el-icon-plus"
-                size="mini"
-                @click="handleAdd"
-                v-hasPermi="configPermi.add"
-              >添加新卡</el-button>
-            </el-col>
             <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
           </el-row>
   
           <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
             <el-table-column type="index" label="序号" align="center"  />
             <el-table-column label="卡号" align="center" key="cardNo" prop="cardNo" v-if="columns[0].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="持卡人" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="手机号" align="center" key="phone" prop="phone" v-if="columns[2].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="卡类型" align="center" key="cardName" prop="cardName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="激活时间" align="center" key="effectiveDate" prop="effectiveDate" v-if="columns[4].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="使用期限" align="center" key="useType" prop="useType" v-if="columns[5].visible" :show-overflow-tooltip="true">
+            <el-table-column label="卡类型" align="center" key="cardType" prop="cardType" v-if="columns[1].visible" :show-overflow-tooltip="true">
               <template slot-scope="scope">
-                <span>{{ setUseType(scope.row) }}</span>
+                <span>{{ scope.row.cardType==0 ? '副卡': scope.row.cardType==1 ? '主卡': '--'}}</span>
               </template>
             </el-table-column>
-            <el-table-column label="卡余额" align="center" key="amount" prop="amount" v-if="columns[6].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="卡积分" align="center" key="credit" prop="credit" v-if="columns[7].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="充值余额" align="center" key="storageAmount" prop="storageAmount" v-if="columns[8].visible" :show-overflow-tooltip="true" />
-            <el-table-column label="卡状态" align="center" key="cardStatus" prop="cardStatus" v-if="columns[9].visible" :show-overflow-tooltip="true">
-              <template slot-scope="scope">
-                <dict-tag :options="dict.type.tourism_physicalCardManagement_cardStatus" :value="scope.row.cardStatus"/>
-              </template>
-            </el-table-column>
-            <el-table-column label="禁用/启用" align="center" key="status1" prop="status1" v-if="columns[10].visible" :show-overflow-tooltip="true">
+            <el-table-column label="持卡人" align="center" key="name" prop="name" v-if="columns[2].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="身份证" align="center" key="idcard" prop="idcard" v-if="columns[3].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="联系电话" align="center" key="mobile" prop="mobile" v-if="columns[4].visible" :show-overflow-tooltip="true" />
+          
+            <el-table-column label="禁用/启用" align="center" key="status" prop="status" v-if="columns[5].visible" :show-overflow-tooltip="true">
               <template slot-scope="scope">
                 <switchBox 
                 :defaultChecked="true" 
@@ -93,7 +84,9 @@
                  />
               </template>
             </el-table-column>
-            <el-table-column label="最近消费时间" align="center" key="newOrderTime" prop="newOrderTime" v-if="columns[11].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="模板" align="center" key="templateName" prop="templateName" v-if="columns[6].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="最近消费时间" align="center" key="lastConsumeTime" prop="lastConsumeTime" v-if="columns[7].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="制卡时间" align="center" key="lastProductTime" prop="lastProductTime" v-if="columns[8].visible" :show-overflow-tooltip="true" />
             <el-table-column
               label="操作"
               align="center"
@@ -108,19 +101,20 @@
                   @click="handleDetails(scope.row)"
                   v-hasPermi="configPermi.details"
                 >详情</el-button>
-                <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
-                    <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
-                    <el-dropdown-menu slot="dropdown">
-                        <el-dropdown-item command="handleResetPwd" icon="el-icon-key"
-                        v-hasPermi="configPermi.resetPwd">设置积分</el-dropdown-item>
-                        <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check"
-                        v-hasPermi="configPermi.AuthRole">设置储值</el-dropdown-item>
-                        <el-dropdown-item command="handleEdit" icon="el-icon-circle-check"
-                        v-hasPermi="configPermi.edit">编辑</el-dropdown-item>
-                        <el-dropdown-item command="handleResetPassword" icon="el-icon-circle-check"
-                        v-hasPermi="configPermi.Password">重置密码</el-dropdown-item>
-                    </el-dropdown-menu>
-                </el-dropdown>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDelete(scope.row)"
+                  v-hasPermi="configPermi.delect"
+                >销卡</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-document"
+                  @click="handlePrint(scope.row)"
+                  v-hasPermi="configPermi.print"
+                >打印</el-button>
               </template>
             </el-table-column>
           </el-table>
@@ -134,14 +128,11 @@
           />
         </el-col>
       </el-row>
-      <!--  新增或修改  -->
-      <addAndEdit ref="addAndEdit" @refresh="getList" />
+
       <!--  详情 -->
       <detailsBox ref="detailsBox" />
-
-      <setIntegralForm ref="setIntegralForm" @refresh="getList" />
-
-      <setStoredValue ref="setStoredValue" @refresh="getList" />
+      <!-- 打印 -->
+      <printForm ref="printForm" @refresh="getList" />
     </div>
   </template>
   
@@ -149,16 +140,16 @@
   import { 
     listTableApi, 
     delTableParamsApi,
-    updateTableApi
+    updateTableApi,
+    addTableApi
   } from "@/api/CURD";
   import addAndEdit from "./formBox/physicalCardManagementForm.vue"
   import detailsBox from "./detailsBox/physicalCardManagementDetails.vue"
-  import setIntegralForm from "./formBox/setIntegralForm.vue"
-  import setStoredValue from "./formBox/setStoredValue.vue"
+  import printForm from "./formBox/printForm.vue"
   export default {
     name: "User",
     dicts: ['tourism_IntegralRecord_cardType','tourism_physicalCardManagement_cardStatus'],
-    components: {addAndEdit,detailsBox,setIntegralForm,setStoredValue},
+    components: {addAndEdit,detailsBox,printForm},
     data() {
       return {
         title: "实体卡管理",// 通用标题
@@ -172,14 +163,15 @@
           resetPwd: ['physicalCard:physicalCardManagement:resetPwd'],// 设置积分
           AuthRole: ['physicalCard:physicalCardManagement:AuthRole'],// 设置储值
           Password: ['physicalCard:physicalCardManagement:Password'], // 重置密码
+          print: ['physicalCard:physicalCardManagement:print']
         },
         configUrl: {
-          list: '/merchant/merchantEntitycard/pageList', // 列表地址
-          delect: '', // 删除地址
+          list: '/merchant/memberEntitycard/pageList', // 列表地址
+          delect: '/merchant/memberEntitycard/deleteById', // 删除地址
           upload: '',// 导入地址
           download:'', // 下载模板地址
           export: '',// 导出地址
-          updateStatus: '/merchant/merchantEntitycard/updateStatus', // 编辑地址
+          updateStatus: '/merchant/memberEntitycard/updateStatus', // 编辑地址
           resetPassword: '/merchant/merchantEntitycard/resetPassword',
           listCopy: '/merchant/merchantEntitycardConfig/pageList'
         },
@@ -206,40 +198,23 @@
         // 控制列表是否显示
         columns: [
           { key: 0, label: `卡号`, visible: true },
-          { key: 1, label: `持卡人`, visible: true },
-          { key: 2, label: `手机号`, visible: true },
+          { key: 1, label: `卡类型`, visible: true },
+          { key: 2, label: `持卡人`, visible: true },
           { key: 3, label: `卡类型`, visible: true },
-          { key: 4, label: `身份证号`, visible: true },
-          { key: 5, label: `激活时间`, visible: true },
-          { key: 6, label: `卡余额`, visible: true },
-          { key: 7, label: `卡积分`, visible: true },
-          { key: 8, label: `充值余额`, visible: true },
-          { key: 9, label: `状态`, visible: true },
-          { key: 10, label: `禁用/启用`, visible: true },
-          { key: 11, label: `最近消费时间`, visible: true },
+          { key: 4, label: `身份证`, visible: true },
+          { key: 5, label: `联系电话`, visible: true },
+          { key: 6, label: `禁用/启用`, visible: true },
+          { key: 7, label: `模板`, visible: true },
+          { key: 8, label: `最近消费时间`, visible: true },
+          { key: 9, label: `制卡时间`, visible: true },
         ],
         tableListCopy: []// 实体卡类型
       };
     },
     created() {
-      this.getListCopy()
       this.getList();
     },
     methods: {
-      /** 查询实体卡类型列表 */
-      getListCopy() {
-        listTableApi(
-          this.configUrl.listCopy,
-          this.addDateRange(
-            this.queryParams, 
-            this.dateRange)).then(response => {
-              this.tableListCopy = response.data.rows;
-          }
-        ).catch (error=>{
-          console.error('获取列表失败!!!!',error)
-          this.tableListCopy = [];
-        }) 
-      },
       /** 查询用户列表 */
       getList() {
         this.loading = true;
@@ -299,15 +274,15 @@
       /** 删除按钮操作 */
       handleDelete(row) {
         const ids = row.id || this.ids;
-        this.$modal.confirm('是否确认删除数据项?').then( () => {
+        this.$modal.confirm('是否确认销除此卡吗?').then( () => {
           return delTableParamsApi(this.configUrl.delect,{
             id: ids
           });
         }).then(() => {
           this.getList();
-          this.$modal.msgSuccess("删除成功");
+          this.$modal.msgSuccess("销卡成功");
         }).catch((e) => {
-          console.error("删除失败====",e)
+          console.error("销卡失败====",e)
         });
       },
       /** 导出按钮操作 */
@@ -333,7 +308,7 @@
       /** 开/闭 园 */
       openAttraction(row) {
         this.$modal.confirm(`是否确认${row.status == 0 ? '启用' : '禁用'} ${row.cardNo||''}吗?`).then( () => {
-          return updateTableApi(this.configUrl.updateStatus,{
+          return addTableApi(this.configUrl.updateStatus,{
             id: row.id,
             status: row.status == 1 ? 0 : 1
           });
@@ -344,60 +319,12 @@
           console.error("失败====",e)
         });
       },
-      /**  重置密码   */
-      handleResetPassword(row){
-        this.$modal.confirm(`是否确认重置卡号 ${row.cardNo||''}的密码为000000吗?`).then( () => {
-          return updateTableApi(this.configUrl.resetPassword,{
-            id: row.id,
-          });
-        }).then(() => {
-          this.getList();
-          this.$modal.msgSuccess(`重置成功`);
-        }).catch((e) => {
-          console.error("失败====",e)
-        });
-      },
-        handleResetPwd(row) {
-            if(this.$refs.setIntegralForm) {
-            this.$refs.setIntegralForm.initData('设置积分', "EDIT",{...row})
-            }
-        },
-        handleAuthRole(row) {
-            if(this.$refs.setStoredValue) {
-            this.$refs.setStoredValue.initData('设置储值', "EDIT",{...row})
-            }
-        },
-        // 更多操作触发
-        handleCommand(command, row) {
-          switch (command) {
-              case "handleResetPwd":
-              this.handleResetPwd(row);
-              break;
-              case "handleAuthRole":
-              this.handleAuthRole(row);
-              break;
-              case "handleEdit":
-              this.handleUpdate(row);
-              break;
-              case "handleResetPassword":
-              this.handleResetPassword(row);
-              break;
-              default:
-              break;
-          }
-        },
-        /** 设置使用期限  */
-        setUseType(row){
-          if(row.useType == 1) {
-            return '永久生效'
-          }else if(row.useType == 2) {
-            return '' + (row.useDay || '') + '天有效'
-          }else if(row.useType == 3) {
-            return '' + row.useEndDay + '内有效'
-          }else{
-            return '--'
-          }
-        },
+      /**  打印  */
+      handlePrint(row) {
+        if(this.$refs.printForm) {
+          this.$refs.printForm.initData(this.title + '详情', "EDITInit",{...row})
+        }
+      }
     }
   };
   </script>

+ 263 - 0
src/views/tourism/membershipManagement/physicalCard/physicalCardTemplate.vue

@@ -0,0 +1,263 @@
+<template>
+    <div class="app-container">
+      <el-row :gutter="20">
+        <!--用户数据-->
+        <el-col :span="24" :xs="24">
+            <!-- <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
+                <el-form-item label="名称" prop="cardName">
+                    <el-input
+                    v-model="queryParams.cardName"
+                    placeholder="请输入名称"
+                    clearable
+                    style="width: 240px"
+                    @keyup.enter.native="handleQuery"
+                    />
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+                    <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+                </el-form-item>
+            </el-form> -->
+          <el-row :gutter="10" class="mb8">
+            <el-col :span="1.5">
+              <el-button
+                type="primary"
+                plain
+                icon="el-icon-plus"
+                size="mini"
+                @click="handleAdd"
+                v-hasPermi="configPermi.add"
+              >添加模板</el-button>
+            </el-col>
+            <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
+          </el-row>
+  
+          <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange">
+            <el-table-column type="index" label="序号" align="center"  />
+            <el-table-column label="模板名称" align="center" key="name" prop="name" v-if="columns[0].visible" :show-overflow-tooltip="true" />
+            <el-table-column label="正面图片" align="center" key="mainBg" prop="mainBg" v-if="columns[1].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                  <div>
+                    <img :src="scope.row.mainBg" alt="">
+                  </div>
+                </template>
+            </el-table-column>
+            <el-table-column label="反面图片" align="center" key="backBg" prop="backBg" v-if="columns[2].visible" :show-overflow-tooltip="true">
+              <template slot-scope="scope">
+                  <div>
+                    <img :src="scope.row.backBg" alt="">
+                  </div>
+                </template>
+            </el-table-column>
+            <el-table-column
+              label="操作"
+              align="center"
+              class-name="small-padding fixed-width"
+            >
+              <template slot-scope="scope" >
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleDetails(scope.row)"
+                  v-hasPermi="configPermi.details"
+                >详情</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-edit"
+                  @click="handleUpdate(scope.row)"
+                  v-hasPermi="configPermi.edit"
+                >编辑</el-button>
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleDelete(scope.row)"
+                  v-hasPermi="configPermi.delect"
+                >删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+  
+          <pagination
+            v-show="total>0"
+            :total="total"
+            :page.sync="queryParams.pageNum"
+            :limit.sync="queryParams.pageSize"
+            @pagination="getList"
+          />
+        </el-col>
+      </el-row>
+      <!--  新增或修改  -->
+      <addAndEdit ref="addAndEdit" @refresh="getList" />
+      <detailsBox ref="detailsBox"></detailsBox>
+    </div>
+  </template>
+  
+  <script>
+  import { 
+    listTableApi, 
+    delTableParamsApi
+    } from "@/api/CURD";
+  import addAndEdit from "./formBox/physicalCardTemplateForm.vue"
+  import detailsBox from "./detailsBox/physicalCardTemplateDetails.vue"
+  export default {
+    name: "User",
+    dicts: [],
+    components: {addAndEdit,detailsBox},
+    data() {
+      return {
+        title: "模板管理",// 通用标题
+        configPermi: {
+          add: ['physicalCard:physicalCardTemplate:add'], // 新增权限
+          details: ['physicalCard:physicalCardTemplate:details'], // 详情权限
+          delect: ['physicalCard:physicalCardTemplate:delect'], // 删除权限
+          edit: ['physicalCard:physicalCardTemplate:edit'], // 编辑权限
+          upload: [''],// 导入权限
+          export: [''],// 导出权限
+          release: ['']
+        },
+        configUrl: {
+          list: '/merchant/templateEntitycard/pageList', // 列表地址
+          delect: '/merchant/templateEntitycard/deleteById', // 删除地址
+          upload: '',// 导入地址
+          download:'', // 下载模板地址
+          export: '',// 导出地址
+          updateStatusById: '',
+        },
+        // 遮罩层
+        loading: true,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 总条数
+        total: 0,
+        // 用户表格数据
+        tableList: null,
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+        },
+        dateRange: [],
+        // 控制列表是否显示
+        columns: [
+          { key: 0, label: `实体卡名称`, visible: true },
+          { key: 2, label: `实体卡价格`, visible: true },
+          { key: 3, label: `使用期限`, visible: true },
+          { key: 4, label: `生效日期`, visible: true },
+          { key: 5, label: `支持储值`, visible: true },
+          { key: 6, label: `支持积分`, visible: true },
+          { key: 7, label: `创捷时间`, visible: true },
+        ],
+      };
+    },
+    created() {
+      this.getList();
+    },
+    methods: {
+      /** 查询用户列表 */
+      getList() {
+        this.loading = true;
+        listTableApi(
+          this.configUrl.list,
+          this.addDateRange(
+            this.queryParams, 
+            this.dateRange)).then(response => {
+              this.tableList = response.data.rows;
+              this.total = response.data.total;
+              this.loading = false;
+          }
+        ).catch (error=>{
+          console.error('获取列表失败!!!!',error)
+          this.tableList = [];
+          this.total = 0;
+          this.loading = false
+        }) 
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.dateRange = [];
+        this.queryParams = {
+          pageNum: 1,
+          pageSize: 10,
+        }
+        this.handleQuery();
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map(item => item.id);
+        this.single = selection.length != 1;
+        this.multiple = !selection.length;
+      },
+      /** 新增按钮操作 */
+      handleAdd() {
+        if(this.$refs.addAndEdit) {
+          this.$refs.addAndEdit.initData(this.title + '新增', "ADD",{})
+        }
+      },
+      /** 修改按钮操作 */
+      handleUpdate(row) {
+        if(this.$refs.addAndEdit) {
+          this.$refs.addAndEdit.initData(this.title + '基本信息编辑', "EDITInit",{...row})
+        }
+      },
+      handleUpdate(row) {
+        if(this.$refs.addAndEdit) {
+          this.$refs.addAndEdit.initData(this.title + '规格信息编辑', "EDITInit",{...row})
+        }
+      },
+      handleDetails(row){
+        if(this.$refs.detailsBox) {
+          this.$refs.detailsBox.initData(this.title + '详情',"DEATILSInit", row)
+        }
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        const ids = row.id || this.ids;
+        this.$modal.confirm('是否确认删除数据项?').then( () => {
+          return delTableParamsApi(this.configUrl.delect,{
+            id: ids
+          });
+        }).then(() => {
+          this.getList();
+          this.$modal.msgSuccess("删除成功");
+        }).catch((e) => {
+          console.error("删除失败====",e)
+        });
+      },
+      /** 导出按钮操作 */
+      handleExport() {
+        this.download(this.configUrl.export, {
+          ...this.queryParams
+        }, `${this.title }_${new Date().getTime()}.xlsx`)
+      },
+      /** 导入按钮操作 */
+      handleImport() {
+        if(this.$refs.upload) {
+          this.$refs.upload.initData({
+            width: '400px',
+            // 弹出层标题(用户导入)
+            title: this.title + "导入",
+            // 下载模板地址
+            importTemplate: this.configUrl.download,
+            // 上传的地址
+            url: this.configUrl.upload
+          })
+        }
+      },
+    }
+  };
+  </script>
+