Explorar o código

1. 调整模板管理

MONSTER-ygh hai 5 meses
pai
achega
9b5f5bb66e

+ 3 - 0
.env.development

@@ -16,6 +16,9 @@ VUE_APP_BASE_IMAGE = '/thirdapi/upload/single/minio'
 # 图片上传网站地址
 VUE_APP_UPLOAD_IMAGE = '/thirdapi/upload/single/minio'
 
+# 打印地址
+VUE_APP_PRINT_URL = 'https://zebra.dev.dazesoft.cn/zebra/card/print/io/upload'
+
 # 部署的URL
 # 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 为 /admin。
 VUE_APP_ASSETS_PUBLIC_PATH = '/'

+ 3 - 0
.env.production

@@ -15,6 +15,9 @@ VUE_APP_BASE_IMAGE = /stage-api/file/statics
 # 图片上传网站地址
 VUE_APP_UPLOAD_IMAGE = '/thirdapi/upload/single/minio'
 
+# 打印地址
+VUE_APP_PRINT_URL = 'https://zebra.dev.dazesoft.cn/zebra/card/print/io/upload'
+
 # 部署的URL
 # 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 为 /admin。
 VUE_APP_ASSETS_PUBLIC_PATH = '/'

+ 3 - 0
.env.staging

@@ -15,6 +15,9 @@ VUE_APP_BASE_IMAGE = /stage-api/file/statics
 # 图片上传网站地址
 VUE_APP_UPLOAD_IMAGE = '/thirdapi/upload/single/minio'
 
+# 打印地址
+VUE_APP_PRINT_URL = 'https://zebra.dev.gztjy.top/zebra/card/print/io/upload'
+
 # 部署的URL
 # 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 为 /admin。
 VUE_APP_ASSETS_PUBLIC_PATH = '/'

+ 286 - 91
src/views/tourism/membershipManagement/physicalCard/formBox/physicalCardTemplateForm.vue

@@ -6,10 +6,15 @@
   append-to-body 
   :close-on-click-modal="false"
     @close="cancel">
+    <el-form :model="form" :rules="rules1" ref="form" label-width="100px" class="demo-ruleForm">
+      <el-form-item label="模板名称" prop="name">
+        <el-input v-model="form.name"></el-input>
+      </el-form-item>
+    </el-form>
     <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">
+        <div class="form-make_zm" :style="{ '--crad-zm': form.mainBg ? `url(${form.mainBg})`:'none' }">
           <div class="form-make_zm-title">正面</div>
           <div class="form-make_zm-info">
             <!-- 工具  -->
@@ -32,57 +37,51 @@
               </el-upload>
               <el-button style="margin-left: 10px;" size="small" type="primary" @click="centerDialogVisibleOpen('addText','zm')">添加文本</el-button>
               <!-- <el-button size="small" type="primary" @click="centerDialogVisibleOpen('addImage','zm')">添加图片</el-button> -->
-              <el-button size="small" type="primary" @click="centerDialogVisibleOpen('addQR','zm')">添加二维</el-button>
+              <el-button style="margin-left: 10px;" size="small" type="primary" @click="centerDialogVisibleOpen('addQR','zm')">添加二维</el-button>
             </div>
             <!-- 样式  -->
             <div class="form-make_zm-style">
               <div class="form-make_zm-style-bgm"></div>
-              <div ref="styleInfo" id="styleInfo" class="form-make_zm-style-info">
+              <div ref="styleInfo_zm" id="styleInfo_zm" class="form-make_zm-style-info">
 
               </div>
             </div>
           </div>
