Commit c0e9da66 by yuzhenWang

做到了生成图片

parent a428b359
<template>
<view class="generate-image-container">
<!-- 插槽用于放置需要生成图片的内容 -->
<view class="content-container" ref="captureElement" v-if="!generatedImage">
<slot></slot>
</view>
<!-- 生成的图片预览 -->
<view class="preview-container" v-if="generatedImage && showPreview">
<image :src="generatedImage" mode="widthFix" class="preview-image"></image>
</view>
</view>
</template>
<script>
import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage';
export default {
name: 'GenerateImage',
props: {
// 是否显示预览
showPreview: {
type: Boolean,
default: true
},
// 二维码内容(如果不需要二维码可不传)
qrCodeContent: {
type: String,
default: ''
},
// 二维码大小
qrCodeSize: {
type: Number,
default: 110
},
// 二维码容器样式
qrCodeContainerStyle: {
type: Object,
default: () => ({
position: 'absolute',
bottom: '10rpx',
right: '10rpx',
background: '#fff',
padding: '10rpx',
borderRadius: '10rpx',
boxShadow: '0 0 10rpx rgba(0,0,0,0.1)'
})
},
// 存储的key,用于缓存
storageKey: {
type: String,
default: 'savedGeneratedImage'
},
// 最大重试次数
maxRetryCount: {
type: Number,
default: 3
},
// 是否启用缓存
enableCache: {
type: Boolean,
default: true
},
// 图片质量(0-1)
quality: {
type: Number,
default: 0.7
}
},
data() {
return {
generatedImage: '', // 生成的图片
isContentReady: false, // 内容是否准备就绪
retryCount: 0 // 重试次数
}
},
mounted() {
this.init();
},
methods: {
init() {
// 检查是否有缓存的图片
if (this.enableCache) {
const cachedImage = uni.getStorageSync(this.storageKey);
if (cachedImage) {
this.generatedImage = cachedImage;
this.$emit('success', cachedImage);
return;
}
}
// 重置状态
this.isContentReady = false;
this.retryCount = 0;
// 模拟内容加载完成
this.handleContentReady();
},
// 内容准备就绪
handleContentReady() {
this.isContentReady = true;
this.generateImage();
},
// 生成图片
async generateImage() {
try {
this.$emit('start');
// 如果有二维码内容,先生成二维码
if (this.qrCodeContent) {
await this.makeQrcode();
await new Promise(resolve => setTimeout(resolve, 500));
}
// 执行截图
await this.captureImage();
this.$emit('success', this.generatedImage);
} catch (error) {
console.error('生成图片失败:', error);
this.$emit('error', error);
this.retryGenerate();
}
},
// 重试机制
retryGenerate() {
if (this.retryCount < this.maxRetryCount) {
this.retryCount++;
const delay = 1000 * this.retryCount;
setTimeout(() => {
this.generateImage();
}, delay);
} else {
this.$emit('fail', '生成图片失败,请稍后再试');
}
},
// 生成二维码
makeQrcode() {
return new Promise((resolve, reject) => {
if (!this.qrCodeContent) {
resolve();
return;
}
// 创建实例
const qr = new UQRCode();
// 设置二维码内容
qr.data = this.qrCodeContent;
qr.size = this.qrCodeSize;
qr.foregroundColor = '#000000';
qr.backgroundColor = '#FFFFFF';
qr.margin = 10;
qr.errorCorrectLevel = UQRCode.errorCorrectLevel.H;
try {
// 调用制作二维码方法
qr.make();
// 获取canvas上下文
const ctx = uni.createCanvasContext('qrcode', this);
// 清空画布
ctx.clearRect(0, 0, this.qrCodeSize, this.qrCodeSize);
// 将二维码绘制到canvas上
qr.canvasContext = ctx;
qr.drawCanvas();
// 绘制完成
ctx.draw(true, () => {
resolve();
});
} catch (err) {
reject(err);
}
});
},
// 截图方法
async captureImage() {
try {
// 获取DOM元素
const element = this.$refs.captureElement.$el;
// 调用工具函数生成图片
const imageData = await elementToImage(element);
// 压缩图片
const compressedImage = await this.compressImage(imageData);
this.generatedImage = compressedImage;
// 缓存图片
if (this.enableCache) {
uni.setStorageSync(this.storageKey, compressedImage);
}
} catch (error) {
throw error;
}
},
// 压缩图片
compressImage(base64) {
return new Promise((resolve) => {
const img = new Image();
img.src = base64;
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 设置压缩后的宽高
const maxWidth = 800;
const maxHeight = 1200;
let width = img.width;
let height = img.height;
if (width > maxWidth) {
height *= maxWidth / width;
width = maxWidth;
}
if (height > maxHeight) {
width *= maxHeight / height;
height = maxHeight;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
// 降低质量
resolve(canvas.toDataURL('image/jpeg', this.quality));
};
});
},
// 保存图片到相册
saveImage() {
if (!this.generatedImage) {
this.$emit('error', '没有可保存的图片');
return;
}
if (uni.downloadFile) {
uni.downloadFile({
url: this.generatedImage,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
this.$emit('save-success');
},
fail: (err) => {
this.$emit('save-error', err);
}
});
}
},
fail: (err) => {
this.$emit('save-error', err);
}
});
} else {
// H5环境下的处理方式
const link = document.createElement('a');
link.href = this.generatedImage;
link.download = 'generated-image.png';
link.click();
this.$emit('save-success');
}
},
// 重新生成图片
regenerate() {
if (this.enableCache) {
uni.removeStorageSync(this.storageKey);
}
this.generatedImage = '';
this.init();
},
// 获取生成的图片
getGeneratedImage() {
return this.generatedImage;
}
}
}
</script>
<style lang="scss" scoped>
.generate-image-container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
position: relative;
.dropdown-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 100;
}
.content-container {
width: 100%;
height: auto;
position: fixed;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
border-radius: 16rpx 16rpx 0 0;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
z-index: 110;
transform: translateY(100%);
transition: transform 0.3s ease;
}
.preview-container {
flex: 1;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
.preview-image {
height: 100%;
width: auto;
object-fit: contain;
}
}
}
</style>
\ No newline at end of file
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
import * as environment from "@/environments/environment"; import * as environment from "@/environments/environment";
import UQRCode from 'uqrcodejs'; import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage'; import { elementToImage } from '@/util/htmlToImage';
import registerBg from '@/static/registerBg.png'
import { initJssdkShare, setWechatShare } from '@/util/fiveshare'; import { initJssdkShare, setWechatShare } from '@/util/fiveshare';
export default { export default {
...@@ -133,11 +133,7 @@ export default { ...@@ -133,11 +133,7 @@ export default {
const delay = 1000 * this.retryCount; const delay = 1000 * this.retryCount;
console.log(`第${this.retryCount}次重试,${delay}ms后重试...`); console.log(`第${this.retryCount}次重试,${delay}ms后重试...`);
// uni.showToast({
// title: `生成中,请稍候...(${this.retryCount}/${this.maxRetryCount})`,
// icon: 'none',
// duration: delay
// });
setTimeout(() => { setTimeout(() => {
this.generateQrcodeAndCapture(); this.generateQrcodeAndCapture();
......
...@@ -26,12 +26,61 @@ ...@@ -26,12 +26,61 @@
</view> </view>
</view> </view>
</view> </view>
<!-- v-if="!generatedImage" -->
<view class="generateImageBox" ref="captureElement" >
<view class="imgBox">
<image
id="posterImg"
style="display: block;"
:src="shareItem.displayImage"
mode="widthFix"
@load="handleBgImageLoad"
@error="handleBgImageError"
crossOrigin="anonymous"
></image>
<view class="descriptionTxt">
{{shareItem.fileSynopsis}}
</view>
</view>
<view class="productNum">
{{shareItem.coursePrice}}
</view>
<view class="generateImageBottom">
<view class="left">
<view class="top">
<view style="width: 100rpx;">
<image
:src="companyLogo"
mode="widthFix"
></image>
</view>
<text class="companyName">分销系统</text>
</view>
<view class="bottom">
识别二维码查看商品
</view>
</view>
<!-- 二维码容器 -->
<view class="qrcode-container">
<canvas
canvas-id="qrcode"
class="qrcode-canvas"
:style="{width: qrCodeSize + 'px', height: qrCodeSize + 'px'}"
></canvas>
</view>
</view>
</view>
<!-- 添加生成的图片预览 -->
<view class="preview-container" v-if="generatedImage">
<image :src="generatedImage" mode="widthFix" class="preview-image"></image>
</view>
<view class="productBox"> <view class="productBox">
<view class="productList" :style="{marginTop}"> <view class="productList" :style="{marginTop}">
<view class="tabBox"> <view class="tabBox">
<!-- @click="courseClassify=4;courseList()" -->
<view :class="{'actived': courseClassify==4}" @click="transform('consult')"><text>咨询产品</text></view> <view :class="{'actived': courseClassify==4}" @click="transform('consult')"><text>咨询产品</text></view>
<!-- @click="courseClassify=3;courseList()" -->
<view :class="{'actived': courseClassify==3}" @click="transform('plan')"><text>规划产品</text></view> <view :class="{'actived': courseClassify==3}" @click="transform('plan')"><text>规划产品</text></view>
</view> </view>
<view class="productItem" v-for="item in localCourseInfos" :key="item.fileId" > <view class="productItem" v-for="item in localCourseInfos" :key="item.fileId" >
...@@ -110,7 +159,6 @@ ...@@ -110,7 +159,6 @@
</template> </template>
<script> <script>
import BootPage from "@/components/bootpage/bootpage.vue"; import BootPage from "@/components/bootpage/bootpage.vue";
import PartnerTipPopup from "@/components/commonPopup/PartnerTipPopup.vue"; import PartnerTipPopup from "@/components/commonPopup/PartnerTipPopup.vue";
import api from "../../api/api"; import api from "../../api/api";
...@@ -124,6 +172,9 @@ ...@@ -124,6 +172,9 @@
import UniShareWx from "@/uni_modules/uni-share-wx/index.vue"; import UniShareWx from "@/uni_modules/uni-share-wx/index.vue";
import {nanoid} from 'nanoid'; import {nanoid} from 'nanoid';
import restrictedTip from '@/components/commonPopup/restrictedTip.vue'; import restrictedTip from '@/components/commonPopup/restrictedTip.vue';
import GenerateImage from '@/components/commonPopup/generateImage.vue';
import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage';
export default{ export default{
name:'courselist', name:'courselist',
props:{ props:{
...@@ -144,7 +195,8 @@ ...@@ -144,7 +195,8 @@
UniShareWx, UniShareWx,
BootPage, BootPage,
PartnerTipPopup, PartnerTipPopup,
restrictedTip restrictedTip,
GenerateImage
}, },
watch: { watch: {
// 监听 prop 变化,更新本地副本 // 监听 prop 变化,更新本地副本
...@@ -167,9 +219,17 @@ ...@@ -167,9 +219,17 @@
shareTipsFlag:false, shareTipsFlag:false,
sourceType:'1',//根据来源展示二维码 默认是cffp, sourceType:'1',//根据来源展示二维码 默认是cffp,
env:dataHandling.getRuntimeEnv2(), env:dataHandling.getRuntimeEnv2(),
shareItem:{},//分享的产品 shareItem:{displayImage:""},//分享的产品
sharelogin: false, sharelogin: false,
courseClassify:4, courseClassify:4,
posterImg:'https://yindun-images.oss-cn-shanghai-finance-1-pub.aliyuncs.com/ydMall/product/serviceContent-zx_jqsw1-1.png',
// posterImg:'https://yindun-images.oss-cn-shanghai-finance-1-pub.aliyuncs.com/ydMall/product/serviceContent-zx_tjzj1-2.png',
// posterImg:'https://dev-yindun-store.oss-cn-shanghai-finance-1-pub.aliyuncs.com/22/1/pbg.jpg',
qrCodeUrl: 'https://example.com',//二维码的链接地址
qrCodeSize: 100,//二维码的尺寸
showGenerateImg:false ,//是否要生成海报图片,
companyLogo : '../../static/logo2.png',
generatedImage:''
} }
}, },
...@@ -177,6 +237,12 @@ ...@@ -177,6 +237,12 @@
onLoad() { onLoad() {
this.queryName = uni.getStorageSync('queryName') || ''; this.queryName = uni.getStorageSync('queryName') || '';
this.sourceType = uni.getStorageSync('addSystemType') || '1'; this.sourceType = uni.getStorageSync('addSystemType') || '1';
if(companyInfo.companyType == '1'){
companyInfo.companyLogo='../../static/myteam/Group1633.png';
}else if(this.companyType == '2'){
companyInfo.companyLogo='../../static/logo2.png';
}
}, },
onShow() { onShow() {
this.queryName = uni.getStorageSync('queryName') || ''; this.queryName = uni.getStorageSync('queryName') || '';
...@@ -191,6 +257,7 @@ ...@@ -191,6 +257,7 @@
setWechatShare(); setWechatShare();
}, window.location.href); }, window.location.href);
// #endif // #endif
}, },
created(){ created(){
this.queryName = uni.getStorageSync('queryName') || ''; this.queryName = uni.getStorageSync('queryName') || '';
...@@ -240,6 +307,10 @@ ...@@ -240,6 +307,10 @@
this.userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo')) this.userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo'))
} }
this.shareItem = JSON.parse(JSON.stringify(item)) this.shareItem = JSON.parse(JSON.stringify(item))
// this.shareItem.displayImage = 'https://yindun-images.oss-cn-shanghai-finance-1-pub.aliyuncs.com/ydMall/product/serviceProcess-zx_zezj1-1.png'
console.log('this.shareItem',this.shareItem);
// return
// 未登录去登录 // 未登录去登录
if(uni.getStorageSync('loginType')!=='codelogin'){ if(uni.getStorageSync('loginType')!=='codelogin'){
dataHandling.pocessTracking( dataHandling.pocessTracking(
...@@ -253,18 +324,7 @@ ...@@ -253,18 +324,7 @@
this.sharelogin = true this.sharelogin = true
return return
} }
if(this.runEnv == 'browser'){
dataHandling.pocessTracking(
'点击',
`用户在产品中心浏览器端点击产品分享按钮`,
'点击',
2,
'产品中心',
'pages/courselist/courselist'
)
this.$refs.popup.open()
return
}
// 已登录,未成为合伙人 // 已登录,未成为合伙人
if(this.userInfo&&!this.userInfo['partnerType']) { if(this.userInfo&&!this.userInfo['partnerType']) {
dataHandling.pocessTracking( dataHandling.pocessTracking(
...@@ -278,12 +338,39 @@ ...@@ -278,12 +338,39 @@
this.$refs.partnerTipPopup.open() this.$refs.partnerTipPopup.open()
return return
} }
// 正常逻辑先注释掉
// if(this.runEnv == 'browser'){
// dataHandling.pocessTracking(
// '点击',
// `用户在产品中心浏览器端点击产品分享按钮`,
// '点击',
// 2,
// '产品中心',
// 'pages/courselist/courselist'
// )
// this.$refs.popup.open()
// return
// }
this.continueShare() this.continueShare()
}, },
continueShare(){ continueShare(){
this.userId = uni.getStorageSync('cffp_userId') this.userId = uni.getStorageSync('cffp_userId')
const shareCode = nanoid() + this.userId const shareCode = nanoid() + this.userId
const jumptime = Date.parse(new Date()) / 1000 const jumptime = Date.parse(new Date()) / 1000
uni.setStorageSync('mpCffp','1')
if(uni.getStorageSync('mpCffp')){
let newLink = shareURL + "/pages/courseDetail/courseDetail?fileId=" + this.shareItem.fileId +
'&coursesharing=1' + '&serialsNo=' + nanoid() + '&shareCode=' + shareCode + '&shareUserId=' +
this.userId + '&jumpUrl=' + jumptime+ "&"//分享链接
this.posterImg = this.shareItem.displayImage
this.qrCodeUrl = newLink
// this.shareItem.displayImage="https://ajb-images.oss-cn-shanghai-finance-1-pub.aliyuncs.com/images/mk-material/133.jpg"
// this.showGenerateImg = true
console.log('this.posterImg',this.posterImg);
console.log('this.qrCodeUrl',this.qrCodeUrl);
return
}
//app分享 //app分享
// #ifdef APP-PLUS // #ifdef APP-PLUS
let dataWXform = { let dataWXform = {
...@@ -432,7 +519,7 @@ ...@@ -432,7 +519,7 @@
url: `/pages/courseDetail/courseDetail?fileId=${item.fileId}` url: `/pages/courseDetail/courseDetail?fileId=${item.fileId}`
}); });
}, },
courseList(){ courseList(){
const param = { const param = {
queryName:this.queryName, queryName:this.queryName,
courseClassify:this.courseClassify courseClassify:this.courseClassify
...@@ -440,8 +527,11 @@ ...@@ -440,8 +527,11 @@
api.courseList(param).then(res=>{ api.courseList(param).then(res=>{
if(res['success']){ if(res['success']){
this.localCourseInfos = res['data']['data']; // 修改本地副本 this.localCourseInfos = res['data']['data']; // 修改本地副本
} }
}) })
}, },
queryAreaCenterInfo() { queryAreaCenterInfo() {
...@@ -451,17 +541,185 @@ ...@@ -451,17 +541,185 @@
}).then((res) => { }).then((res) => {
if (res['success']) { if (res['success']) {
uni.setStorageSync('fileUploadItemCFFPList', res['data']['fileUploadItemCFFPList']) uni.setStorageSync('fileUploadItemCFFPList', res['data']['fileUploadItemCFFPList'])
// const cffp_userInfo = {
// name: res['data']['userReName'],
// mobile: res['data']['mobile'],
// partnerType:res['data']['partnerType'],
// levelCode:res['data']['levelCode'],
// }
// uni.setStorageSync('cffp_userInfo', JSON.stringify(cffp_userInfo));
this.fileUploadItemCFFPList = uni.getStorageSync('fileUploadItemCFFPList'); this.fileUploadItemCFFPList = uni.getStorageSync('fileUploadItemCFFPList');
} }
}) })
}, },
// 背景图片加载成功
handleBgImageLoad() {
this.generateQrcodeAndCapture();
},
// 背景图片加载失败
handleBgImageError() {
console.error('产品图片加载完成');
// 即使失败也继续流程,可能会有默认背景
// this.generateQrcodeAndCapture();
},
// 顺序执行:生成二维码 -> 截图
async generateQrcodeAndCapture() {
try {
uni.showLoading({
title: '准备生成分享图...'
});
// 1. 先生成二维码
console.log('开始生成二维码...');
await this.makeQrcode();
console.log('二维码生成完成');
// 2. 等待500ms确保渲染完成
await new Promise(resolve => setTimeout(resolve, 1000));
// 3. 执行截图
console.log('开始截图...');
await this.captureImage();
console.log('截图完成');
uni.hideLoading();
} catch (error) {
console.error('生成分享图失败:', error);
uni.hideLoading();
// this.retryGenerate();
}
},
// 重试机制
// retryGenerate() {
// if (this.retryCount < this.maxRetryCount) {
// this.retryCount++;
// const delay = 1000 * this.retryCount;
// console.log(`第${this.retryCount}次重试,${delay}ms后重试...`);
// setTimeout(() => {
// this.generateQrcodeAndCapture();
// }, delay);
// } else {
// // uni.showToast({
// // title: '生成分享图失败,请稍后再试',
// // icon: 'none'
// // });
// }
// },
// 生成二维码
makeQrcode() {
return new Promise((resolve, reject) => {
// 创建实例
const qr = new UQRCode();
// 设置二维码内容
qr.data = this.qrCodeUrl;
// 设置二维码大小
qr.size = this.qrCodeSize;
// 设置前景色(二维码颜色)
qr.foregroundColor = '#000000';
// 设置背景色
qr.backgroundColor = '#FFFFFF';
// 设置边距
qr.margin = 10;
// 设置纠错等级
qr.errorCorrectLevel = UQRCode.errorCorrectLevel.H;
try {
// 调用制作二维码方法
qr.make();
// 获取canvas上下文
const ctx = uni.createCanvasContext('qrcode', this);
// 清空画布
ctx.clearRect(0, 0, this.qrCodeSize, this.qrCodeSize);
// 将二维码绘制到canvas上
qr.canvasContext = ctx;
qr.drawCanvas();
// 绘制完成
ctx.draw(true, () => {
console.log('二维码绘制完成');
resolve();
});
} catch (err) {
reject(err);
}
});
},
// 截图方法
async captureImage() {
try {
uni.showLoading({
title: '正在生成图片...'
});
// 获取DOM元素(在H5环境下)
const element = this.$refs.captureElement.$el;
// 调用工具函数生成图片
const imageData = await elementToImage(element);
this.generatedImage=imageData
// console.log('this.generatedImage',this.generatedImage);
// 压缩图片
// const compressedImage = await this.compressImage(imageData);
// this.generatedImage = compressedImage;
} catch (error) {
console.error('截图失败:', error);
throw error; // 抛出错误以便外部捕获
} finally {
uni.hideLoading();
}
},
compressImage(base64) {
return new Promise((resolve) => {
const img = new Image();
img.src = base64;
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 设置压缩后的宽高
const maxWidth = 800;
const maxHeight = 1200;
let width = img.width;
let height = img.height;
if (width > maxWidth) {
height *= maxWidth / width;
width = maxWidth;
}
if (height > maxHeight) {
width *= maxHeight / height;
height = maxHeight;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
// 降低质量
resolve(canvas.toDataURL('image/jpeg', 0.7));
};
});
},
// 获取无缓存URL
getCacheFreeUrl(url) {
if (!url) return '';
// 添加时间戳参数防止缓存
return url + (url.includes('?') ? '&' : '?') + '_t=' + Date.now();
},
}, },
mounted() { mounted() {
this.fileUploadItemCFFPList = uni.getStorageSync('fileUploadItemCFFPList'); this.fileUploadItemCFFPList = uni.getStorageSync('fileUploadItemCFFPList');
...@@ -477,18 +735,95 @@ ...@@ -477,18 +735,95 @@
onHide() { onHide() {
this.queryName = '' this.queryName = ''
uni.removeStorageSync('queryName') uni.removeStorageSync('queryName')
} },
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container{ .container{
position: relative;
background-color: rgba(235, 239, 247, 1); background-color: rgba(235, 239, 247, 1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
height: auto; height: auto;
box-sizing: border-box; box-sizing: border-box;
.generateImageBox{
position: absolute;
bottom: 0;
right: -100%;
z-index: -1;
border-radius: 20rpx;
width: 100%;
box-sizing: border-box;
background-color: #fff;
padding: 20rpx;
.imgBox{
box-sizing: border-box;
width: 100%;
image{
width: 100%;
}
.descriptionTxt{
font-size: 28rpx;
}
}
.productNum{
font-size: 30rpx;
font-weight: 500;
margin: 20rpx 0;
color: rgba(255, 74, 50, 1);
}
.generateImageBottom{
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left{
width: 50%;
.top{
width: 100%;
display: flex;
align-items: center;
image{
width: 100%;
}
.companyName{
color: #333;
font-size: 28rpx;
}
}
.bottom{
font-size: 26rpx;
color: #999;
margin-top: 10rpx;
}
}
.qrcode-container {
background: #fff;
padding: 10rpx;
border-radius: 10rpx;
box-shadow: 0 0 10rpx rgba(0,0,0,0.1);
.qrcode-canvas {
display: block;
}
}
}
}
.preview-container{
width: 100%;
box-sizing: border-box;
padding: 20rpx;
background-color: pink;
margin-bottom: 100rpx;
.preview-image{
width: 100%;
}
}
.tabBox{ .tabBox{
display: flex; display: flex;
align-items: center; align-items: center;
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
></join-popup> ></join-popup>
<!-- <tabBar :currentPage="currentPage"></tabBar> --> <!-- <tabBar :currentPage="currentPage"></tabBar> -->
</view> </view>
<uni-popup ref="popup" type="top" background-color="#fff"> <uni-popup ref="popup" type="top" background-color="#fff">
<view class="descriptionBox"> <view class="descriptionBox">
...@@ -259,7 +260,7 @@ ...@@ -259,7 +260,7 @@
loginType : uni.getStorageSync('loginType'), loginType : uni.getStorageSync('loginType'),
userInfo:{} ,//用户信息, userInfo:{} ,//用户信息,
productItem:{}, productItem:{},
dataToken:'' dataToken:'',
} }
}, },
components: { components: {
...@@ -270,7 +271,7 @@ ...@@ -270,7 +271,7 @@
courseItem, courseItem,
JoinPopup, JoinPopup,
PartnerTipPopup, PartnerTipPopup,
restrictedTip restrictedTip,
}, },
onShow() { onShow() {
...@@ -291,10 +292,7 @@ ...@@ -291,10 +292,7 @@
}, },
onLoad(options) { onLoad(options) {
console.log('options',options);
// if(options.dataToken){
// this.dataToken = options.dataToken
// }
if(uni.getStorageSync('dataToken')){ if(uni.getStorageSync('dataToken')){
this.dataToken = uni.getStorageSync('dataToken') this.dataToken = uni.getStorageSync('dataToken')
} }
...@@ -453,7 +451,6 @@ ...@@ -453,7 +451,6 @@
this.reLogin() this.reLogin()
return return
} }
console.log('1111');
let loginType = uni.getStorageSync('loginType') let loginType = uni.getStorageSync('loginType')
if(loginType == 'codelogin'){ if(loginType == 'codelogin'){
this.querySystemMessage() this.querySystemMessage()
......
...@@ -8,35 +8,7 @@ let userInfo = {name:''} ...@@ -8,35 +8,7 @@ let userInfo = {name:''}
if(uni.getStorageSync('cffp_userInfo')){ if(uni.getStorageSync('cffp_userInfo')){
userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo')) userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo'))
} }
//初始化
// export function initJssdkShare(callback, url) {
// console.log('签名',url);
// var url = url
// //这一步需要调用后台接口,返回需要的签名 签名时间戳 随机串 和公众号appid
// //注意url:window.location.href.split('#')[0] //
// // request.post("", {
// // url // url是当前页面的url
// // },
// let WxConfigRequestVO = {
// url:url,
// systemType:uni.getStorageSync('addSystemType')?uni.getStorageSync('addSystemType'):'1'
// }
// // @ts-ignore
// api.Wxshare(WxConfigRequestVO).then(res => {
// jWeixin.config({
// debug: false,//调试的时候需要 在app上回弹出errmg:config ok 的时候就证明没问题了 这时候就可以改为false
// appId: res.data.appId,//appid
// timestamp: res.data.timestamp,//时间戳
// nonceStr: res.data.nonceStr,//随机串
// signature: res.data.signature,//签名
// jsApiList: res.data.jsApiList//必填 是下面需要用到的方法集合
// })
// if(callback){
// callback()
// }
// })
// }
// 初始化SDK // 初始化SDK
export function initJssdkShare(callback, url) { export function initJssdkShare(callback, url) {
const WxConfigRequestVO = { const WxConfigRequestVO = {
......
import html2canvas from 'html2canvas'; import html2canvas from 'html2canvas';
import {baseURL,apiURL,cffpURL,sfpUrl,imgUrl,scrmUrl} from "../environments/environment";
/** /**
* 将DOM元素转换为图片 * 将DOM元素转换为图片
...@@ -13,14 +14,40 @@ export const elementToImage = async (element, options = {}) => { ...@@ -13,14 +14,40 @@ export const elementToImage = async (element, options = {}) => {
backgroundColor: null, // 透明背景 backgroundColor: null, // 透明背景
scale: 2, // 提高缩放以获得更清晰的图片 scale: 2, // 提高缩放以获得更清晰的图片
useCORS: true, // 允许跨域图片 useCORS: true, // 允许跨域图片
allowTaint: true, // 允许污染图片 allowTaint: false, // 允许污染图片
logging: false // 关闭日志 logging: false, // 关闭日志,
delay: 10000
}; };
const canvas = await html2canvas(element, { ...defaultOptions, ...options }); const canvas = await html2canvas(element, { ...defaultOptions, ...options });
return canvas.toDataURL('image/png'); return canvas.toDataURL('image/png');
} catch (error) { } catch (error) {
console.error('生成图片失败:', error); console.error('生成图片失败:', error);
throw error; throw error;
} }
}; };
\ No newline at end of file export function convertImageToBase64Frontend (url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous'; // 处理跨域问题
img.src = url;
console.log('img',img);
img.onload = () =>{
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.height = img.naturalHeight;
canvas.width = img.naturalWidth;
ctx.drawImage(img, 0, 0);
try {
const dataURL = canvas.toDataURL('image/png');
resolve(dataURL);
} catch (e) {
reject(e);
}
};
img.onerror = function() {
reject(new Error('图片加载失败'));
};
});
}
\ No newline at end of file
import {apiURL,cffpURL,sfpUrl} from "../environments/environment"; // import {apiURL,cffpURL,sfpUrl} from "../environments/environment";
import api from "@/api/api"; // import api from "@/api/api";
// 白名单,不需要携带token就允许被访问的接口
const whiteApiList = [`${apiURL}/authorize/obtainToken`, // // 白名单,不需要携带token就允许被访问的接口
`${apiURL}/authorize/checkToken`, // const whiteApiList = [
`${cffpURL}/user/loginVerification`, // `${apiURL}/authorize/obtainToken`,
`${apiURL}/appVersion/checkIsUpdate`, // `${apiURL}/authorize/checkToken`,
`${cffpURL}/accessLog/accessLogSave`, // `${cffpURL}/user/loginVerification`,
`${cffpURL}/user/powerQuery`,`${cffpURL}/user/wxLogin`, // `${apiURL}/appVersion/checkIsUpdate`,
`${cffpURL}/certificate/officialWebsiteDetail`, // `${cffpURL}/accessLog/accessLogSave`,
`${apiURL}/verificationCode`, // `${cffpURL}/user/powerQuery`,
`${sfpUrl}/sfp/sfpMain/pocessTracking`, // `${cffpURL}/user/wxLogin`,
`${cffpURL}/partner/queryById`, // `${cffpURL}/certificate/officialWebsiteDetail`,
]; // `${apiURL}/verificationCode`,
export const interceptor = () => { // `${sfpUrl}/sfp/sfpMain/pocessTracking`,
uni.addInterceptor('request', { // `${cffpURL}/partner/queryById`,
// 请求拦截器 // ];
invoke(args) {
// 当本地没有token,并且接口地址没在白名单内,需要重新获取token // // 判断是否为资源请求(图片、字体等)
if (!uni.getStorageSync('uni-token') && !whiteApiList.includes(args.url)) { // const isResourceRequest = (url) => {
// const resourceExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.ttf', '.woff', '.woff2'];
const params = { // return resourceExtensions.some(ext => url.includes(ext));
ticket: 'uni-app', // };
loginId: null
} // export const interceptor = () => {
let h5userId = uni.getStorageSync('cffp_userId'); // uni.addInterceptor('request', {
// // 请求拦截器
if (h5userId) { // invoke(args) {
params.loginId = h5userId; // // 资源请求不添加认证头,避免触发OPTIONS预检请求
// if (isResourceRequest(args.url)) {
} // // 对于资源请求,使用更简单的请求头
uni.request({ // args.header = {
url: `${apiURL}/authorize/obtainToken`, // 'content-type': 'application/x-www-form-urlencoded'
method: 'POST', // };
data: params, // return;
success: (res) => { // }
if (res.statusCode === 200) {
uni.setStorageSync('uni-token', res.data['data']['token']); // // 当本地没有token,并且接口地址没在白名单内,需要重新获取token
let isHas = window.location.href.indexOf('?')==-1?'?':'&'; // if (!uni.getStorageSync('uni-token') && !whiteApiList.includes(args.url)) {
window.location.href = window.location.href + isHas + 't_reload=' + new Date().getTime(); // const params = {
} // ticket: 'uni-app',
} // loginId: null
}) // }
} // let h5userId = uni.getStorageSync('cffp_userId');
//设置请求头及token
args.header = { // if (h5userId) {
'content-type': args.method === 'POST' ? 'application/json' : 'application/x-www-form-urlencoded', // params.loginId = h5userId;
'X-Authorization': uni.getStorageSync('uni-token') ? uni.getStorageSync('uni-token') : '', // }
// 'Access-Control-Allow-Headers': 'appId',
// 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', // uni.request({
// 'Access-Control-Max-Age': 86400, // url: `${apiURL}/authorize/obtainToken`,
} // method: 'POST',
}, // data: params,
// 响应拦截器,可以对数据进行预处理 // success: (res) => {
success(args) { // if (res.statusCode === 200) {
if(args && args.data && args.data.errorCode && "T001"==args.data.errorCode){ // uni.setStorageSync('uni-token', res.data['data']['token']);
uni.removeStorageSync('isLogin'); // let isHas = window.location.href.indexOf('?')==-1?'?':'&';
uni.switchTab({ // window.location.href = window.location.href + isHas + 't_reload=' + new Date().getTime();
url:'/pages/index/index' // }
}) // }
} // })
}, // }
fail() {
// console.log('interceptor-fail', err) // // 设置API请求头及token
}, // args.header = {
complete() { // 'content-type': args.method === 'POST' ? 'application/json' : 'application/x-www-form-urlencoded',
// uni.hideLoading() // 'X-Authorization': uni.getStorageSync('uni-token') ? uni.getStorageSync('uni-token') : '',
} // }
}) // },
} // // 响应拦截器,可以对数据进行预处理
// success(args) {
// if(args && args.data && args.data.errorCode && "T001"==args.data.errorCode){
// uni.removeStorageSync('isLogin');
// uni.switchTab({
// url:'/pages/index/index'
// })
// }
// },
// fail(err) {
// console.log('interceptor-fail', err)
// },
// complete() {
// // uni.hideLoading()
// }
// })
// // 添加image拦截器,专门处理图片请求
// uni.addInterceptor('image', {
// invoke(args) {
// // 图片请求使用简单请求头
// args.header = {
// 'content-type': 'application/x-www-form-urlencoded'
// };
// }
// });
// }
// 旧版的拦截器
import {apiURL,cffpURL,sfpUrl} from "../environments/environment";
import api from "@/api/api";
// 白名单,不需要携带token就允许被访问的接口
const whiteApiList = [`${apiURL}/authorize/obtainToken`,
`${apiURL}/authorize/checkToken`,
`${cffpURL}/user/loginVerification`,
`${apiURL}/appVersion/checkIsUpdate`,
`${cffpURL}/accessLog/accessLogSave`,
`${cffpURL}/user/powerQuery`,`${cffpURL}/user/wxLogin`,
`${cffpURL}/certificate/officialWebsiteDetail`,
`${apiURL}/verificationCode`,
`${sfpUrl}/sfp/sfpMain/pocessTracking`,
`${cffpURL}/partner/queryById`,
];
export const interceptor = () => {
uni.addInterceptor('request', {
// 请求拦截器
invoke(args) {
// 当本地没有token,并且接口地址没在白名单内,需要重新获取token
if (!uni.getStorageSync('uni-token') && !whiteApiList.includes(args.url)) {
const params = {
ticket: 'uni-app',
loginId: null
}
let h5userId = uni.getStorageSync('cffp_userId');
if (h5userId) {
params.loginId = h5userId;
}
uni.request({
url: `${apiURL}/authorize/obtainToken`,
method: 'POST',
data: params,
success: (res) => {
if (res.statusCode === 200) {
uni.setStorageSync('uni-token', res.data['data']['token']);
let isHas = window.location.href.indexOf('?')==-1?'?':'&';
window.location.href = window.location.href + isHas + 't_reload=' + new Date().getTime();
}
}
})
}
//设置请求头及token
args.header = {
'content-type': args.method === 'POST' ? 'application/json' : 'application/x-www-form-urlencoded',
'X-Authorization': uni.getStorageSync('uni-token') ? uni.getStorageSync('uni-token') : '',
// 'Access-Control-Allow-Headers': 'appId',
// 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
// 'Access-Control-Max-Age': 86400,
}
},
// 响应拦截器,可以对数据进行预处理
success(args) {
if(args && args.data && args.data.errorCode && "T001"==args.data.errorCode){
uni.removeStorageSync('isLogin');
uni.switchTab({
url:'/pages/index/index'
})
}
},
fail() {
// console.log('interceptor-fail', err)
},
complete() {
// uni.hideLoading()
}
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment