Sfoglia il codice sorgente

获客链接管理页面新增提取链接功能+生成二维码功能

cgp 2 giorni fa
parent
commit
e9dca66ca0
1 ha cambiato i file con 256 aggiunte e 9 eliminazioni
  1. 256 9
      src/views/qw/acquisitionAssistant/index.vue

+ 256 - 9
src/views/qw/acquisitionAssistant/index.vue

@@ -97,6 +97,7 @@
       <el-table-column label="链接ID" prop="linkId" width="200" :show-overflow-tooltip="true" />
       <el-table-column label="链接名称" prop="linkName" width="150" :show-overflow-tooltip="true" />
       <el-table-column label="链接URL" prop="url" width="200" :show-overflow-tooltip="true" />
+      <el-table-column label="pageParam" prop="pageParam" width="150" :show-overflow-tooltip="true" />
       <el-table-column label="使用范围" prop="rangeDesc" width="200" :show-overflow-tooltip="true" />
       <el-table-column label="状态" width="80" align="center">
         <template slot-scope="scope">
@@ -110,12 +111,7 @@
           <span>{{ parseTime(scope.row.qwCreateTime) }}</span>
         </template>
       </el-table-column>
-<!--      <el-table-column label="最后同步时间" width="160" align="center">-->
-<!--        <template slot-scope="scope">-->
-<!--          <span>{{ parseTime(scope.row.syncTime) }}</span>-->
-<!--        </template>-->
-<!--      </el-table-column>-->
-      <el-table-column label="操作" align="center" width="220" fixed="right">
+      <el-table-column label="操作" align="center" width="300" fixed="right">
         <template slot-scope="scope">
           <el-button
             size="mini"
@@ -135,6 +131,21 @@
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
           >删除</el-button>
+          <!-- 新增:一键提取链接按钮 -->
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-link"
+            @click="handleCopyLink(scope.row)"
+          >提取链接</el-button>
+          <!-- 新增:生成二维码按钮 -->
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-s-promotion"
+            @click="handleGenerateQRCode(scope.row)"
+            style="color: #67C23A;"
+          >生成二维码</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -226,8 +237,6 @@
           <!-- 已选信息展示 -->
           <div v-if="form.selectedUserIds && form.selectedUserIds.length" class="el-form-item__tips" style="color: #909399; font-size: 12px; margin-top: 5px;">
             <div>已选择 {{ form.selectedUserIds.length }} 名成员</div>
-<!--            <div>企微用户ID: {{ form.userListParam ? form.userListParam.join(', ') : '-' }}</div>-->
-<!--            <div>本地数据库ID: {{ form.qwUserTableIdList ? form.qwUserTableIdList.join(', ') : '-' }}</div>-->
             <el-button type="text" @click="clearSelectedUsers" size="mini">清空</el-button>
           </div>
         </el-form-item>
@@ -300,6 +309,40 @@
         <el-form-item label="备注">{{ detailData.remark || '-' }}</el-form-item>
       </el-form>
     </el-dialog>
+
+    <!-- 二维码弹窗 -->
+    <el-dialog
+      title="获客链接二维码"
+      :visible.sync="qrCodeDialog.visible"
+      width="500px"
+      append-to-body
+      @closed="handleQrCodeDialogClosed"
+    >
+      <div class="qr-code-container" v-loading="qrCodeDialog.generating">
+        <div class="qr-code-wrapper" v-if="qrCodeDialog.dataUrl">
+          <img :src="qrCodeDialog.dataUrl" alt="二维码" class="qr-code-image" />
+          <div class="qr-code-info">
+            <p><strong>链接名称:</strong>{{ qrCodeDialog.linkName }}</p>
+            <p><strong>链接ID:</strong>{{ qrCodeDialog.linkId }}</p>
+            <p><strong>完整链接:</strong>
+              <el-link :href="qrCodeDialog.fullUrl" target="_blank" type="primary" :underline="false">
+                {{ qrCodeDialog.fullUrl }}
+              </el-link>
+            </p>
+            <p><strong>pageParam:</strong>{{ qrCodeDialog.pageParam }}</p>
+          </div>
+        </div>
+        <div v-else-if="!qrCodeDialog.generating" class="qr-code-empty">
+          <el-empty description="暂无二维码" />
+        </div>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="downloadQRCode" :disabled="!qrCodeDialog.dataUrl">
+          <i class="el-icon-download"></i> 保存二维码
+        </el-button>
+        <el-button @click="qrCodeDialog.visible = false">关 闭</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -315,6 +358,8 @@ import {
   qwUserCompanyList
 } from '@/api/qw/acquisitionAssistant'
 
+import QRCode from 'qrcodejs2'
+
 export default {
   name: 'AcquisitionAssistant',
   data() {
@@ -342,6 +387,17 @@ export default {
       // 是否显示弹出层
       open: false,
       detailOpen: false,
+      // 二维码弹窗数据
+      qrCodeDialog: {
+        visible: false,
+        generating: false,
+        dataUrl: null,
+        fullUrl: '',
+        linkName: '',
+        linkId: '',
+        pageParam: '',
+        rowData: null
+      },
       // 查询参数 - corpId作为全局筛选条件
       queryParams: {
         pageNum: 1,
@@ -365,7 +421,7 @@ export default {
         userListParam: [],           // 企微用户ID数组 (用于前端显示和回显)
         departmentListParam: [],     // 部门ID数组
         qwUserTableIdList: [],       // 本地数据库ID数组 (需要传给后端保存)
-        userList: '',                // 完整的JSON字符串 (可能包含userList+departmentList)
+        userList: '',                // 完整的JSON字符串 (包含userList)
 
         // 优先分配相关
         priorityUserListParam: [],   // 优先分配的企微用户ID数组
@@ -392,6 +448,8 @@ export default {
       userTotal: 0,
       hasMoreUsers: true,
       initialLoaded: false,
+      // 基础域名
+      baseDomain: 'c.ysyd.top'
     }
   },
   computed: {
@@ -415,6 +473,150 @@ export default {
     })
   },
   methods: {
+    /** 获取完整链接 */
+    getFullUrl(row) {
+      if (!row || !row.pageParam) return `${this.baseDomain}`
+      return `${this.baseDomain}/${row.pageParam}`
+    },
+
+    /** 复制完整链接 */
+    handleCopyFullUrl(row) {
+      const fullUrl = this.getFullUrl(row)
+      this.copyToClipboard(fullUrl, '完整链接已复制')
+    },
+
+    /** 一键提取链接 */
+    handleCopyLink(row) {
+      const fullUrl = this.getFullUrl(row)
+      this.copyToClipboard(fullUrl, '链接已提取并复制到剪贴板')
+    },
+
+    /** 复制到剪贴板的通用方法 */
+    copyToClipboard(text, successMessage) {
+      // 创建临时输入框
+      const textarea = document.createElement('textarea')
+      textarea.value = text
+      textarea.style.position = 'fixed'
+      textarea.style.opacity = '0'
+      document.body.appendChild(textarea)
+      textarea.select()
+
+      try {
+        const successful = document.execCommand('copy')
+        if (successful) {
+          this.$message({
+            message: successMessage || '复制成功',
+            type: 'success',
+            duration: 2000
+          })
+        } else {
+          this.$message.error('复制失败,请手动复制')
+        }
+      } catch (err) {
+        console.error('复制失败:', err)
+        this.$message.error('复制失败,请手动复制')
+      } finally {
+        document.body.removeChild(textarea)
+      }
+    },
+
+    /** 生成二维码 - 使用项目自带的QRCode库 */
+    handleGenerateQRCode(row) {
+      if (!row || !row.pageParam) {
+        this.$message.warning('该链接没有pageParam参数,无法生成二维码')
+        return
+      }
+
+      const fullUrl = this.getFullUrl(row)
+
+      // 显示二维码弹窗,并显示加载中
+      this.qrCodeDialog.visible = true
+      this.qrCodeDialog.generating = true
+      this.qrCodeDialog.dataUrl = null
+      this.qrCodeDialog.fullUrl = fullUrl
+      this.qrCodeDialog.linkName = row.linkName || '-'
+      this.qrCodeDialog.linkId = row.linkId || '-'
+      this.qrCodeDialog.pageParam = row.pageParam || '-'
+      this.qrCodeDialog.rowData = row
+
+      try {
+        // 使用 setTimeout 让UI能够更新加载状态
+        setTimeout(() => {
+          // 创建一个临时容器来生成二维码
+          const tempDiv = document.createElement('div')
+          tempDiv.style.position = 'absolute'
+          tempDiv.style.left = '-9999px'
+          tempDiv.style.top = '-9999px'
+          document.body.appendChild(tempDiv)
+
+          try {
+            // 使用项目自带的 QRCode 库生成二维码
+            const qrcode = new QRCode(tempDiv, {
+              text: fullUrl,
+              width: 300,
+              height: 300,
+              colorDark: '#000000',
+              colorLight: '#ffffff',
+              correctLevel: QRCode.CorrectLevel.H // 使用高容错率
+            })
+
+            // 等待二维码生成
+            setTimeout(() => {
+              try {
+                // 从临时容器中获取生成的 canvas 或 img 元素
+                const canvas = tempDiv.querySelector('canvas')
+                if (canvas) {
+                  // 转换为 data URL
+                  this.qrCodeDialog.dataUrl = canvas.toDataURL('image/png')
+                } else {
+                  // 如果使用 table 方式生成,尝试其他方法
+                  console.warn('未找到canvas元素,尝试其他方法')
+                  this.$message.warning('二维码生成方式不支持保存为图片,请更新浏览器')
+                }
+              } catch (err) {
+                console.error('获取二维码图片失败:', err)
+                this.$message.error('生成二维码失败')
+              } finally {
+                // 清理临时容器
+                document.body.removeChild(tempDiv)
+                this.qrCodeDialog.generating = false
+              }
+            }, 100)
+          } catch (err) {
+            console.error('生成二维码失败:', err)
+            this.$message.error('生成二维码失败')
+            document.body.removeChild(tempDiv)
+            this.qrCodeDialog.generating = false
+          }
+        }, 50)
+      } catch (error) {
+        console.error('生成二维码失败:', error)
+        this.$message.error('生成二维码失败')
+        this.qrCodeDialog.generating = false
+      }
+    },
+
+    /** 下载二维码 */
+    downloadQRCode() {
+      if (!this.qrCodeDialog.dataUrl) return
+
+      // 创建下载链接
+      const link = document.createElement('a')
+      link.href = this.qrCodeDialog.dataUrl
+      link.download = `qrcode_${this.qrCodeDialog.linkId || 'link'}_${Date.now()}.png`
+      document.body.appendChild(link)
+      link.click()
+      document.body.removeChild(link)
+
+      this.$message.success('二维码已开始下载')
+    },
+
+    /** 二维码弹窗关闭后的处理 */
+    handleQrCodeDialogClosed() {
+      // 可以在这里做一些清理工作,如果需要的话
+      // 目前不需要特殊处理
+    },
+
     /** 格式化时间 */
     parseTime(time, pattern) {
       if (arguments.length === 0 || !time) {
@@ -1079,4 +1281,49 @@ export default {
 .el-select-dropdown__item span {
   line-height: 1.5;
 }
+
+/* 二维码弹窗样式 */
+.qr-code-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  min-height: 350px;
+  padding: 20px 0;
+}
+
+.qr-code-wrapper {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 100%;
+}
+
+.qr-code-image {
+  width: 250px;
+  height: 250px;
+  border: 1px solid #eee;
+  padding: 10px;
+  background: white;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  margin-bottom: 20px;
+}
+
+.qr-code-info {
+  width: 100%;
+  padding: 15px;
+  background-color: #f9f9f9;
+  border-radius: 4px;
+  font-size: 14px;
+}
+
+.qr-code-info p {
+  margin: 8px 0;
+  word-break: break-all;
+}
+
+.qr-code-empty {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+}
 </style>