Procházet zdrojové kódy

企微群裂变-二维码联调

lishanshan před 6 měsíci
rodič
revize
fa6f9933f2

+ 1 - 1
.npmrc

@@ -1,2 +1,2 @@
 tag-version-prefix=""
-registry=https://registry.npm.taobao.org
+# registry=https://registry.npm.taobao.org

+ 21 - 1
src/api/activity/index.js

@@ -71,4 +71,24 @@ export function getWecomEmployeeList(data) {
     method: 'get',
     params: data,
   })
-}
+}
+
+// 通过企微群id查询企微群的二维码链接
+export function getWecomGroupQrcode(data, config) {
+  return request({
+    url: service + '/system/weGroupFission/getChartQrCodeByChatIdStream',
+    method: 'get',
+    params: data,
+    ...config
+  })
+}
+
+// 生成小程序码的二进制流
+export function getMiniProgramQrCode(data, config) {
+  return request({
+    url: service + '/system/weGroupFission/getWechatGroupFissionUrlStream',
+    method: 'post',
+    data,
+    ...config
+  })
+}

+ 14 - 10
src/views/weGroupFission/modules/CompPreview.vue

@@ -11,8 +11,8 @@
                 <div class="poster-title">{{ formData.title || '请填写活动名称' }}</div>
 
                 <div class="poster-badge">
-                    <span class="dot">●</span>
-                    <span>活动说明</span>
+                    <span class="dot">● </span>
+                    <span> 活动说明</span>
                 </div>
 
                 <div class="poster-desc">{{ formData.activityInstructions || '请填写活动说明' }}</div>
@@ -40,16 +40,17 @@
                 </div>
             </div>
 
-            <div class="poster-footer" :style="{ backgroundImage: `url(${staticUrl}/static/activity/bg3.png)` }">
+            <div class="poster-footer" :style="{ backgroundImage: `url(${formData.wecomGroupQrcode} || ${staticUrl}/static/activity/bg3.png)` }">
                 <div class="qr-box">
-                    <div id="qrcode"></div>
+                    <img v-if="formData.wecomGroupQrcode" :src="formData.wecomGroupQrcode" alt="企微群二维码" style="width: 100%; height: 100%; object-fit: contain;" />
+                    <div v-else id="qrcode"></div>
                 </div>
                 <div class="info-right">
                     <div class="brand">
                         <!-- <div class="brand-logo" style="background: #eee;"></div> -->
                         <span>{{ formData.merchantName || '--' }}</span>
                     </div>
-                    <div class="date-tag">{{ formData.timeRange.join(' ~ ') || '?? ~ ??' }}</div>
+                    <div class="date-tag">{{ formData.timeRange && Array.isArray(formData.timeRange) ? formData.timeRange.join(' ~ ') : '?? ~ ??' }}</div>
                 </div>
             </div>
         </div>