-          <div style="padding: 20px;">
-            <span>编辑</span> 
-            <div id="styleInfo_list">
-              <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
-                <div v-if="ruleForm.type == 'text'">
-                  <el-form-item label="文本名称" prop="textInfo">
-                    <el-input v-model="ruleForm.textInfo"></el-input>
-                  </el-form-item>
-                  <el-form-item label="字体大小" prop="size">
-                    <el-input-number v-model="ruleForm.size" controls-position="right" :min="12" :max="100"></el-input-number>
-                  </el-form-item>
-                  <el-form-item label="字体颜色" prop="color">
-                    <el-color-picker v-model="ruleForm.color"></el-color-picker>
-                  </el-form-item>
-                </div>
-                <div v-if="editFun == 'addQR'">
-                  <el-form-item label="宽度" prop="width">
-                    <el-input-number v-model="ruleForm.width" controls-position="right" :min="1"></el-input-number>
-                  </el-form-item>
-                  <el-form-item label="高度" prop="height">
-                    <el-input-number v-model="ruleForm.height" controls-position="right" :min="1"></el-input-number>
-                  </el-form-item>
-                </div>
-                <el-form-item label="关联字段" prop="replace">
-                  <el-select v-model="ruleForm.replace" placeholder="请选择关联字段">
-                    <el-option
-                      v-for="item in dict.type.tourism_make_key"
-                      :key="item.value"
-                      :label="item.label"
-                      :value="item.value">
-                    </el-option>
-                  </el-select>
-                </el-form-item>
-                <el-form-item>
-                  <el-button type="primary" @click="updateFun('ruleForm')">更新</el-button>
-                </el-form-item>
-              </el-form>
+        </div>
+        <div class="form-make_fm" :style="{ '--crad-zm': form.backBg ? `url(${form.backBg})`:'none' }">
+          <div class="form-make_fm-title">反面</div>
+          <div class="form-make_fm-info">
+            <!-- 工具  -->
+            <div class="form-make_fm-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,'backBg')"
+                :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="centerDialogVisibleOpen('addText','fm')">添加文本</el-button>
+              <!-- <el-button size="small" type="primary" @click="centerDialogVisibleOpen('addImage','fm')">添加图片</el-button> -->
+              <el-button style="margin-left: 10px;" size="small" type="primary" @click="centerDialogVisibleOpen('addQR','fm')">添加二维</el-button>
+            </div>
+            <!-- 样式  -->
+            <div class="form-make_fm-style">
+              <div class="form-make_fm-style-bgm"></div>
+              <div ref="styleInfo_fm" id="styleInfo_fm" class="form-make_fm-style-info">
+
+              </div>
             </div>
           </div>
         </div>
-
       </div>
       
     </div>
@@ -102,9 +101,13 @@
       :visible.sync="centerDialogVisible"
       width="30%"
       append-to-body
+      :close-on-click-modal="false"
       center>
       <div>
         <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
+          <div v-if="editFun == 'addImage'">
+            
+          </div>
           <div v-if="editFun == 'addText'">
             <el-form-item label="文本名称" prop="textInfo">
               <el-input v-model="ruleForm.textInfo"></el-input>
@@ -134,9 +137,13 @@
               </el-option>
             </el-select>
           </el-form-item>
+          <el-form-item label="层级" prop="zIndex">
+            <el-input-number v-model="ruleForm.zIndex" controls-position="right"></el-input-number>
+          </el-form-item>
         </el-form>
       </div>
       <span slot="footer" class="dialog-footer">
+        <el-button type="danger" @click="delDiv">删除</el-button>
         <el-button @click="centerDialogVisible = false">取 消</el-button>
         <el-button type="primary" @click="centerDialogVisiblePush">确 定</el-button>
       </span>
