Commit 6befba54 by yuzhenWang

改变由小程序进来的分享方式

parent c0e9da66
......@@ -66,6 +66,12 @@
console.log('App Show', options);
// 每次进应用显示时检查用户状态
this.checkUserStatus();
// if(options.query.mpCffp){
// uni.setStorageSync('mpCffp',options.query.mpCffp)
// }else{
// uni.removeStorageSync('mpCffp')
// }
// App平台从options获取参数
// #ifdef APP-PLUS
if(options && options.query) {
......@@ -162,6 +168,10 @@
// 处理H5平台的URL参数
handleH5UrlParams() {
const url = window.location.href;
if(uni.getStorageSync('mpCffp')){
uni.removeStorageSync('mpCffp')
}
if(url.indexOf('?') > -1) {
const queryString = url.split('?')[1];
const params = this.parseQueryString(queryString);
......@@ -234,8 +244,10 @@
if(params.addSystemType){
uni.setStorageSync('addSystemType', params.addSystemType);
}
// // 可以在这里添加事件通知其他页面参数已准备好
// uni.$emit('externalParamsReady', params);
// 家办商城跳转,分享带参
if(params.mpCffp){
uni.setStorageSync('mpCffp',params.mpCffp)
}
} catch(e) {
console.error('存储外部链接参数失败:', e);
}
......
<template>
<view class="multi-select-dropdown">
<!-- 直接调用toggleDropdown -->
<!-- 遮罩层 -->
<view class="dropdown-mask" v-show="isOpen" @click.stop="closeDropdown"></view>
<!-- 下拉内容 - 修改为底部弹出 -->
<view class="dropdown-content bottom-popup" v-show="isOpen">
<view class="boxImg">
<view class="preview-image">
<image
v-if="imgType == 'orderPoster'"
:src="localImage"
mode="widthFix"
></image>
<image
:src="localImage"
mode="widthFix"
v-if="imgType == 'sharePoster'"
></image>
<view class="btnBottom" :style="{bottom:btnBottom}">
<view class="desTxt">
{{shareTxt}}
</view>
<view class="closeBtn" @click.stop="closeDropdown">
<view class="closeBox">
<view class="iconfont icon-guanbi" ></view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {setWechatShare,initJssdkShare,setWechatShareDirectly} from '@/util/fiveshare';
import dataHandling from "@/util/dataHandling";
import api from "@/api/api";
export default {
name: 'sharePosterPop',
props: {
// 分享的海报
generatedImage: {
type: String,
default: ''
},
// 分享的海报链接
sharePosterUrl: {
type: String,
default: ''
},
// 分享的海报数据
sharePosterObj: {
type: Object,
},
btnBottom:{
type: String,
default: ''
},
shareTxt:{
type: String,
default: '长按图片分享给朋友'
},
imgType:{
type:String,
default:'sharePoster'
}
},
data() {
return {
isOpen: false,
localImage: '' // 内部存储图片
}
},
computed: {
},
watch: {
// 监听父组件传递的图片变化
generatedImage(newVal) {
if (newVal) {
this.localImage = newVal
}
}
},
mounted() {
},
beforeDestroy() {
console.log('销毁了');
},
methods: {
toggleDropdown() {
if (this.isOpen) {
this.closeDropdown()
} else {
this.openDropdown()
}
},
openDropdown() {
this.isOpen = true
// 禁止页面滚动
document.body.style.overflow = 'hidden'
},
closeDropdown() {
this.isOpen = false
this.$emit('closePoster')
// 恢复页面滚动
document.body.style.overflow = ''
},
// 触摸开始
handleTouchStart() {
// 显示识别选项
this.showActionSheet();
// this.pressTimer = setTimeout(() => {
// this.showScanHint = true;
// }, this.longPressDuration);
},
// 显示操作菜单
showActionSheet() {
if (typeof wx !== 'undefined') {
uni.showActionSheet({
itemList: ['识别二维码'],
success: (res) => {
switch (res.tapIndex) {
case 0:
this.scanQRCode();
break;
}
}
});
}
},
// 识别二维码
scanQRCode() {
if (typeof wx !== 'undefined') {
wx.scanQRCode({
needResult: 1,
scanType: ["qrCode"],
success: (res) => {
const result = res.resultStr;
console.log('扫描结果',result);
// this.$emit('qrScanned', result);
}
});
}
},
}
}
</script>
<style lang="scss" scoped>
.multi-select-dropdown {
position: relative;
display: inline-block;
.dropdown-content {
position: fixed;
left: 50%;
top: 0%;
transform: translateX(-50%);
color: #fff;
padding: 50rpx;
box-sizing: border-box;
z-index: 1100;
transition: transform 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
&.bottom-popup {
// transform: translateY(0);
}
.boxImg{
width: 550rpx;
height:550rpx;
.preview-image{
display: block;
position: relative;
width: 100%;
.btnBottom{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
box-sizing: border-box;
margin-top: 20rpx;
position: absolute;
bottom: -16%;
.desTxt{
font-size: 32rpx;
font-weight: 500;
}
.btnBox{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
.itemBtn{
.top{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.commonIcon{
font-size: 30rpx;
color: #fff;
width: 80rpx;
height: 80rpx;
background-color: #2d2b2c;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
}
.bottom{
color: #fff;
font-size: 24rpx;
}
}
}
}
.closeBtn{
margin-top: 20rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
.closeBox{
width: 60rpx;
height: 60rpx;
background-color: #2d2b2c;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
.icon-guanbi{
font-size: 26rpx;
color: #fff;
}
}
}
}
}
}
}
.dropdown-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
/* 所有iPad竖屏 */
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) {
/* 竖屏样式 */
.boxImg {
width: 350rpx !important;
height: 350rpx !important;
}
.btnBottom {
bottom: -21% !important;
.desTxt{
font-size: 26rpx !important;
}
}
}
/* 所有iPad横屏 */
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) {
/* 横屏样式 */
.boxImg {
width:650rpx !important;
height:650rpx !important;
}
.btnBottom {
bottom: -15% !important;
}
}
}
</style>
\ No newline at end of file
<template>
<view class="box" :class="{ 'is-loading': loading }">
<text class="iconfont icon-loading" :style="{color:loadColor}"></text>
</view>
</template>
<script>
export default {
props: {
loading: {
type: Boolean,
default: false
},
loadColor: {
type: String,
default: '#fff'
}
}
}
</script>
<style scoped lang="scss">
.box {
color: #fff;
/* 初始状态不旋转 */
transform: rotate(0deg);
transition: transform 0.3s;
}
.box.is-loading {
font-size: 24rpx;
/* 无限旋转动画 */
animation: rotating 1s linear infinite;
}
@keyframes rotating {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
\ No newline at end of file
......@@ -8,19 +8,35 @@
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
// 判断是否在小程序Webview环境中
function isInMiniProgram() {
// 更安全的小程序环境判断
try {
return typeof wx !== 'undefined' && wx.miniProgram && wx.miniProgram.getEnv;
} catch (e) {
return false;
}
}
// 页面加载完成后执行
document.addEventListener('DOMContentLoaded', function() {
// 非小程序环境才加载微信JS-SDK
if (!isInMiniProgram()) {
var script = document.createElement('script');
script.src = 'https://res2.wx.qq.com/open/js/jweixin-1.6.0.js';
document.head.appendChild(script);
console.log('加载微信JS-SDK');
} else {
console.log('小程序Webview环境,不加载微信JS-SDK');
}
});
</script>
<title>银盾家办</title>
<link rel="stylesheet" href="./static/font/iconfont.css">
<link rel="shortcut icon" href="./static/iconLong.png">
<!-- <link rel="shortcut icon" href="./static/icon.png"> -->
<!--preload-links-->
<!--app-context-->
<!-- 哈希加密算法 -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.9.0/sha256.min.js"></script> -->
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<!-- 移动端调试 -->
<!-- <script type="text/javascript" src="//cdn.jsdelivr.net/npm/eruda"></script> -->
<!-- <script>eruda.init();</script> -->
<script src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
</head>
<body>
<div id="app">
......
<template>
<view class="container">
<!-- 禁用弹窗 -->
<restrictedTip ref="restrictedTip"/>
<view v-if="!mpCffp">
<view class="shareheader" style="" v-if="coursesharing != 1 || deviceType==3">
<!-- #ifdef APP -->
<view class="iconfont icon-youjiantou" style="margin-left: 30rpx;" @click="goBack()"></view>
<!-- #endif -->
<view class="share-entrance">
<view class="share-entrance" >
<view style="z-index: 99999;">
<uni-popup ref="share" type="top" safeArea backgroundColor="#F4F2F3" :maskClick='true'
@change="maskClick">
<uni-popup-share @select="sharechange"></uni-popup-share>
</uni-popup>
</view>
<!-- v-if="isWxH5" -->
<view v-if="isWxH5" style="width: 40rpx;height: 40rpx;padding-right: 20rpx;">
<image class="image" @click="reinvite" src="../../static/fastentry/Slice122.png" mode=""></image>
......@@ -22,8 +26,12 @@
<view class="" style="width: 40rpx;height: 40rpx; ">
<image class="image" @click="shareToggle" src="../../static/fastentry/Slice12.png" mode=""></image>
</view>
</view>
</view>
</view>
<!-- 课程banner图 -->
<!-- v-show="!sliceshare" -->
<view class="courseBannerBox" v-if="!sliceshare && bannerViewType == '1'">
......@@ -128,9 +136,29 @@
</h4>
<view v-html="lecturerInfo?.lecturerIntroduce" class="lecturerText richTextContent"></view>
</view>
<view v-if="!mpCffp">
<view class="buyBox" @click="saveOrder()" v-if="(courseInfo.status == 1 || courseInfo.status == 2) && courseInfo.coursePrice != 0">
<text>{{showName}}</text>
</view>
</view>
<view v-if="mpCffp" class="shareBuyBox">
<view class="rightShare" @click="reinvite">
<loadingIcon
:loading="isLoading"
v-if="isLoading"
loadColor="#20269B"
/>
<text style="margin-left: 5rpx;">分享</text>
</view>
<view class="leftBuy" @click="saveOrder()" v-if="(courseInfo.status == 1 || courseInfo.status == 2) && courseInfo.coursePrice != 0">
<loadingIcon
:loading="isOrderLoading"
v-if="isOrderLoading"
/>
<text style="margin-left: 5rpx;">{{showName}}</text>
</view>
</view>
</view>
</view>
......@@ -180,8 +208,65 @@
@join="gotoJoinPartner"
@continue="continueShare"
/>
<!-- 海报弹窗 -->
<sharePosterPop
ref="sharePosterPop"
:generatedImage="generatedImage"
@closePoster="closePoster"
:shareTxt="posterShareTxt"
:imgType="posterImgType"
></sharePosterPop>
<!-- #ifdef H5 -->
<view class="generateImageBox" ref="captureElement" v-if="!generatedImage">
<view class="imgBox">
<img
v-if="showImg"
class="posterImg"
@load="handleBgImageLoad"
@error="handleBgImageError"
style="display: block;"
:src="shareItem.fileFirstImage+'?t='+Math.random()"
crossorigin="anonymous"
alt="防缓存图片"
/>
</view>
<view class="txtBox">
<view class="descriptionTxt">
{{shareItem.fileSynopsis}}
</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>
<view class="companyName">银盾家办</view>
</view>
<view class="bottom">
{{posterDesTxt}}
</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>
<!-- #endif -->
</view>
</template>
<script>
......@@ -197,7 +282,10 @@
import {nanoid} from 'nanoid';
import common from '../../common/common';
import {baseURL,apiURL,cffpURL,companyInfo,shareURL} from "@/environments/environment";
import sharePosterPop from '@/components/commonPopup/sharePosterPop.vue';
import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage';
import loadingIcon from '@/components/loading/loading.vue';
export default {
components: {
UniShareWx,
......@@ -205,7 +293,9 @@
LoginPopup,
VerifyPopup,
PartnerTipPopup,
restrictedTip
restrictedTip,
sharePosterPop,
loadingIcon
},
data() {
return {
......@@ -271,7 +361,20 @@
time: 3
}
],
danmuValue: ''
danmuValue: '',
qrCodeUrl: 'https://example.com',//二维码的链接地址
qrCodeSize: 100,//二维码的尺寸
companyLogo : '../../static/logo2.png',
generatedImage:'',//生成的海报图片,
shareItem:{fileFirstImage:''},
showImg:false,
mpCffp:'',
isLoading: false,
posterDesTxt:'',
isOrderLoading:false,
posterShareTxt:'长按图片分享给朋友',
orderCodeUrl:'',
posterImgType:'sharePoster'
};
},
methods: {
......@@ -324,6 +427,23 @@
this.userId = uni.getStorageSync('cffp_userId')
const shareCode = nanoid() + this.userId
const jumptime = Date.parse(new Date()) / 1000
if(this.mpCffp){
if(uni.getStorageSync('posterItem')){
this.shareItem = JSON.parse(JSON.stringify(uni.getStorageSync('posterItem')))
}
this.posterShareTxt = '长按图片分享给朋友'
this.posterDesTxt = '识别二维码查看商品'
let newLink = shareURL + "/pages/courseDetail/courseDetail?fileId=" + this.fileId +
'&coursesharing=1' + '&serialsNo=' + nanoid() + '&shareCode=' + shareCode + '&shareUserId=' +
this.userId + '&jumpUrl=' + jumptime + "&"
this.qrCodeUrl = newLink
this.showImg = true
this.isLoading = true
this.submitsuessc(shareCode,jumptime),
this.posterImgType = 'sharePoster'
return
}
//app分享
// #ifdef APP-PLUS
let dataWXform = {
......@@ -573,8 +693,6 @@
shareCode: this.shareCode,
dataSource: this.coursesharing == 1 ? '2' : this.dataSource
}
console.log('param',param);
// return
api.saveOrder(param).then(res => {
if (res['success']) {
this.orderId = res['data']['id'];
......@@ -589,6 +707,35 @@
'产品详情',
'pages/courseDetail/courseDetail'
)
// 如果是商城跳转到cffp得购买直接弹出海报框
if(this.mpCffp){
if(uni.getStorageSync('posterItem')){
this.shareItem = JSON.parse(JSON.stringify(uni.getStorageSync('posterItem')))
}
let dataToken = uni.getStorageSync('uni-token')
this.posterShareTxt = '保存图片扫码下单'
this.posterDesTxt = '扫码下单'
let newLink = shareURL + `/pages/orderConfirm/orderConfirm?fileId=${this.fileId}&orderId=${this.orderId}&userId=${this.userId}&dataToken=${dataToken}`
this.qrCodeUrl = newLink
this.showImg = true
this.isOrderLoading = true,
this.posterImgType = 'orderPoster'
return
}
// 是由小程序的webview跳转过来的
// if (this.mpCffp) {
// let dataToken = uni.getStorageSync('uni-token')
// this.orderCodeUrl = shareURL + `/pages/orderConfirm/orderConfirm?fileId=${this.fileId}&orderId=${this.orderId}&userId=${this.userId}&dataToken=${dataToken}`
// // 这里需要与小程序的webview通信,不会写
// setTimeout(()=>{
// console.log('wx',wx);
// this.sendMessageToMiniProgram();
// },500)
// return
// }
uni.navigateTo({
url: `/pages/orderConfirm/orderConfirm?fileId=${this.fileId}&orderId=${this.orderId}&userId=${this.userId}`
})
......@@ -998,10 +1145,236 @@
}
})
}
},
// 海报分享方法
// 背景图片加载成功
handleBgImageLoad() {
this.generateQrcodeAndCapture();
},
// 背景图片加载失败
handleBgImageError() {
console.log('产品图片加载完成');
// 即使失败也继续流程,可能会有默认背景
// this.generateQrcodeAndCapture();
},
// 顺序执行:生成二维码 -> 截图
async generateQrcodeAndCapture() {
try {
// uni.showLoading({
// title: '准备生成分享图...'
// });
// 1. 先生成二维码
console.log('开始生成二维码...');
await this.makeQrcode();
console.log('二维码生成完成');
// 2. 等待500ms确保渲染完成
await new Promise(resolve => setTimeout(resolve, 1500));
// 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
this.isLoading = false
this.isOrderLoading = false
this.$refs.sharePosterPop.toggleDropdown()
// 压缩图片
// 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));
};
});
},
// 关闭海报弹窗
closePoster(){
this.showImg = false
this.generatedImage = '',
this.shareItem = {
fileFirstImage:''
}
},
sendMessageToMiniProgram() {
// 确保wx对象已存在
if (typeof wx === 'undefined') {
console.error('微信JS-SDK未加载');
return false;
}
// 构建要传递的数据
const messageData = {
type: 'showOrderPopup',
action: 'purchase',
orderCodeUrl: this.orderCodeUrl,
title: this.courseInfo.fileTitle,
price: this.courseInfo.coursePrice,
fileId: this.fileId,
timestamp: Date.now()
};
console.log('准备发送消息到小程序:', messageData);
try {
if (wx.miniProgram) {
wx.miniProgram.postMessage({
data: messageData
});
// 2. 然后触发导航(让消息被接收)这种方法不行
wx.miniProgram.navigateBack({
delta: 0 // 后退0层,相当于刷新当前页
});
console.log('消息发送并触发接收成功');
} else {
console.error('wx.miniProgram不存在');
return false;
}
return true;
} catch (error) {
console.error('发送消息失败:', error);
return false;
}
},
onLoad(option) {
},
onLoad(option) {
if(companyInfo.companyType == '1'){
this.companyLogo='../../static/myteam/Group1633.png';
}else if(this.companyType == '2'){
this.companyLogo='../../static/logo2.png';
}
if(option.addSystemType){
this.addSystemType = option.addSystemType
}
......@@ -1027,7 +1400,7 @@
uni.setStorageSync('h5_coursesharing', this.coursesharing);
this.getshareData()
}
let dataForm = JSON.parse(uni.getStorageSync('cffp_userInfo'))
let dataForm = JSON.parse(JSON.stringify(uni.getStorageSync('cffp_userInfo')))
this.realName = dataForm.realName;
if(!this.realName){
this.queryInfo();
......@@ -1036,7 +1409,13 @@
// this.switchTab(1);
},
onShow() {
//this.switchTab(1);
this.isLoading = false
if(uni.getStorageSync('mpCffp')){
this.mpCffp = uni.getStorageSync('mpCffp')
}
this.showImg = false
this.generatedImage = ''
this.shareItem={fileFirstImage:''},
this.loginType = uni.getStorageSync('loginType')
this.init();
this.isWx_Miniprogram();
......@@ -1070,16 +1449,96 @@
setWechatShare();
}, window.location.href);
// #endif
},
onHide() {
this.$nextTick(()=>{
this.$refs.sharePosterPop.closeDropdown()
})
}
}
</script>
<style lang="scss" scoped>
.container{
// background-color: #f7f7f7;
width: 100%;
height: auto;
box-sizing: border-box;
position: relative;
.generateImageBox{
position: absolute;
top:-100%;
z-index: -1;
border-radius: 20rpx;
width: 100%;
box-sizing: border-box;
background-color: #fff;
.imgBox{
box-sizing: border-box;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
.posterImg{
width: 900rpx;
height: 900rpx;
}
}
.txtBox{
padding: 20rpx;
.descriptionTxt{
font-size: 45rpx;
}
.productNum{
font-size: 45rpx;
font-weight: 500;
margin: 10rpx 0;
color: rgba(255, 74, 50, 1);
}
.generateImageBottom{
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left{
min-width: 500rpx;
.top{
width: 100%;
display: flex;
align-items: center;
image{
width: 100%;
}
.companyName{
min-width: 300rpx;
color: #333;
font-size: 35rpx;
}
}
.bottom{
font-size: 30rpx;
color: #999;
margin-top: 10rpx;
font-weight: 500;
}
}
.qrcode-container {
background: #fff;
padding: 10rpx;
border-radius: 10rpx;
box-shadow: 0 0 10rpx rgba(0,0,0,0.1);
.qrcode-canvas {
display: block;
}
}
}
}
}
}
page {
padding: 0;
......@@ -1355,6 +1814,48 @@
text-align: center;
max-width: 60%;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
}
.shareBuyBox{
position: fixed;
bottom: 0;
left: 0;
right: 0;
color: #fff;
font-size: 36rpx;
padding: 40rpx 20rpx;
width: 100%;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #fff;
box-sizing: border-box;
.leftBuy{
color: #fff;
background-color: #20269B;
padding: 20rpx 100rpx;
border-radius: 80rpx;
font-size: 36rpx;
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.rightShare{
margin-right: 30rpx;
width: 30%;
color: #20269B;
font-size: 36rpx;
padding: 20rpx 0rpx;
border-radius: 80rpx;
border: 1rpx solid #20269B;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
......@@ -1385,5 +1886,63 @@
margin-top: 30%;
padding: 0 30px;
}
/* iPad横屏特定适配 */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: landscape) {
.container {
.generateImageBox{
max-width: 950rpx !important;
.descriptionTxt{
font-size: 33rpx !important;
}
.txtBox{
.generateImageBottom{
.left{
width: 60% !important;
.top{
width: 100%;
.companyName{
min-width: 200rpx !important;
font-size: 30rpx !important;
}
}
.bottom{
font-size: 28rpx !important;
}
}
}
}
}
}
}
/* 所有iPad竖屏 */
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) {
/* 竖屏样式 */
.generateImageBox{
max-width: 950rpx !important;
.descriptionTxt{
font-size: 33rpx !important;
}
.txtBox{
.generateImageBottom{
.left{
width: 60% !important;
.top{
width: 100%;
.companyName{
min-width: 200rpx !important;
font-size: 30rpx !important;
}
}
.bottom{
font-size: 28rpx !important;
}
}
}
}
}
}
}
</style>
......@@ -26,24 +26,27 @@
</view>
</view>
</view>
<!-- 家办商城跳cffp的分享功能 -->
<!-- #ifdef H5 -->
<!-- v-if="!generatedImage" -->
<view class="generateImageBox" ref="captureElement" >
<view class="generateImageBox" ref="captureElement" v-if="!generatedImage">
<view class="imgBox">
<image
id="posterImg"
style="display: block;"
:src="shareItem.displayImage"
mode="widthFix"
<img
class="posterImg"
@load="handleBgImageLoad"
@error="handleBgImageError"
crossOrigin="anonymous"
></image>
<view class="descriptionTxt">
{{shareItem.fileSynopsis}}
style="display: block;"
:src="sharePosterItem.fileFirstImage+'?t='+Math.random()"
crossorigin="anonymous"
alt="防缓存图片"
/>
</view>
<view class="txtBox">
<view class="descriptionTxt">
{{sharePosterItem.fileSynopsis}}
</view>
<view class="productNum">
{{shareItem.coursePrice}}
{{sharePosterItem.coursePrice}}
</view>
<view class="generateImageBottom">
<view class="left">
......@@ -54,8 +57,7 @@
mode="widthFix"
></image>
</view>
<text class="companyName">分销系统</text>
<text class="companyName">银盾家办</text>
</view>
<view class="bottom">
识别二维码查看商品
......@@ -71,12 +73,10 @@
</view>
</view>
</view>
<!-- 添加生成的图片预览 -->
<view class="preview-container" v-if="generatedImage">
<image :src="generatedImage" mode="widthFix" class="preview-image"></image>
</view>
<!-- #endif -->
<view class="productBox">
<view class="productList" :style="{marginTop}">
<view class="tabBox">
<view :class="{'actived': courseClassify==4}" @click="transform('consult')"><text>咨询产品</text></view>
......@@ -106,7 +106,11 @@
最高可赚¥{{item.income || '0.00'}}
</view>
<view class="right" @click="gotoShare(item)">
去分享
<loadingIcon
:loading="isLoading"
v-if="isLoading&&(sharePosterItem.fileId==item.fileId)"
/>
<text style="margin-left: 5rpx;">去分享</text>
</view>
</view>
</view>
......@@ -120,6 +124,14 @@
@close="closeLogin"
>
</BootPage>
<!-- 海报弹窗 -->
<sharePosterPop
ref="sharePosterPop"
:generatedImage="generatedImage"
@closePoster="closePoster"
:sharePosterUrl="qrCodeUrl"
:sharePosterObj="sharePosterObj"
></sharePosterPop>
<uni-popup ref="popup" type="center" background-color="#fff">
<view class="descriptionBox">
<view class="imageBox">
......@@ -172,7 +184,8 @@
import UniShareWx from "@/uni_modules/uni-share-wx/index.vue";
import {nanoid} from 'nanoid';
import restrictedTip from '@/components/commonPopup/restrictedTip.vue';
import GenerateImage from '@/components/commonPopup/generateImage.vue';
import sharePosterPop from '@/components/commonPopup/sharePosterPop.vue';
import loadingIcon from '@/components/loading/loading.vue';
import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage';
export default{
......@@ -196,7 +209,8 @@
BootPage,
PartnerTipPopup,
restrictedTip,
GenerateImage
sharePosterPop,
loadingIcon
},
watch: {
// 监听 prop 变化,更新本地副本
......@@ -219,32 +233,34 @@
shareTipsFlag:false,
sourceType:'1',//根据来源展示二维码 默认是cffp,
env:dataHandling.getRuntimeEnv2(),
shareItem:{displayImage:""},//分享的产品
shareItem:{},//分享的产品
sharelogin: false,
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:''
generatedImage:'',//生成的海报图片
sharePosterObj:{},//海报分享数据
sharePosterItem:{fileFirstImage:''},
isLoading: false
}
},
onLoad() {
this.queryName = uni.getStorageSync('queryName') || '';
this.sourceType = uni.getStorageSync('addSystemType') || '1';
if(companyInfo.companyType == '1'){
companyInfo.companyLogo='../../static/myteam/Group1633.png';
this.companyLogo='../../static/myteam/Group1633.png';
}else if(this.companyType == '2'){
companyInfo.companyLogo='../../static/logo2.png';
this.companyLogo='../../static/logo2.png';
}
},
onShow() {
this.isLoading = false
this.generatedImage = ''
this.sharePosterItem = {fileFirstImage:''}
this.queryName = uni.getStorageSync('queryName') || '';
this.courseList();
this.sourceType = uni.getStorageSync('addSystemType') || '1';
......@@ -278,6 +294,7 @@
}
}
},
methods:{
transform(value){
if(value == 'consult'){
......@@ -306,10 +323,6 @@
if(uni.getStorageSync('cffp_userInfo')){
this.userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo'))
}
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'){
......@@ -324,7 +337,7 @@
this.sharelogin = true
return
}
this.shareItem = JSON.parse(JSON.stringify(item))
// 已登录,未成为合伙人
if(this.userInfo&&!this.userInfo['partnerType']) {
dataHandling.pocessTracking(
......@@ -339,36 +352,34 @@
return
}
// 正常逻辑先注释掉
// if(this.runEnv == 'browser'){
// dataHandling.pocessTracking(
// '点击',
// `用户在产品中心浏览器端点击产品分享按钮`,
// '点击',
// 2,
// '产品中心',
// 'pages/courselist/courselist'
// )
// this.$refs.popup.open()
// return
// }
if(this.runEnv == 'browser'){
dataHandling.pocessTracking(
'点击',
`用户在产品中心浏览器端点击产品分享按钮`,
'点击',
2,
'产品中心',
'pages/courselist/courselist'
)
this.$refs.popup.open()
return
}
this.continueShare()
},
continueShare(){
this.userId = uni.getStorageSync('cffp_userId')
const shareCode = nanoid() + this.userId
const jumptime = Date.parse(new Date()) / 1000
uni.setStorageSync('mpCffp','1')
if(uni.getStorageSync('mpCffp')){
this.isLoading = true
this.sharePosterItem = JSON.parse(JSON.stringify(this.shareItem))
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);
this.submitsuessc(shareCode,jumptime,this.shareItem)
return
}
//app分享
......@@ -515,11 +526,13 @@
'产品中心',
'pages/courselist/courselist'
)
uni.setStorageSync('posterItem',item)
uni.navigateTo({
url: `/pages/courseDetail/courseDetail?fileId=${item.fileId}`
});
},
courseList(){
console.log('执行了');
const param = {
queryName:this.queryName,
courseClassify:this.courseClassify
......@@ -554,7 +567,7 @@
// 背景图片加载失败
handleBgImageError() {
console.error('产品图片加载完成');
console.log('产品图片加载完成');
// 即使失败也继续流程,可能会有默认背景
// this.generateQrcodeAndCapture();
},
......@@ -572,7 +585,7 @@
console.log('二维码生成完成');
// 2. 等待500ms确保渲染完成
await new Promise(resolve => setTimeout(resolve, 1000));
await new Promise(resolve => setTimeout(resolve, 2000));
// 3. 执行截图
console.log('开始截图...');
......@@ -668,7 +681,9 @@
// 调用工具函数生成图片
const imageData = await elementToImage(element);
this.generatedImage=imageData
// console.log('this.generatedImage',this.generatedImage);
this.isLoading = false
this.$refs.sharePosterPop.toggleDropdown()
// 压缩图片
// const compressedImage = await this.compressImage(imageData);
......@@ -713,12 +728,13 @@
};
});
},
// 获取无缓存URL
getCacheFreeUrl(url) {
if (!url) return '';
// 添加时间戳参数防止缓存
return url + (url.includes('?') ? '&' : '?') + '_t=' + Date.now();
},
// 关闭海报弹窗
closePoster(){
this.sharePosterItem = {
fileFirstImage:""
}
this.generatedImage = ''
}
},
mounted() {
......@@ -735,6 +751,9 @@
onHide() {
this.queryName = ''
uni.removeStorageSync('queryName')
this.$nextTick(()=>{
this.$refs.sharePosterPop.closeDropdown()
})
},
}
......@@ -751,38 +770,44 @@
box-sizing: border-box;
.generateImageBox{
position: absolute;
bottom: 0;
right: -100%;
top:-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%;
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
.posterImg{
width: 900rpx;
height: 900rpx;
}
.descriptionTxt{
font-size: 28rpx;
}
.txtBox{
padding: 20rpx;
.descriptionTxt{
font-size: 45rpx;
}
.productNum{
font-size: 30rpx;
font-size: 45rpx;
font-weight: 500;
margin: 20rpx 0;
margin: 10rpx 0;
color: rgba(255, 74, 50, 1);
}
.generateImageBottom{
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.left{
width: 50%;
min-width: 500rpx;
.top{
width: 100%;
display: flex;
......@@ -791,14 +816,16 @@
width: 100%;
}
.companyName{
min-width: 300rpx;
color: #333;
font-size: 28rpx;
font-size: 35rpx;
}
}
.bottom{
font-size: 26rpx;
font-size: 30rpx;
color: #999;
margin-top: 10rpx;
font-weight: 500;
}
}
.qrcode-container {
......@@ -814,11 +841,12 @@
}
}
}
}
.preview-container{
width: 100%;
box-sizing: border-box;
padding: 20rpx;
background-color: pink;
margin-bottom: 100rpx;
.preview-image{
width: 100%;
......@@ -962,13 +990,12 @@
color: rgba(34, 35, 133, 1);
}
.right{
display: flex;
align-items: center;
justify-content: center;
padding: 15rpx 10rpx 15rpx 15rpx;
background: rgba(36, 37, 137, 1);
width: 20%;
font-size: 27rpx;
color: #fff;
border-radius: 0 10rpx 10rpx 0rpx; /* 左上 右上 右下 左下 */
......@@ -1147,6 +1174,56 @@
padding-top: 50rpx;
}
}
.generateImageBox{
max-width: 950rpx !important;
.descriptionTxt{
font-size: 33rpx !important;
}
.txtBox{
.generateImageBottom{
.left{
width: 60% !important;
.top{
width: 100%;
.companyName{
min-width: 200rpx !important;
font-size: 30rpx !important;
}
}
.bottom{
font-size: 28rpx !important;
}
}
}
}
}
}
}
/* 所有iPad竖屏 */
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) {
/* 竖屏样式 */
.generateImageBox{
max-width: 950rpx !important;
.descriptionTxt{
font-size: 33rpx !important;
}
.txtBox{
.generateImageBottom{
.left{
width: 60% !important;
.top{
width: 100%;
.companyName{
min-width: 200rpx !important;
font-size: 30rpx !important;
}
}
.bottom{
font-size: 28rpx !important;
}
}
}
}
}
}
</style>
\ No newline at end of file
......@@ -65,6 +65,7 @@
:showFlag="false"
:cffpCourseInfos="cffpCourseInfos"
@changeCourseClassify="changeCourseClassify"
ref="courselist"
></courselist>
<view class="productListBox">
......@@ -275,6 +276,8 @@
},
onShow() {
console.log('webview',typeof wx !== 'undefined' && wx.miniProgram);
this.loginType = uni.getStorageSync('loginType')
this.init();
......@@ -291,8 +294,12 @@
}
},
onHide() {
this.$nextTick(()=>{
this.$refs.courselist.$refs.sharePosterPop.closeDropdown()
})
},
onLoad(options) {
if(uni.getStorageSync('dataToken')){
this.dataToken = uni.getStorageSync('dataToken')
}
......@@ -786,6 +793,7 @@
}
},
}
</script>
......
......@@ -4,7 +4,29 @@
<text class="iconfont icon-youjiantou zuojiantou" @click="goBack()" style="top: 20rpx;"></text>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="generateImageBox" v-if="!generatedImage">
<view class="imgBox" ref="captureElement">
<img
v-if="posterImg"
class="posterImg"
@load="handleBgImageLoad"
@error="handleBgImageError"
style="display: block;"
src="@/static/images/sharePoster.png"
crossorigin="anonymous"
alt="防缓存图片"
/>
<view class="qrcode-container">
<canvas
canvas-id="qrcode"
class="qrcode-canvas"
:style="{width: qrCodeSize + 'px', height: qrCodeSize + 'px'}"
></canvas>
</view>
</view>
</view>
<!-- #endif -->
<view class="tabTitle">
<text :class="{'actived': tabType===1}" @click="switchTab(1)">基本信息</text>
<text :class="{'actived': tabType===2}" @click="switchTab(2)">邀请信息</text>
......@@ -33,7 +55,18 @@
</view>
</view>
<!-- <share></share> -->
<button type="primary" plain="true" class="sendInvite" @click="shareToggle()">发出邀请</button>
<button
type="primary"
plain="true"
class="sendInvite"
@click="shareToggle()"
>
<loadingIcon
:loading="isLoading"
v-if="isLoading"
/>
<text style="margin-left: 5rpx;">发出邀请</text>
</button>
</view>
<!-- 邀请信息 -->
<view class="inviteListsBox" v-if="tabType===2">
......@@ -94,6 +127,13 @@
</view>
</view>
</view>
<!-- 海报弹窗 -->
<sharePosterPop
ref="sharePosterPop"
:generatedImage="generatedImage"
@closePoster="closePoster"
btnBottom="-15%"
></sharePosterPop>
</view>
</template>
......@@ -103,7 +143,15 @@
import common from '../../common/common';
import {hshare ,setWechatShare,initJssdkShare} from '@/util/fiveshare';
import {baseURL,apiURL,cffpURL,companyInfo,shareURL} from "@/environments/environment";
import sharePosterPop from '@/components/commonPopup/sharePosterPop.vue';
import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage';
import loadingIcon from '@/components/loading/loading.vue';
export default {
components:{
sharePosterPop,
loadingIcon
},
data() {
return {
companyType:companyInfo.companyType,
......@@ -134,9 +182,17 @@
realName: '',
partnerLevel: '',
invitationCode: '',
shareTipsFlag: false
shareTipsFlag: false,
qrCodeUrl:'/myPackageA/applyFranchise/applyFranchise',
qrCodeSize: 80,//二维码的尺寸
generatedImage:'',//生成的海报图片
companyLogo : '../../static/logo2.png',
posterImg:'',
isLoading: false
};
},
onLoad(option) {
//this.partnerLevel = option.levelCode
this.partnerLevel = 'P1'
......@@ -146,6 +202,11 @@
}else {
this.ydLogoShare = `${shareURL}/static/logo2.png`;
}
if(companyInfo.companyType == '1'){
this.companyLogo='../../static/myteam/Group1633.png';
}else if(this.companyType == '2'){
this.companyLogo='../../static/logo2.png';
}
let dataForm = JSON.parse(uni.getStorageSync('cffp_userInfo'))
this.realName = dataForm.realName || dataForm.nickName;
this.invitationCode = dataForm.invitationCode
......@@ -154,12 +215,20 @@
}
},
onShow(){
this.isLoading = false
this.posterImg = ''
this.generatedImage = ''
// #ifdef H5
initJssdkShare(() => {
setWechatShare();
}, window.location.href);
// #endif
},
onHide() {
this.$nextTick(()=>{
this.$refs.sharePosterPop.closeDropdown()
})
},
methods: {
goBack() {
uni.navigateBack({
......@@ -249,10 +318,20 @@
api.saveApplyInfo(this.dataForm).then(res => {
if (res['success']) {
this.shareId = res.data.id;
// #ifdef APP-PLUS
this.$refs.share.open()
// #endif
//#ifdef H5
// 小程序跳cffp得分享
if(uni.getStorageSync('mpCffp')){
this.qrCodeUrl = shareURL +
"/myPackageA/applyFranchise/applyFranchise?shareId=" +
this.shareId + '&invitationCode=' + this.invitationCode+ '&inviteUserId=' + this.userId, //分享链接
this.posterImg = '@/static/images/sharePoster.png'
this.isLoading = true
return
}
this.shareTipsFlag = true;
this.getshareData()
// #endif
......@@ -368,6 +447,150 @@
}
})
},
// 分享海报代码
// 背景图片加载成功
handleBgImageLoad() {
console.log('产品图片加载成功');
this.generateQrcodeAndCapture();
},
// 背景图片加载失败
handleBgImageError() {
console.log('产品图片加载失败');
// 即使失败也继续流程,可能会有默认背景
// this.generateQrcodeAndCapture();
},
// 顺序执行:生成二维码 -> 截图
async generateQrcodeAndCapture() {
try {
uni.showLoading({
title: '准备生成分享图...'
});
// 1. 先生成二维码
console.log('开始生成二维码...');
await this.makeQrcode();
console.log('二维码生成完成');
// 2. 等待500ms确保渲染完成
await new Promise(resolve => setTimeout(resolve, 1500));
// 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
this.isLoading = false
this.$refs.sharePosterPop.toggleDropdown()
// 压缩图片
// const compressedImage = await this.compressImage(imageData);
// this.generatedImage = compressedImage;
} catch (error) {
console.error('截图失败:', error);
throw error; // 抛出错误以便外部捕获
} finally {
uni.hideLoading();
}
},
// 关闭海报弹窗
closePoster(){
this.posterImg = ''
this.generatedImage = ''
}
}
}
</script>
......@@ -376,7 +599,46 @@
.container {
position: relative;
height: 100vh;
.generateImageBox{
position: absolute;
top:-100%;
z-index: -1;
border-radius: 20rpx;
width: 100%;
box-sizing: border-box;
background-color: #fff;
height: 900rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.imgBox{
position: relative;
width: 500rpx;
height: 900rpx;
box-sizing: border-box;
.posterImg{
width: 100%;
height: 100%;
object-fit: cover;
}
.qrcode-container {
position: absolute;
bottom: 1%;
right: 1%;
background: #fff;
padding: 10rpx;
border-radius: 10rpx;
box-shadow: 0 0 10rpx rgba(0,0,0,0.1);
.qrcode-canvas {
display: block;
}
}
}
}
.tabTitle {
color: #666666;
background-color: #fff;
......@@ -509,6 +771,9 @@
background-color: #20269B;
color: #fff;
font-size: 36rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
......
......@@ -204,7 +204,8 @@
tipsFlag: false,
isRedirect: null,
amount: 0,
calculatedPrice: 0
calculatedPrice: 0,
dataToken:'',
}
},
computed: {
......@@ -505,8 +506,43 @@
}, 500)
}
},
reLogin(){
uni.showLoading({
title: '加载中...'
});
const params = {
loginType:'5',
authToken: this.dataToken
}
api.loginVerification(params).then((res)=>{
if(res['success']){
uni.setStorageSync('isLogin','1');
uni.setStorageSync('loginType','codelogin');
uni.setStorageSync('cffp_userId', res.data.userId);
uni.setStorageSync('uni-token', res.data['token']);
this.userId = res.data.userId
this.dataToken = ''
uni.removeStorageSync('dataToken')
}else{
uni.showToast({
title: res['message'],
duration: 2000,
icon: 'none'
})
}
})
uni.hideLoading()
}
},
onLoad(option) {
if(uni.getStorageSync('dataToken')){
this.dataToken = uni.getStorageSync('dataToken')
}
if(uni.getStorageSync('dataToken')&&(!uni.getStorageSync('cffp_userId')||(uni.getStorageSync('cffp_userId')!=option.userId))){
this.reLogin()
}
this.fileId = option.fileId;
this.orderId = option.orderId;
if (option.userId) {
......
......@@ -346,7 +346,7 @@
// 创建两个Promise
const updateInfoPromise = api.updateinfo(UserRequestVO).then(res => {
if (res.success) {
uni.showToast({title: '修改成功', duration: 2000, icon: 'none'});
uni.showToast({title: '修改成功', duration: 1000, icon: 'none'});
dataHandling.pocessTracking(
'个人资料',
`成功修改个人资料`,
......
......@@ -55,6 +55,24 @@
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe441;</span>
<div class="name">loading</div>
<div class="code-name">&amp;#xe441;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe339;</span>
<div class="name">下载保存</div>
<div class="code-name">&amp;#xe339;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe400;</span>
<div class="name">转发</div>
<div class="code-name">&amp;#xe400;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe338;</span>
<div class="name">对号</div>
<div class="code-name">&amp;#xe338;</div>
......@@ -432,9 +450,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1755135137201') format('woff2'),
url('iconfont.woff?t=1755135137201') format('woff'),
url('iconfont.ttf?t=1755135137201') format('truetype');
src: url('iconfont.woff2?t=1755827337778') format('woff2'),
url('iconfont.woff?t=1755827337778') format('woff'),
url('iconfont.ttf?t=1755827337778') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
......@@ -461,6 +479,33 @@
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-loading"></span>
<div class="name">
loading
</div>
<div class="code-name">.icon-loading
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiazaibaocun"></span>
<div class="name">
下载保存
</div>
<div class="code-name">.icon-xiazaibaocun
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zhuanfa1"></span>
<div class="name">
转发
</div>
<div class="code-name">.icon-zhuanfa1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-duihao"></span>
<div class="name">
对号
......@@ -1029,6 +1074,30 @@
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-loading"></use>
</svg>
<div class="name">loading</div>
<div class="code-name">#icon-loading</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiazaibaocun"></use>
</svg>
<div class="name">下载保存</div>
<div class="code-name">#icon-xiazaibaocun</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zhuanfa1"></use>
</svg>
<div class="name">转发</div>
<div class="code-name">#icon-zhuanfa1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-duihao"></use>
</svg>
<div class="name">对号</div>
......
@font-face {
font-family: "iconfont"; /* Project id 4933433 */
src: url('iconfont.woff2?t=1755135137201') format('woff2'),
url('iconfont.woff?t=1755135137201') format('woff'),
url('iconfont.ttf?t=1755135137201') format('truetype');
src: url('iconfont.woff2?t=1755827337778') format('woff2'),
url('iconfont.woff?t=1755827337778') format('woff'),
url('iconfont.ttf?t=1755827337778') format('truetype');
}
.iconfont {
......@@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-loading:before {
content: "\e441";
}
.icon-xiazaibaocun:before {
content: "\e339";
}
.icon-zhuanfa1:before {
content: "\e400";
}
.icon-duihao:before {
content: "\e338";
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -6,6 +6,27 @@
"description": "",
"glyphs": [
{
"icon_id": "10273624",
"name": "loading",
"font_class": "loading",
"unicode": "e441",
"unicode_decimal": 58433
},
{
"icon_id": "567492",
"name": "下载保存",
"font_class": "xiazaibaocun",
"unicode": "e339",
"unicode_decimal": 58169
},
{
"icon_id": "1929167",
"name": "转发",
"font_class": "zhuanfa1",
"unicode": "e400",
"unicode_decimal": 58368
},
{
"icon_id": "925451",
"name": "对号",
"font_class": "duihao",
......
......@@ -392,5 +392,17 @@ export default{
// 3. 刘海屏设备safe-area-inset-top通常大于20(非刘海屏为0)
return computedHeight > 20;
},
// 新增方法:将 Base64 字符串转换为 Blob 对象
dataURLToBlob(dataurl) {
const arr = dataurl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
},
}
\ No newline at end of file
......@@ -103,3 +103,53 @@ export function setWechatShare(data) {
},url)
}
// 新的分享方法 直接调起微信好友弹窗
// 设置微信分享内容并直接调起分享
export function setWechatShareDirectly(data) {
if (!jWeixin) {
console.error('微信SDK未初始化');
return;
}
if(!data){
const currentUrl = `${shareURL}/pages/index/index`;
data = {
title: '成为银盾合伙人,分享商品赚不停',
desc: `资源+伙伴,共赢未来!`,
link: currentUrl,
imgUrl: `${shareURL}/static/images/shareBg.png`
};
}
jWeixin.ready(() => {
// 尝试直接调起分享
try {
// 注意:此接口需要特定权限,普通公众号可能无法使用
jWeixin.invoke('shareWechatMessage', {
title: data.title,
desc: data.desc,
link: data.link,
imgUrl: data.imgUrl
}, function(res) {
if(res.err_msg === 'shareWechatMessage:ok') {
console.log('分享成功');
} else {
// fallback 到常规分享设置
setWechatShare(data);
}
});
} catch (e) {
console.error('直接调起分享失败,使用常规分享', e);
// 常规分享设置
jWeixin.updateAppMessageShareData({
title: data.title,
desc: data.desc,
link: data.link,
imgUrl: data.imgUrl,
success: () => console.log('好友分享设置成功')
});
}
});
}
\ No newline at end of file
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