@@ -72,7 +73,7 @@ export default {
     },
     data() {
         return {
-            
+
         };
     },
     computed: {
@@ -112,9 +113,9 @@ export default {
         // 初始化二维码
         getQRCode(url) {
             new QRCode('qrcode', {
-                text: url, 
-                width: 64, 
-                height: 64, 
+                text: url,
+                width: 64,
+                height: 64,
                 colorDark: '#000000', // 二维码前景色
                 colorLight: '#ffffff', // 二维码背景色
                 correctLevel: QRCode.CorrectLevel.H // 容错级别:L/M/Q/H(H最高)
@@ -192,6 +193,9 @@ export default {
         }
 
         .poster-badge {
+            color: #fff;
+            font-size: 14px;
+            font-weight: 500;
             padding: 4px 10px;
             margin-bottom: 10px;
             border-radius: 15px;
@@ -313,4 +317,4 @@ export default {
         }
     }
 }
-</style>
+</style>

+ 59 - 11
src/views/weGroupFission/modules/modal.vue

@@ -24,7 +24,7 @@
                                 <el-date-picker ref="timeRange"
                                     type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss"
                                     range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
-                                    :picker-options="pickerOptions"  v-model="formModel.timeRange" 
+                                    :picker-options="pickerOptions"  v-model="formModel.timeRange"
                                 ></el-date-picker>
                             </el-form-item>
 
@@ -39,7 +39,7 @@
                                 </el-select>
                             </el-form-item>
                             <el-form-item label="关联企微群" prop="wecomGroupId">
-                                <el-select v-model="formModel.wecomGroupId" placeholder="请选择关联企微群" filterable>
+                                <el-select v-model="formModel.wecomGroupId" placeholder="请选择关联企微群" filterable @change="onWecomGroupChange">
                                     <el-option v-for="item in dicts.wecomGroupId" :key="item.val" :label="item.name" :value="item.val"></el-option>
                                 </el-select>
                             </el-form-item>
@@ -114,7 +114,7 @@
         <div class="drawer-footer">
             <el-button v-if="currentStep > 0" @click="handlePrev">上一步</el-button>
             <el-button v-if="currentStep < 3" type="primary" @click="handleNext">下一步</el-button>
-            <el-button v-if="currentStep === 3" type="primary" 
+            <el-button v-if="currentStep === 3" type="primary"
                 :loading="btnLoading"
                 @click="handleSubmit"
             >完成并保存</el-button>
@@ -123,15 +123,16 @@
 </template>
 
 <script>
-import { 
-    getDicts 
+import {
+    getDicts
 } from '@/api/system/menu';
-import { 
+import {
     queryById,
-    saveOrUpdate, 
+    saveOrUpdate,
     getDictListByType,
     getWecomGroupList,
-    getWecomEmployeeList, 
+    getWecomEmployeeList,
+    getWecomGroupQrcode
 } from '@/api/activity/index';
 import moment from 'moment';
 import CompSign from './CompSign.vue';
@@ -154,7 +155,7 @@ export default {
             isUpdate: false,
             formModel: {
                 id: '',
-                timeRange: [], 
+                timeRange: [],
                 newUserRule: '1',
                 payoutMethod: '1',
                 timingDistribution: '1',
@@ -288,7 +289,7 @@ export default {
             this.resetForm();
             this.visible = true;
             // 加载详情
-            queryById({ id: record.id }).then(res => {
+            queryById({ id: record.id }).then(async res => {
                 if (res.code === 200) {
                     this.formModel = res.data;
                     // 时间
@@ -322,6 +323,14 @@ export default {
                             return nd;
                         });
                     }
+                    // 企微群二维码
+                    if (res.data.wecomGroupId) {
+                        try {
+                            await this.getWecomGroupQrcodeById(res.data.wecomGroupId);
+                        } catch (error) {
+                            console.error('获取二维码失败:', error);
+                        }
+                    }
                 }
             });
         },
@@ -341,6 +350,45 @@ export default {
                 this.formModel.merchantName = selectedOption.name;
             }
         },
+        // 关联企微群选择事件
+        async onWecomGroupChange() {
+            // 根据企微群ID,生成二维码
+            if (this.formModel.wecomGroupId) {
+                try {
+                    await this.getWecomGroupQrcodeById(this.formModel.wecomGroupId);
+                } catch (error) {
+                    console.error('获取二维码失败:', error);
+                }
+            }
+        },
+        // 获取企微群二维码
+        async getWecomGroupQrcodeById(chatId) {
+            if (!chatId) {
+                console.error('缺少chatId参数');
+                throw new Error('缺少chatId参数');
+            }
+
+            try {
+                const res = await getWecomGroupQrcode({
+                    chatId: chatId,
+                }, {
+                    responseType: 'blob' // 设置响应类型为blob
+                });
+
+                if (res) {
+                    // 将二进制流转换为Data URL
+                    const blob = new Blob([res], { type: 'image/png' });
+                    const imageUrl = URL.createObjectURL(blob);
+                    this.$set(this.formModel, 'wecomGroupQrcode', imageUrl); // 关键:赋值给formModel
+                    return imageUrl;
+                }
+                return null;
+            } catch (error) {
+                console.error('获取二维码失败:', error);
+                this.$message.error('获取二维码失败');
+                throw error;
+            }
+        },
         handleTierChange(deletedIndex) {
             this.$nextTick(() => {
                 this.$refs.form.validateField('inviteTiers');
@@ -453,4 +501,4 @@ export default {
     right: 0;
     z-index: 99;
 }
-</style>
+</style>

+ 117 - 40
src/views/weGroupFission/modules/share.vue

@@ -37,12 +37,14 @@
 </template>
 
 <script>
-import QRCode from 'qrcodejs2';
+// import QRCode from 'qrcodejs2';
 import html2canvas from 'html2canvas';
 import CompPreview from './CompPreview.vue';
-import { 
+import {
     queryById,
-    getWechatGroupFissionUrl
+    getWechatGroupFissionUrl,
+    getMiniProgramQrCode,
+    getWecomGroupQrcode
 } from '@/api/activity/index';
 export default {
     name: '',
@@ -78,7 +80,7 @@ export default {
         // 初始数据
         getData(record) {
             // 加载详情
-            queryById({ id: record.id }).then(res => {
+            queryById({ id: record.id }).then(async res => {
                 if (res.code === 200) {
                     this.formData = res.data;
                     // 时间
@@ -112,55 +114,130 @@ export default {
                             return nd;
                         });
                     }
-                    
-                    this.$refs.targetDom.getQRCode(this.wechatPath);
+
+                    // 加载企微群二维码
+                    // this.$refs.targetDom.getQRCode(this.wechatPath);
+                    if (res.data.wecomGroupId) {
+                        try {
+                            await this.getWecomGroupQrcodeById(res.data.wecomGroupId);
+                        } catch (error) {
+                            console.error('获取二维码失败:', error);
+                        }
+                    }
                 }
             });
         },
+        // 获取企微群二维码
+        async getWecomGroupQrcodeById(chatId) {
+            if (!chatId) {
+                console.error('缺少chatId参数');
+                throw new Error('缺少chatId参数');
+            }
+
+            try {
+                const res = await getWecomGroupQrcode({
+                    chatId: chatId,
+                }, {
+                    responseType: 'blob' // 设置响应类型为blob
+                });
+
+                if (res) {
+                    // 将二进制流转换为Data URL
+                    const blob = new Blob([res], { type: 'image/png' });
+                    const imageUrl = URL.createObjectURL(blob);
+                    this.$set(this.formData, 'wecomGroupQrcode', imageUrl); // 关键:赋值给formData
+                    return imageUrl;
+                }
+                return null;
+            } catch (error) {
+                console.error('获取二维码失败:', error);
+                this.$message.error('获取二维码失败');
+                throw error;
+            }
+        },
         // 初始化二维码
         async getQRCode(record) {
             await getWechatGroupFissionUrl({
-                url: 'packageF/pages/activity/weGroupFission/poster',
-                version: 'release',
+                // url: 'packageF/pages/activity/weGroupFission/poster',
+                url: 'pages/home/home',
+                version: 'trial', // release 正式版,trial 体验版
                 groupFissionId: record.id,
             }).then(res => {
                 if (res.code === 200) {
                     this.wechatPath = res.data;
                 }
             });
-            this.qrcode = new QRCode('share-qrcode', {
-                text: this.wechatPath, 
-                width: 200, 
-                height: 200, 
-                colorDark: '#000000', // 二维码前景色
-                colorLight: '#ffffff', // 二维码背景色
-                correctLevel: QRCode.CorrectLevel.H // 容错级别:L/M/Q/H(H最高)
-            });
+            // this.qrcode = new QRCode('share-qrcode', {
+            //     text: this.wechatPath,
+            //     width: 200,
+            //     height: 200,
+            //     colorDark: '#000000', // 二维码前景色
+            //     colorLight: '#ffffff', // 二维码背景色
+            //     correctLevel: QRCode.CorrectLevel.H // 容错级别:L/M/Q/H(H最高)
+            // });
         },
         // 下载功能
         async onDownload(type) {
             if (type === 'miniCode') {
-                const qrImg = document.querySelector('#share-qrcode img') || document.querySelector('#share-qrcode canvas');
-                if (!qrImg) {
-                    this.$message.error('二维码生成失败!');
-                    return;
-                }
+                try {
+                    // 获取当前活动ID
+                    const groupFissionId = this.formData.id;
+                    if (!groupFissionId) {
+                        this.$message.error('缺少活动ID!');
+                        return;
+                    }
 
-                // 创建下载链接
-                const a = document.createElement('a');
-                a.download = '小程序码-' + new Date().getTime() + '.png'; // 下载文件名
+                    // 生成二维码的二进制流
+                    const blob = await getMiniProgramQrCode({
+                        // url: 'packageF/pages/activity/weGroupFission/poster',
+                        url: 'pages/home/home',
+                        version: 'trial', // release 正式版,trial 体验版
+                        groupFissionId: groupFissionId,
+                    }, {
+                        responseType: 'blob' // 设置响应类型为blob
+                    });
 
-                // 处理 Canvas 或 Img 转 DataURL
-                if (qrImg.tagName === 'CANVAS') {
-                    a.href = qrImg.toDataURL('image/png');
-                } else {
-                    a.href = qrImg.src;
+                    if (blob) {
+                        // 创建下载链接
+                        const url = URL.createObjectURL(blob);
+                        const a = document.createElement('a');
+                        a.href = url;
+                        a.download = '小程序码-' + new Date().getTime() + '.png'; // 下载文件名
+
+                        // 触发下载
+                        document.body.appendChild(a);
+                        a.click();
+
+                        // 清理资源
+                        document.body.removeChild(a);
+                        URL.revokeObjectURL(url);
+                    } else {
+                        this.$message.error('二维码生成失败!');
+                    }
+                } catch (error) {
+                    console.error('下载小程序码失败:', error);
                 }
+                // const qrImg = document.querySelector('#share-qrcode img') || document.querySelector('#share-qrcode canvas');
+                // if (!qrImg) {
+                //     this.$message.error('二维码生成失败!');
+                //     return;
+                // }
 
-                // 触发下载
-                document.body.appendChild(a);
-                a.click();
-                document.body.removeChild(a);
+                // // 创建下载链接
+                // const a = document.createElement('a');
+                // a.download = '小程序码-' + new Date().getTime() + '.png'; // 下载文件名
+
+                // // 处理 Canvas 或 Img 转 DataURL
+                // if (qrImg.tagName === 'CANVAS') {
+                //     a.href = qrImg.toDataURL('image/png');
+                // } else {
+                //     a.href = qrImg.src;
+                // }
+
+                // // 触发下载
+                // document.body.appendChild(a);
+                // a.click();
+                // document.body.removeChild(a);
             } else {
                 try {
                     // 1. 获取目标 DOM 元素
@@ -225,14 +302,14 @@ export default {
 .share-content {
     .share-card {
         padding: 20px;
-        background: #f8faff; 
+        background: #f8faff;
         border-radius: 12px;
-        border: 1px solid #eff4f9; 
+        border: 1px solid #eff4f9;
         transition: all 0.3s;
 
         &:hover {
             border-color: #d9e4ff;
-            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); 
+            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
         }
 
         .card-header {
@@ -251,12 +328,12 @@ export default {
                 font-size: 16px;
 
                 &.wechat-icon {
-                    background: #e7f8eb; 
+                    background: #e7f8eb;
                     color: #07c160;
                 }
 
                 &.h5-icon {
-                    background: #e6f7ff; 
+                    background: #e6f7ff;
                     color: #1890ff;
                 }
             }
@@ -276,7 +353,7 @@ export default {
                     font-size: 22px;
                     cursor: pointer;
                     transition: all 0.2s;
-                    color: #1890ff; 
+                    color: #1890ff;
                     padding: 4px;
                     border-radius: 4px;
 
@@ -304,4 +381,4 @@ export default {
     position: fixed;
     top: -2000px;
 }
-</style>
+</style>