|
|
@@ -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>
|