@@ -163,15 +170,22 @@ export default {
       loadingText: "拼命加载数据中...",
       formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
       configUrl: {
-        add: '/merchant/merchantEntitycardConfig/insertOrUpdate', // 新增地址
-        details: '/merchant/merchantEntitycardConfig/selectById', // 规格详情
-        edit: '/merchant/merchantEntitycardConfig/insertOrUpdate', // 编辑地址
+        add: '/merchant/templateEntitycard/insertOrUpdate', // 新增地址
+        details: '/merchant/templateEntitycard/selectById', // 规格详情
+        edit: '/merchant/templateEntitycard/insertOrUpdate', // 编辑地址
       },
       performId: null,
       form: {
         id: undefined,
         mainBg: null,
         backBg: null,
+        mainText: null,
+        backText: null,
+      },
+      rules1: {
+        name: [
+          { required: true, message: '请输入模板名称', trigger: ['blur', 'change'] },
+        ],
       },
       //  上传文件
       actionUrl: process.env.VUE_APP_BASE_API + process.env.VUE_APP_UPLOAD_IMAGE,
@@ -221,6 +235,9 @@ export default {
       }
       this.loading = false
       this.$nextTick(()=>{
+        document.getElementById('styleInfo_zm').innerHTML = this.form.mainText?this.form.mainText:''
+        document.getElementById('styleInfo_fm').innerHTML = this.form.backText?this.form.backText:''
+        this.addEvent()
         if(this.$refs["form"]) {
           this.$refs["form"].clearValidate();
         }
@@ -250,6 +267,23 @@ export default {
         this.loading = false
       }
     },
+    /**  获取子元素 并添加 点击事件 和 拖拽事件  */
+    addEvent(){
+      this.$nextTick(()=>{
+        // 获取所有子元素并绑定事件
+        const parent = document.getElementById('styleInfo_zm');
+        parent.querySelectorAll('div').forEach((child) => {
+          child.addEventListener('dragend',this.dragendFun)
+          child.addEventListener('click',this.clickFun)
+        });
+        const parent1 = document.getElementById('styleInfo_fm');
+        parent1.querySelectorAll('div').forEach((child) => {
+          child.addEventListener('dragend',this.dragendFun_fm)
+          child.addEventListener('click',this.clickFun)
+        });
+      })
+      
+    },
     /**
      * 保存
      * @date 2023-11-22
@@ -262,13 +296,13 @@ export default {
           this.loadingText = "提交数据中..."
           this.loading = true
           let params = JSON.parse(JSON.stringify(this.form))
+          params['mainText'] = document.getElementById('styleInfo_zm').innerHTML
+          params['backText'] = document.getElementById('styleInfo_fm').innerHTML
           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();
             })
@@ -288,7 +322,6 @@ export default {
      */
     reset() {
       if (this.$refs["form"]) {
-        //this.$refs["form"].resetFields();
         this.$set(this, 'form', {activationRule:[]})
         this.$nextTick(() => {
           this.$refs["form"].clearValidate();
@@ -335,54 +368,107 @@ export default {
     handleRemove(index) {
       this.form.goodsImage.splice(index,1)
     },
-
+    /**   添加文本   */
     addText(type){
-      let div = document.createElement('div')
-      div.setAttribute('class', 'form-make_zm-style-item');
-      div.setAttribute('id', 'text_'+ Number((new Date()).getTime()));
-      div.setAttribute('replace', 'text_'+ this.ruleForm.replace);
-
-      div.setAttribute('draggable', 'true');
-      div.style.color = this.ruleForm.color
-      div.style.fontSize = this.ruleForm.size + 'px'
-      div.style.backgroundColor = '#fff'
-      div.innerHTML = this.ruleForm.textInfo
-      div.addEventListener('dragend',this.dragendFun)
-      div.addEventListener('click',this.clickFun)
-      let box = document.getElementById('styleInfo')
-      box.appendChild(div)
+      let className = `form-make_${type}-style-item`
+      let idName = `styleInfo_${type}`
+      if(!this.ruleForm.id){
+        this.addTitle = '添加文本'
+        let div = document.createElement('div')
+        div.setAttribute('class', className);
+        div.setAttribute('id', 'text_'+ Number((new Date()).getTime()));
+        div.setAttribute('replace', 'text_'+ (this.ruleForm.replace?this.ruleForm.replace:''));
+
+        div.setAttribute('draggable', 'true');
+        div.style.color = this.ruleForm.color
+        div.style.fontSize = this.ruleForm.size + 'px'
+        div.style.backgroundColor = 'rgba(255, 255, 255, 0)'
+        div.innerHTML = this.ruleForm.textInfo
+        div.style.zIndex = this.ruleForm.zIndex
+        if(type == 'zm'){
+          div.addEventListener('dragend',this.dragendFun)
+        }else {
+          div.addEventListener('dragend',this.dragendFun_fm)
+        }
+        div.addEventListener('click',this.clickFun)
+        let box = document.getElementById(idName)
+        box.appendChild(div)
+      }else {
+        let div = document.getElementById(this.ruleForm.id)
+        div.setAttribute('replace', 'text_'+ (this.ruleForm.replace?this.ruleForm.replace:''));
+        div.style.color = this.ruleForm.color
+        div.style.fontSize = this.ruleForm.size + 'px'
+        div.style.zIndex = this.ruleForm.zIndex
+        div.innerHTML = this.ruleForm.textInfo
+      }
       this.centerDialogVisible = false
+      this.ruleForm = {}
     },
+    /**   添加图片   */
     addImage(type){
 
     },
+    /**   添加二维码   */
     addQR(type){
-      let div = document.createElement('div')
-      div.setAttribute('class', 'form-make_zm-style-item');
-      div.setAttribute('id', 'qr_'+ Number((new Date()).getTime()));
-      div.setAttribute('replace', 'qr_'+ this.ruleForm.replace);
-
-      div.setAttribute('draggable', 'true');
-      div.style.width = this.ruleForm.width  + 'px'
-      div.style.height = this.ruleForm.height + 'px'
-      div.style.backgroundColor = '#fff'
-      div.innerHTML = "二维码位置"
-      div.style.color = '#000'
-      div.style.fontSize = '16px'
-      div.addEventListener('dragend',this.dragendFun)
-      div.addEventListener('click',this.clickFun)
-      let box = document.getElementById('styleInfo')
-      
-      box.appendChild(div)
-      // let box1 = document.getElementById('styleInfo_list')
-      // box1.appendChild(div)
+      let className = `form-make_${type}-style-item`
+      let idName = `styleInfo_${type}`
+      if(!this.ruleForm.id) {
+        this.addTitle = '添加二维码'
+        let div = document.createElement('div')
+        div.setAttribute('class', className);
+        div.setAttribute('id', 'qr_'+ Number((new Date()).getTime()));
+        div.setAttribute('replace', 'qr_'+ (this.ruleForm.replace?this.ruleForm.replace:''));
+        
+        div.setAttribute('draggable', 'true');
+        div.style.width = this.ruleForm.width  + 'px'
+        div.style.height = this.ruleForm.height + 'px'
+        div.style.backgroundColor = '#fff'
+        div.innerHTML = "二维码位置"
+        div.style.color = '#000'
+        div.style.fontSize = '16px'
+        div.style.zIndex = this.ruleForm.zIndex
+        if(type == 'zm'){
+          div.addEventListener('dragend',this.dragendFun)
+        }else {
+          div.addEventListener('dragend',this.dragendFun_fm)
+        }
+        div.addEventListener('click',this.clickFun)
+        let box = document.getElementById(idName)
+        
+        box.appendChild(div)
+        // let box1 = document.getElementById('styleInfo_list')
+        // box1.appendChild(div)
+      }else {
+        let div = document.getElementById(this.ruleForm.id)
+        div.setAttribute('replace', 'qr_'+ (this.ruleForm.replace?this.ruleForm.replace:''));
+        div.style.width = this.ruleForm.width + 'px'
+        div.style.height = this.ruleForm.height + 'px'
+        div.style.zIndex = this.ruleForm.zIndex
+      }
       this.centerDialogVisible = false
+      this.ruleForm = {}
     },
     
-    /**  拖拽事件  */
+    /** 正面 拖拽事件  */
     dragendFun(e){
       let draggedItem = document.getElementById(e.target.id);
-      let dropzone = document.getElementById('styleInfo');
+      let dropzone = document.getElementById('styleInfo_zm');
+      // 获取元素相对于父元素的位置
+      let rect = draggedItem.getBoundingClientRect();
+      let parentRect = dropzone.getBoundingClientRect();
+    
+      // 计算元素在父元素中的位置
+      let left =e.clientX - parentRect.x;
+      let top =e.clientY - parentRect.y;
+      console.log("dragend事件====",e.clientX,e.clientY)
+      // 设置元素的新位置
+      draggedItem.style.left = left + 'px';
+      draggedItem.style.top = top + 'px';
+    },
+    /** 正面 拖拽事件  */
+    dragendFun_fm(e){
+      let draggedItem = document.getElementById(e.target.id);
+      let dropzone = document.getElementById('styleInfo_fm');
       // 获取元素相对于父元素的位置
       let rect = draggedItem.getBoundingClientRect();
       let parentRect = dropzone.getBoundingClientRect();
@@ -399,18 +485,32 @@ export default {
       let draggedItem = document.getElementById(e.target.id);
       let content = draggedItem.getAttribute('replace')
       let info = draggedItem.innerHTML
+      console.log("content==",content)
       if(content.indexOf('text_') > -1) {
+        console.log("draggedItem.style.color==",draggedItem.style.color)
+        this.editFun = 'addText'
+        this.centerDialogVisible = true
         this.$set(this,'ruleForm',{
           id: e.target.id,
           type: 'text',
           textInfo: info,
           size: Number(draggedItem.style.fontSize.replace('px','')),
           color: draggedItem.style.color,
+          zIndex: draggedItem.style.zIndex,
           replace: content.replace('text_','')
         })
       }
       if(content.indexOf('qr_') > -1) {
-
+        this.editFun = 'addQr'
+        this.centerDialogVisible = true
+        this.$set(this,'ruleForm',{
+          id: e.target.id,
+          type: 'qr',
+          width: Number(draggedItem.style.width.replace('px','')),
+          height: Number(draggedItem.style.height.replace('px','')),
+          zIndex: draggedItem.style.zIndex,
+          replace: content.replace('qr_','')
+        })
       }
       console.log(this.ruleForm)
     },
@@ -418,8 +518,22 @@ export default {
     centerDialogVisibleOpen(fun,type) {
       this.editType = type
       this.editFun = fun
+      this.ruleForm = {}
       this.centerDialogVisible = true
+      this.$nextTick(()=>{
+        this.$refs.ruleForm.clearValidate()
+        if(this.editFun == 'addText'){
+          this.$set(this.ruleForm,'zIndex',1)
+        }
+        if(this.editFun == 'addImage'){
+          this.$set(this.ruleForm,'zIndex',1)
+        }
+        if(this.editFun == 'addQR'){
+          this.$set(this.ruleForm,'zIndex',1)
+        }
+      })
     },
+    /**  编辑div */
     centerDialogVisiblePush() {
       switch(this.editFun){
         case 'addText' : this.addText(this.editType); break;
@@ -427,6 +541,14 @@ export default {
         case 'addQR' : this.addQR(this.editType); break;
       }
     },
+    /**  删除div  */
+    delDiv(){
+      if(this.ruleForm.id) {
+        document.getElementById(this.ruleForm.id).remove()
+        this.centerDialogVisible = false
+        this.ruleForm = {}
+      } 
+    },
     updateFun() {
       let div = document.getElementById(this.ruleForm.id)
       if(this.ruleForm.type == 'text') {
@@ -442,7 +564,6 @@ export default {
 
 <style lang="scss" scoped>
 .form-dialog-box {
-  padding: 0 30px;
   padding: 0 30px;
   min-height: 50vh;
   max-height: 65vh;
@@ -597,17 +718,19 @@ export default {
 
 .form-make {
   display: flex;
-  flex-direction: column;
-  justify-content: center;
+  // flex-direction: column;
+  justify-content: space-between;
   width: 100%;
   height: 100%;
   --crad-zm: none;
   --crad-fm: none;
-  --crad-w: 860px;
-  --crad-h: 540px;
+  // --crad-w: 860px;
+  // --crad-h: 540px;
+  --crad-w: 460px;
+  --crad-h: 288px;
   .form-make_zm {
     display: flex;
-    height: 600px;
+    height: 350px;
     .form-make_zm-title {
       width: 20px;
       height: 100%;
@@ -661,6 +784,63 @@ export default {
       }
     }
   }
+
+  .form-make_fm {
+    display: flex;
+    height: 350px;
+    .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;
+        box-sizing: border-box;
+        overflow: hidden;
+        position: relative;
+        .form-make_fm-style-bgm {
+          width: 100%;
+          height: 100%;
+          background-image: var(--crad-zm);
+          background-size: 100% 100%;
+          background-repeat: no-repeat;
+          border-radius: 20px;
+        }
+        .form-make_fm-style-info {
+          width: 100%;
+          height: 100%;
+          position: absolute;
+          z-index: 9;
+          top: 0;
+          left: 0;
+          border-radius: 20px;
+          box-sizing: border-box;
+          overflow: hidden;
+        }
+      }
+    }
+  }
 }
 
 
@@ -682,5 +862,20 @@ export default {
   align-items: center;
   justify-content: center;
   flex-shrink: 0;
+  background-color: rgba(255, 255, 255, 1);
+}
+.form-make_fm-style-item {
+  position: absolute;
+  top: 30px;
+  left: 30px;
+  color: #000;
+  font-size: 16px;
+  cursor: pointer;
+  white-space: nowrap;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  background-color: rgba(255, 255, 255, 1);
 }
 </style>

+ 245 - 95
src/views/tourism/membershipManagement/physicalCard/formBox/printForm.vue

@@ -8,32 +8,34 @@
     @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">
+        <div class="form-make_zm" :style="{ '--crad-zm': form.mainBg ? `url(${form.mainBg})`:'none' }">
           <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 class="form-make_zm-style">
+              <div class="form-make_zm-style-bgm" id="myElement" ref="myElement"></div>
+              <div ref="styleInfo_zm" id="styleInfo_zm" class="form-make_zm-style-info">
+
+              </div>
             </div>
           </div>
         </div>
-
-        <div class="form-make_fm">
+        <div class="form-make_fm" :style="{ '--crad-zm': form.backBg ? `url(${form.backBg})`:'none' }">
           <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" style="position: relative;">
-              <div class="form-make_fm-style-bgm" ref="myElement1">
+            <div class="form-make_fm-style">
+              <div class="form-make_fm-style-bgm" id="myElement1" ref="myElement1"></div>
+              <div ref="styleInfo_fm" id="styleInfo_fm" class="form-make_fm-style-info">
 
               </div>
-              <div class="form-make_fm-style-text" ref="myElement2">
-                <div 
-                v-if="isQrCode"
-                id="barcode">
-                  <barcode :value="cardNo" format="CODE128" :width="width" height="48"></barcode>  
-                </div>
-              </div>
-              
             </div>
           </div>
         </div>
@@ -46,7 +48,7 @@
       type="primary" 
       @click="submitForm" 
       :loading="loading">
-              {{ loading ? '提交中...' : '提交' }}
+              {{ loading ? '打印中...' : '打印' }}
       </el-button>
     </span>
     <!-- 添加或修改对话框 End -->
@@ -60,7 +62,7 @@ import {
 } from '@/api/CURD'
 import VueBarcode from 'vue-barcode';
 //映入注册
-// import JsBarcode from 'jsbarcode'
+import JsBarcode from 'jsbarcode'
 import html2canvas from 'html2canvas';
 export default {
   name: "addAndEdit",
@@ -76,13 +78,23 @@ export default {
       loadingText: "拼命加载数据中...",
       formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2  : 获取详情失败 
       configUrl: {
-        print:'/zebra/card/print/io/upload'
+        print:'/zebra/card/print/io/upload',
+        codeDetails: '/merchant/templateEntitycard/selectById', // 规格详情
       },
       isQrCode: false,
       bgm1: require('./1_0.png') ,//require('./zm.jpg'),
       bgm2: require('./1_1.png'), // require('./fm.jpg')
       cardNo: '',
-      width: 3
+      width: 3,
+      tableList: [],
+      form: {
+        id: undefined,
+        mainBg: null,
+        backBg: null,
+        mainText: null,
+        backText: null,
+      },
+      formCopy: {}
     };
   },
   methods: {
@@ -94,7 +106,7 @@ export default {
       this.loading = true
       this.actionUrlLoading = false
       this.model = model
-      this.form = JSON.parse(JSON.stringify(row))
+      this.formCopy = JSON.parse(JSON.stringify(row))
       this.formStatus = 0
       this.cardNo = row.cardNo //row.cardNo
       if(this.cardNo.length > 16 ) {
@@ -107,32 +119,21 @@ export default {
         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 //是否显示文字信息
-      //     });
-      //   })
-        
-      // }  
+      await this.getTableDeatilsCodeFun(row)
       this.formStatus = 1
       this.isQrCode = true
+      this.$nextTick(()=>{
+        document.getElementById('styleInfo_zm').innerHTML = this.form.mainText?this.form.mainText:''
+        document.getElementById('styleInfo_fm').innerHTML = this.form.backText?this.form.backText:''
+        this.addEvent()
+      })
       this.loading = false
     },
     /** 获取详情 */
-    async getTableDeatilsFun(row) {
-      const id = row.id
-      this.loading = true
+     async getTableDeatilsCodeFun(row) {
+      const id = row.templateId
       try {
-        let res = await getTableDeatilsByIdApi(this.configUrl.details, { id })
+        let res = await getTableDeatilsByIdApi(this.configUrl.codeDetails, { id })
         if (res.code == 200) {
           let obj = {
             ...res.data,
@@ -146,11 +147,62 @@ export default {
         }
         this.loading = false
       } catch (error) {
-        console.error('获取详情失败!!!!', error)
+        this.$message.error('获取详情失败!!!');
         this.formStatus = 2
         this.loading = false
       }
     },
+    /**  获取子元素 并添加 点击事件 和 拖拽事件  */
+    addEvent(){
+      this.$nextTick(()=>{
+        // 获取所有子元素并绑定事件
+        const parent = document.getElementById('styleInfo_zm');
+        parent.querySelectorAll('div').forEach((child) => {
+          if(child.getAttribute('replace')) {
+            if(child.getAttribute('replace').indexOf('qr_') != -1){
+              let content = child.getAttribute('replace').replace('qr_','').replace('${','').replace('}','')
+              child.innerHTML = `<img id="img_${child.getAttribute('id')}" style="width:100%;hright:100%" />`
+              //实例化
+              this.$nextTick(()=>{
+                JsBarcode(`#img_${child.getAttribute('id')}`, this.formCopy[content], {
+                    format: "CODE39",  //条形码的格式
+                    // lineColor: "#0aa",  //线条颜色
+                    width:1, //线宽
+                    height:40,  //条码高度
+                    // displayValue: false //是否显示文字信息
+                });
+              })
+            }else if(child.getAttribute('replace').indexOf('text_') != -1) {
+              let content = child.getAttribute('replace').replace('text_','').replace('${','').replace('}','')
+              child.innerHTML = this.formCopy[content]
+            }
+          }
+        });
+        const parent1 = document.getElementById('styleInfo_fm');
+        parent1.querySelectorAll('div').forEach((child) => {
+          if(child.getAttribute('replace')) {
+            if(child.getAttribute('replace').indexOf('qr_') != -1){
+              let content = child.getAttribute('replace').replace('qr_','').replace('${','').replace('}','')
+              child.innerHTML = `<img id="img_${child.getAttribute('id')}" style="width:100%;hright:100%" />`
+              //实例化
+              this.$nextTick(()=>{
+                JsBarcode(`#img_${child.getAttribute('id')}`, this.formCopy[content], {
+                    format: "CODE39",  //条形码的格式
+                    // lineColor: "#0aa",  //线条颜色
+                    width:1, //线宽
+                    height:40,  //条码高度
+                    // displayValue: false //是否显示文字信息
+                });
+              })
+            }else if(child.getAttribute('replace').indexOf('text_') != -1) {
+              let content = child.getAttribute('replace').replace('text_','').replace('${','').replace('}','')
+              child.innerHTML = this.formCopy[content]
+            }
+          }
+        });
+      })
+      
+    },
     /**
      * 保存
      * @date 2023-11-22
@@ -159,18 +211,19 @@ export default {
     async submitForm(type) {
       console.log("dsfsfds=======", type, this.form)
       try {
-        this.loadingText = "提交数据中..."
+        this.loadingText = "打印数据中..."
         this.loading = true
         let cardImgFrontFile = await this.captureCanvas('myElement')
+        let cardImgFrontFile1 = await this.captureCanvas('styleInfo_zm')
         let cardImgBackFile = await this.captureCanvas('myElement1')
-        let cardFontBackFilee = await this.captureCanvas('myElement2')
+        let cardFontBackFilee = await this.captureCanvas('styleInfo_fm')
         const formData = new FormData();
         formData.append("ip", '172.16.90.128');
         formData.append("cardImgFrontFile", cardImgFrontFile);
-        formData.append("cardFontFrontFile", null);
+        formData.append("cardFontFrontFile", cardImgFrontFile1);
         formData.append("cardImgBackFile", cardImgBackFile);
-        formData.append("cardFontBackFilee", cardFontBackFilee);
-        let res1 = await fetch('https://zebra.dev.gztjy.top/zebra/card/print/io/upload', {  
+        formData.append("cardFontBackFile", cardFontBackFilee);
+        let res1 = await fetch(process.env.VUE_APP_PRINT_URL, {  
           method: 'POST', // 或者 'GET'  
           // headers: { 
           //   'Content-Type': 'multipart/form-data' //携带参数为json
@@ -304,7 +357,6 @@ export default {
 
 <style lang="scss" scoped>
 .form-dialog-box {
-  padding: 0 30px;
   padding: 0 30px;
   min-height: 50vh;
   max-height: 65vh;
@@ -429,21 +481,49 @@ export default {
   }
 }
 
+::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;
-  align-items: center;
+  // flex-direction: column;
+  justify-content: space-between;
   width: 100%;
   height: 100%;
   --crad-zm: none;
   --crad-fm: none;
-  --crad-w: 862px;
-  --crad-h: 542px;
+  // --crad-w: 860px;
+  // --crad-h: 540px;
+  --crad-w: 460px;
+  --crad-h: 288px;
   .form-make_zm {
     display: flex;
-    height: var(--crad-h);
+    height: 350px;
     .form-make_zm-title {
       width: 20px;
       height: 100%;
@@ -453,27 +533,54 @@ export default {
       align-items: center;
       font-size: 24px;
       font-family: 600;
-      padding: 0 20px;
+      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;
+        box-sizing: border-box;
+        overflow: hidden;
+        position: relative;
+        .form-make_zm-style-bgm {
+          width: 100%;
+          height: 100%;
+          background-image: var(--crad-zm);
+          background-size: 100% 100%;
+          background-repeat: no-repeat;
+          border-radius: 20px;
+        }
+        .form-make_zm-style-info {
+          width: 100%;
+          height: 100%;
+          position: absolute;
+          z-index: 9;
+          top: 0;
+          left: 0;
+          border-radius: 20px;
+          box-sizing: border-box;
+          overflow: hidden;
+        }
       }
     }
   }
+
   .form-make_fm {
     display: flex;
-    height: var(--crad-h);
-    margin-top: 10px;
+    height: 350px;
     .form-make_fm-title {
       width: 20px;
       height: 100%;
@@ -489,64 +596,44 @@ export default {
     .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;
-        box-sizing: border-box;
-        position: relative;
         border-radius: 20px;
+        box-sizing: border-box;
         overflow: hidden;
+        position: relative;
         .form-make_fm-style-bgm {
           width: 100%;
           height: 100%;
-          background-image: var(--crad-fm);
+          background-image: var(--crad-zm);
           background-size: 100% 100%;
           background-repeat: no-repeat;
-          position: absolute;
-          top: 0px;
-          left: 0px;
-          z-index: 88;
           border-radius: 20px;
-          overflow: hidden;
         }
-        .form-make_fm-style-text {
+        .form-make_fm-style-info {
           width: 100%;
           height: 100%;
           position: absolute;
-          top: 0px;
-          left: 0px;
-          z-index: 99;
+          z-index: 9;
+          top: 0;
+          left: 0;
           border-radius: 20px;
+          box-sizing: border-box;
           overflow: hidden;
         }
-        
       }
     }
   }
-  #barcode {
-    width: 323px;
-    height: 91px;
-    position: absolute;
-    z-index: 99;
-    bottom: 46px;
-    background-color: rgb(255, 255, 255);
-    display: flex;
-    justify-content: center;
-    box-sizing: border-box;
-    right: 58px;
-
-    // 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;
-  }
 }
 
 
@@ -556,4 +643,67 @@ export default {
 .custom-class-box {
   z-index: 999999 !important;
 }
+.form-make_zm-style-item {
+  position: absolute;
+  top: 30px;
+  left: 30px;
+  color: #000;
+  font-size: 16px;
+  cursor: pointer;
+  white-space: nowrap;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  background-color: rgba(255, 255, 255, 1);
+}
+.form-make_fm-style-item {
+  position: absolute;
+  top: 30px;
+  left: 30px;
+  color: #000;
+  font-size: 16px;
+  cursor: pointer;
+  white-space: nowrap;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  background-color: rgba(255, 255, 255, 1);
+}
+
+
+</style>
+<style>
+.custom-class-box {
+  z-index: 999999 !important;
+}
+.form-make_zm-style-item {
+  position: absolute;
+  top: 30px;
+  left: 30px;
+  color: #000;
+  font-size: 16px;
+  cursor: pointer;
+  white-space: nowrap;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  background-color: rgba(255, 255, 255, 1);
+}
+.form-make_fm-style-item {
+  position: absolute;
+  top: 30px;
+  left: 30px;
+  color: #000;
+  font-size: 16px;
+  cursor: pointer;
+  white-space: nowrap;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-shrink: 0;
+  background-color: rgba(255, 255, 255, 1);
+}
 </style>

+ 4 - 4
src/views/tourism/membershipManagement/physicalCard/physicalCardTemplate.vue

@@ -38,14 +38,14 @@
             <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="">
+                    <img style="width: 120px;height: 80px;" :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="">
+                    <img style="width: 120px;height: 80px;" :src="scope.row.backBg" alt="">
                   </div>
                 </template>
             </el-table-column>
@@ -55,13 +55,13 @@
               class-name="small-padding fixed-width"
             >
               <template slot-scope="scope" >
-                <el-button
+                <!-- <el-button
                   size="mini"
                   type="text"
                   icon="el-icon-edit"
                   @click="handleDetails(scope.row)"
                   v-hasPermi="configPermi.details"
-                >详情</el-button>
+                >详情</el-button> -->
                 <el-button
                   size="mini"
                   type="text"