Commit 4f295149 by yuzhenWang

Merge branch 'uat' into 'master'

Uat

See merge request !74
parents 89dfeb74 d4d00b27
...@@ -66,6 +66,12 @@ ...@@ -66,6 +66,12 @@
console.log('App Show', options); console.log('App Show', options);
// 每次进应用显示时检查用户状态 // 每次进应用显示时检查用户状态
this.checkUserStatus(); this.checkUserStatus();
// if(options.query.mpCffp){
// uni.setStorageSync('mpCffp',options.query.mpCffp)
// }else{
// uni.removeStorageSync('mpCffp')
// }
// App平台从options获取参数 // App平台从options获取参数
// #ifdef APP-PLUS // #ifdef APP-PLUS
if(options && options.query) { if(options && options.query) {
...@@ -162,6 +168,10 @@ ...@@ -162,6 +168,10 @@
// 处理H5平台的URL参数 // 处理H5平台的URL参数
handleH5UrlParams() { handleH5UrlParams() {
const url = window.location.href; const url = window.location.href;
if(uni.getStorageSync('mpCffp')){
uni.removeStorageSync('mpCffp')
}
if(url.indexOf('?') > -1) { if(url.indexOf('?') > -1) {
const queryString = url.split('?')[1]; const queryString = url.split('?')[1];
const params = this.parseQueryString(queryString); const params = this.parseQueryString(queryString);
...@@ -234,8 +244,10 @@ ...@@ -234,8 +244,10 @@
if(params.addSystemType){ if(params.addSystemType){
uni.setStorageSync('addSystemType', params.addSystemType); uni.setStorageSync('addSystemType', params.addSystemType);
} }
// // 可以在这里添加事件通知其他页面参数已准备好 // 家办商城跳转,分享带参
// uni.$emit('externalParamsReady', params); if(params.mpCffp){
uni.setStorageSync('mpCffp',params.mpCffp)
}
} catch(e) { } catch(e) {
console.error('存储外部链接参数失败:', e); console.error('存储外部链接参数失败:', e);
} }
......
import request from "../util/request"; import request from "../util/request";
import {baseURL,apiURL,cffpURL,sfpUrl} from "../environments/environment"; import {baseURL,apiURL,cffpURL,sfpUrl,imgUrl,scrmUrl} from "../environments/environment";
export default { export default {
//查看token是否已经失效 //查看token是否已经失效
...@@ -416,4 +416,12 @@ export default { ...@@ -416,4 +416,12 @@ export default {
pocessTracking(params) { pocessTracking(params) {
return request(`${sfpUrl}/sfp/sfpMain/pocessTracking`, 'POST', params) return request(`${sfpUrl}/sfp/sfpMain/pocessTracking`, 'POST', params)
}, },
//修改备注
editRemarkName(params) {
return request(`${cffpURL}/orgInfo/editRemarkName`, 'POST', params)
},
//提现记录
withdrawalList(params) {
return request(`${scrmUrl}/scrm-api/agCffpUserFortune/withdrawal/list`, 'POST', params)
},
} }
<template>
<view class="multi-select-dropdown">
<!-- 触发按钮 -->
<view class="dropdown-trigger" @click.stop="toggleDropdown">
<slot name="trigger" :selectedItems="selectedItems">
<text class="trigger-text">{{ displayText }}</text>
<text class="iconfont icon-arrow-down" :class="{ 'rotate': isOpen }"></text>
</slot>
</view>
<!-- 遮罩层 -->
<view class="dropdown-mask" v-show="isOpen" @click.stop="closeDropdown"></view>
<!-- 下拉内容 - 修改为底部弹出 -->
<view class="dropdown-content bottom-popup" v-show="isOpen">
<!-- 搜索框(可选) -->
<view class="search-box" v-if="searchable">
<input
class="search-input"
placeholder="搜索"
v-model="searchText"
@input="handleSearch"
/>
</view>
<!-- 选项列表 -->
<scroll-view scroll-y class="options-list">
<view
class="option-item"
v-for="item in filteredOptions"
:key="item[valueKey]"
@click.stop="toggleOption(item)"
>
<view class="checkbox" :class="{ 'checked': isSelected(item) }"></view>
<text class="option-label">{{ item[labelKey] }}</text>
</view>
</scroll-view>
<!-- 操作按钮 -->
<view class="action-buttons">
<view class="button reset" @click.stop="closeDropdown">取消</view>
<view class="button confirm" @click.stop="confirmSelection">确定</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'MultiSelectDropdown',
props: {
// 选项列表
options: {
type: Array,
default: () => []
},
// 已选中的值
value: {
type: Array,
default: () => []
},
// 选项文本的key
labelKey: {
type: String,
default: 'label'
},
// 选项值的key
valueKey: {
type: String,
default: 'value'
},
// 占位文本
placeholder: {
type: String,
default: '请选择'
},
// 是否可搜索
searchable: {
type: Boolean,
default: false
},
// 最大选择数量
maxSelect: {
type: Number,
default: null
}
},
data() {
return {
isOpen: false,
selectedItems: [...this.value],
searchText: '',
filteredOptions: []
}
},
computed: {
displayText() {
if (this.selectedItems.length === 0) {
return this.placeholder
}
if (this.selectedItems.length === this.options.length) {
return '已选择全部'
}
// 显示选中的前2项,超过则显示数量
const selectedLabels = this.options
.filter(option => this.selectedItems.includes(option[this.valueKey]))
.map(option => option[this.labelKey])
if (selectedLabels.length <= 2) {
return selectedLabels.join('、')
} else {
return `已选择${selectedLabels.length}项`
}
}
},
watch: {
options: {
immediate: true,
handler(newVal) {
this.filteredOptions = [...newVal]
}
},
value(newVal) {
this.selectedItems = [...newVal]
console.log('this.selectedItems',this.selectedItems);
}
},
methods: {
toggleDropdown() {
if (this.isOpen) {
this.closeDropdown()
} else {
this.openDropdown()
}
},
openDropdown() {
this.isOpen = true
this.selectedItems = [...this.value]
// 禁止页面滚动
document.body.style.overflow = 'hidden'
},
closeDropdown() {
console.log('this.selectedItems',this.selectedItems);
this.isOpen = false
this.searchText = ''
this.filteredOptions = [...this.options]
// if(this.selectedItems.includes('-1')){
// this.selectedItems = []
// console.log(' this.selectedItems', this.selectedItems);
// }
// 恢复页面滚动
document.body.style.overflow = ''
},
toggleOption(item) {
const value = item[this.valueKey]
const index = this.selectedItems.indexOf(value)
if (value === '-1') { // 处理"全部"选项
if (index === -1) {
// 选中全部
this.selectedItems = this.options.map(option => option[this.valueKey])
} else {
// 取消选中全部
this.selectedItems = []
}
return
}
if (index === -1) {
// 检查是否超过最大选择数量
if (this.maxSelect && this.selectedItems.length >= this.maxSelect) {
uni.showToast({
title: `最多选择${this.maxSelect}项`,
icon: 'none'
})
return
}
this.selectedItems.push(value)
// 如果选中了所有非"全部"选项,自动选中"全部"
const allNonAllOptions = this.options
.filter(option => option[this.valueKey] !== '-1')
.map(option => option[this.valueKey])
const allSelected = allNonAllOptions.every(val => this.selectedItems.includes(val))
if (allSelected && this.options.some(opt => opt[this.valueKey] === '-1')) {
this.selectedItems.push('-1')
}
} else {
this.selectedItems.splice(index, 1)
// 如果取消选中了任意选项,确保取消选中"全部"
const allIndex = this.selectedItems.indexOf('-1')
if (allIndex !== -1) {
this.selectedItems.splice(allIndex, 1)
}
}
},
isSelected(item) {
if (item[this.valueKey] === '-1') {
// 对于"全部"选项,检查是否所有非"全部"选项都被选中
const allNonAllOptions = this.options
.filter(option => option[this.valueKey] !== '-1')
.map(option => option[this.valueKey])
return allNonAllOptions.length > 0 &&
allNonAllOptions.every(val => this.selectedItems.includes(val))
}
return this.selectedItems.includes(item[this.valueKey])
},
handleSearch() {
if (!this.searchText) {
this.filteredOptions = [...this.options]
return
}
this.filteredOptions = this.options.filter(option =>
option[this.labelKey].toLowerCase().includes(this.searchText.toLowerCase())
)
},
resetSelection() {
this.selectedItems = []
// this.closeDropdown()
},
confirmSelection() {
this.$emit('input', [...this.selectedItems])
this.$emit('change', [...this.selectedItems])
this.closeDropdown()
}
}
}
</script>
<style lang="scss" scoped>
.multi-select-dropdown {
position: relative;
display: inline-block;
.dropdown-trigger {
display: flex;
align-items: center;
padding: 0 20rpx;
height: 60rpx;
border-radius: 8rpx;
box-sizing: border-box;
.trigger-text {
font-size: 28rpx;
color: #333;
margin-right: 10rpx;
max-width: 200rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.icon-arrow-down {
font-size: 24rpx;
color: #666;
transition: transform 0.3s;
&.rotate {
transform: rotate(180deg);
}
}
}
.dropdown-content {
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;
&.bottom-popup {
transform: translateY(0);
}
.search-box {
padding: 20rpx;
border-bottom: 1rpx solid #eee;
.search-input {
width: 100%;
height: 60rpx;
padding: 0 20rpx;
background-color: #f5f5f5;
border-radius: 8rpx;
font-size: 26rpx;
}
}
.options-list {
max-height: 60vh;
padding: 10rpx 0;
.option-item {
display: flex;
align-items: center;
padding: 20rpx;
&:active {
background-color: #f5f5f5;
}
.checkbox {
width: 30rpx;
height: 30rpx;
border: 2rpx solid #ccc;
border-radius: 4rpx;
margin-right: 15rpx;
position: relative;
&.checked {
background-color: #2A36AD;
border-color: #2A36AD;
&::after {
content: '';
position: absolute;
left: 8rpx;
top: 3rpx;
width: 12rpx;
height: 18rpx;
border: solid white;
border-width: 0 2rpx 2rpx 0;
transform: rotate(45deg);
}
}
}
.option-label {
font-size: 28rpx;
color: #333;
}
}
}
.action-buttons {
display: flex;
justify-content: space-between;
padding: 20rpx;
border-top: 1rpx solid #eee;
.button {
width: 30%;
height: 60rpx;
line-height: 60rpx;
text-align: center;
border-radius: 60rpx;
font-size: 28rpx;
padding: 20rpx ;
&.reset {
// margin-right: 20rpx;
color: #666;
border: 1rpx solid #666;
}
&.confirm {
background-color: #2A36AD;
color: #fff;
}
}
}
}
.dropdown-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 100;
}
}
</style>
\ No newline at end of file
<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
<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
...@@ -62,11 +62,8 @@ ...@@ -62,11 +62,8 @@
} }
}); });
} else if (item.isJump) { } else if (item.isJump) {
console.log('333333',item)
this.$refs.restrictedOrCanelTip.open() this.$refs.restrictedOrCanelTip.open()
// uni.navigateTo({
// url: item.link
// });
return return
}else if (item.link != null) { }else if (item.link != null) {
uni.navigateTo({ uni.navigateTo({
......
...@@ -6,14 +6,16 @@ const dev = { ...@@ -6,14 +6,16 @@ const dev = {
cffp_url:'https://mdev.anjibao.cn/cffpApi/cffp', cffp_url:'https://mdev.anjibao.cn/cffpApi/cffp',
share_url:'https://mdev.anjibao.cn/cffp', share_url:'https://mdev.anjibao.cn/cffp',
sfp_url:'https://mdev.anjibao.cn/sfpApi', sfp_url:'https://mdev.anjibao.cn/sfpApi',
img_url:'https://mdev.zuihuibi.cn' img_url:'https://mdev.zuihuibi.cn',
scrm_url:'https://mdev.zuihuibi.cn'
} }
const stage = { const stage = {
base_url:'https://mstage.zuihuibi.cn', base_url:'https://mstage.zuihuibi.cn',
api_url:'https://mstage.zuihuibi.cn/cffpApi', api_url:'https://mstage.zuihuibi.cn/cffpApi',
cffp_url:'https://mstage.zuihuibi.cn/cffpApi/cffp', cffp_url:'https://mstage.zuihuibi.cn/cffpApi/cffp',
share_url:'https://mstage.zuihuibi.cn/cffp', share_url:'https://mstage.zuihuibi.cn/cffp',
sfp_url:'https://mstage.zuihuibi.cn/sfpApi' sfp_url:'https://mstage.zuihuibi.cn/sfpApi',
scrm_url:'https://mstage.zuihuibi.cn'
} }
const prod = { const prod = {
...@@ -22,7 +24,8 @@ const prod = { ...@@ -22,7 +24,8 @@ const prod = {
cffp_url:'https://app.ydhomeoffice.cn/appApi/cffp', cffp_url:'https://app.ydhomeoffice.cn/appApi/cffp',
share_url:'https://app.ydhomeoffice.cn/appYdhomeoffice', share_url:'https://app.ydhomeoffice.cn/appYdhomeoffice',
sfp_url:'https://hoservice.ydhomeoffice.cn/hoserviceApi', sfp_url:'https://hoservice.ydhomeoffice.cn/hoserviceApi',
img_url:'https://app.ydhomeoffice.cn' img_url:'https://app.ydhomeoffice.cn',
scrm_url:'https://m.zuihuibi.cn'
} }
// companyType: '1', cffp // companyType: '1', cffp
// companyType: '2', appYdhomeoffice // companyType: '2', appYdhomeoffice
...@@ -54,6 +57,7 @@ let cffpURL = config[env].cffp_url; ...@@ -54,6 +57,7 @@ let cffpURL = config[env].cffp_url;
let shareURL = config[env].share_url; let shareURL = config[env].share_url;
let sfpUrl = config[env].sfp_url; let sfpUrl = config[env].sfp_url;
let imgUrl = config[env].img_url; let imgUrl = config[env].img_url;
let scrmUrl = config[env].scrm_url;
export{ export{
baseURL, baseURL,
...@@ -63,5 +67,6 @@ export{ ...@@ -63,5 +67,6 @@ export{
shareURL, shareURL,
sfpUrl, sfpUrl,
env, env,
imgUrl imgUrl,
scrmUrl
} }
\ No newline at end of file
...@@ -8,19 +8,35 @@ ...@@ -8,19 +8,35 @@
document.write( document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + '<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' : '') + '" />') (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> </script>
<title>银盾家办</title> <title>银盾家办</title>
<link rel="stylesheet" href="./static/font/iconfont.css"> <link rel="stylesheet" href="./static/font/iconfont.css">
<link rel="shortcut icon" href="./static/iconLong.png"> <link rel="shortcut icon" href="./static/iconLong.png">
<!-- <link rel="shortcut icon" href="./static/icon.png"> -->
<!--preload-links--> <script src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
<!--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> -->
</head> </head>
<body> <body>
<div id="app"> <div id="app">
......
...@@ -57,13 +57,13 @@ ...@@ -57,13 +57,13 @@
<view <view
:class="{'grey':disabledSendBtn}" :class="{'grey':disabledSendBtn}"
@click="sendMessage()" @click="sendMessage()"
v-if="loginType=== 'visitor'" v-if="showVerificationCode"
> >
{{sendCodeHtml}} {{sendCodeHtml}}
</view> </view>
</view> </view>
</view> </view>
<view class="inputBox" v-if="loginType=== 'visitor'"> <view class="inputBox" v-if="showVerificationCode">
<view class="txt"> <view class="txt">
<text class="require">*</text>验证码 <text class="require">*</text>验证码
</view> </view>
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
timer:null, timer:null,
remainTimes:60, remainTimes:60,
loginType:uni.getStorageSync('loginType'), loginType:uni.getStorageSync('loginType'),
userInfo:{}, userInfo:'',
userId: uni.getStorageSync('cffp_userId'),//本人id, userId: uni.getStorageSync('cffp_userId'),//本人id,
InviteeUserId:'',//被邀请人id InviteeUserId:'',//被邀请人id
inviteUserId:'',//邀请人id, inviteUserId:'',//邀请人id,
...@@ -159,9 +159,13 @@ ...@@ -159,9 +159,13 @@
showCode:false ,//弹窗是否展示客服二维码 showCode:false ,//弹窗是否展示客服二维码
restrictedOrCanelContent:'', //禁用/注销展示文本 restrictedOrCanelContent:'', //禁用/注销展示文本
sharePosterObj:{invitationCode:'',inviteUserId:''},//通过分享海报进来 sharePosterObj:{invitationCode:'',inviteUserId:''},//通过分享海报进来
showVerificationCode:false,//验证码是否展示
} }
}, },
onLoad(options){ onLoad(options){
if(uni.getStorageSync('loginType')){
this.loginType = uni.getStorageSync('loginType')
}
this.inviteUserId = '' this.inviteUserId = ''
if(options.inviteUserId){ if(options.inviteUserId){
this.inviteUserId = options.inviteUserId this.inviteUserId = options.inviteUserId
...@@ -174,7 +178,7 @@ ...@@ -174,7 +178,7 @@
this.shareId = options.shareId this.shareId = options.shareId
this.getqueryById(options.shareId) this.getqueryById(options.shareId)
// uni.clearStorageSync() // uni.clearStorageSync()
uni.setStorageSync('loginType', 'visitor') // uni.setStorageSync('loginType', 'visitor')
} }
}, },
...@@ -186,7 +190,6 @@ ...@@ -186,7 +190,6 @@
if(uni.getStorageSync('cffp_userInfo')){ if(uni.getStorageSync('cffp_userInfo')){
this.userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo')) this.userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo'))
} }
console.log('show',this.userInfo)
if(uni.getStorageSync('cffp_userId')){ if(uni.getStorageSync('cffp_userId')){
this.userId = uni.getStorageSync('cffp_userId') this.userId = uni.getStorageSync('cffp_userId')
} }
...@@ -198,18 +201,21 @@ ...@@ -198,18 +201,21 @@
if(!this.shareId&&this.loginType == 'codelogin'&&this.userInfo.mobile){ if(!this.shareId&&this.loginType == 'codelogin'&&this.userInfo.mobile){
this.form.mobile = this.userInfo.mobile this.form.mobile = this.userInfo.mobile
this.editMobile = true this.editMobile = true
this.showVerificationCode = false
} }
// 非邀请状态 // 非邀请状态
if(!this.shareId&&this.loginType == 'codelogin'&&!this.form.nickName){ if(!this.shareId&&this.loginType == 'codelogin'&&!this.form.nickName){
this.queryInfo() this.queryInfo()
} }
// 登录状态 // 登录状态 非邀请
if(this.loginType == 'codelogin'){ if(this.loginType == 'codelogin' && !this.shareId){
// #ifdef H5 // #ifdef H5
initJssdkShare(() => { initJssdkShare(() => {
setWechatShare(); setWechatShare();
}, window.location.href); }, window.location.href);
// #endif // #endif
}else {
this.showVerificationCode = true
} }
}, },
...@@ -238,11 +244,25 @@ ...@@ -238,11 +244,25 @@
}) })
}, },
getqueryById(shareId){ getqueryById(shareId){
api.queryById({id:shareId}).then(res =>{ api.queryById({id:shareId}).then(res =>{
console.log('res.data.data',res.data.data);
this.form.nickName = res.data.data.name this.form.nickName = res.data.data.name
this.form.mobile = res.data.data.mobileNumber this.form.mobile = res.data.data.mobileNumber
this.editNickName = this.editMobile = true this.editNickName = this.editMobile = true
if(res.data.data.isPartner){ // 手机号一致的没做判断,以后可能要做判断
// if(this.userInfo&&(this.userInfo.mobile !==this.form.mobile )){
// this.showVerificationCode = true
// uni.setStorageSync('loginType', 'visitor')
// return
// }
// 之前登录过,但和申请加盟的账号不一致
if(this.userInfo&&(this.userInfo.mobile !==this.form.mobile )){
this.showVerificationCode = true
uni.setStorageSync('loginType', 'visitor')
return
}
if(res.data.data.isPartner&& this.loginType == 'codelogin'){
this.$refs.successJoinPopup.open() this.$refs.successJoinPopup.open()
} }
}) })
...@@ -427,6 +447,7 @@ ...@@ -427,6 +447,7 @@
...res.data ...res.data
} }
uni.setStorageSync('cffp_userInfo', JSON.stringify(cffp_userInfo)) uni.setStorageSync('cffp_userInfo', JSON.stringify(cffp_userInfo))
uni.setStorageSync('user_mobile', cffp_userInfo.mobile)
}else { }else {
uni.setStorageSync('loginType', 'visitor') uni.setStorageSync('loginType', 'visitor')
...@@ -478,11 +499,7 @@ ...@@ -478,11 +499,7 @@
this.showCode = false this.showCode = false
this.restrictedOrCanelContent = res['message'] this.restrictedOrCanelContent = res['message']
this.$refs.restrictedOrCanelTip.open() this.$refs.restrictedOrCanelTip.open()
// uni.showToast({
// title: res['message'],
// duration: 2000,
// icon: 'none'
// })
} }
}) })
}, },
......
...@@ -6,18 +6,212 @@ ...@@ -6,18 +6,212 @@
<text style="font-size: 30rpx;">提现记录</text> <text style="font-size: 30rpx;">提现记录</text>
</view> </view>
<!-- #endif --> <!-- #endif -->
<view class="backArrow"> <view class="content">
<text class="iconfont icon-youjiantou zuojiantou" style="left: 5rpx;" @click="goBack()"></text> <view style="flex: 1;">
<text style="font-size: 30rpx;">提现记录</text> <view class="totalBox" :style="{justifyContent:showTotal?'space-between':'flex-end'}">
<view class="left" v-if="showTotal">
<text class="totalTxt">总金额:</text>
<text class="totalNum">{{dataObj.totalAmount}}</text>
<view class="des">
(不包含已拒绝记录)
</view>
</view>
<view class="right" >
<multi-select-dropdown
:options="statusOptions"
:value="selectedStatus"
labelKey="label"
valueKey="value"
placeholder="提现状态"
@change="handleStatusChange"
>
<template #trigger="{ selectedItems }">
<text class="filterTxt">{{selectedTxt}}</text>
<text class="iconfont icon-shaixuan"></text>
</template>
</multi-select-dropdown>
</view>
</view>
<view class="recordBox" v-if="dataObj.withdrawalVOList.length>0">
<view class="itemBox" v-for="item in dataObj.withdrawalVOList" :key="item.id">
<view class="left">
<text v-if="item.paidMethod == 2" class="iconfont icon-zhifubao2"></text>
<text v-if="item.paidMethod == 1" class="iconfont icon-weixin"></text>
</view>
<view class="right">
<view class="top">
<text class="tixian">提现时间:<text>{{item.exchangeDate}}</text> </text>
<text class="money">¥{{item.exchangeAmount}}</text>
</view>
<view class="bottom" :style="{justifyContent:item.status=='0'?'flex-end':'space-between'}">
<text v-show="item.status=='1'" class="daozhang">到账时间:<text>{{item.paidDate}}</text> </text>
<view v-show="item.status=='3'" class="daozhang ">拒绝理由:<text class="refuse-reason">{{item.reviewMessage}}</text> </view>
<text class="pay" >
{{
item.status=='0'?'审核中'
:item.status=='1'?'已到账'
:item.status=='3'?'已拒绝':'--'
}}
</text>
</view>
</view>
</view> </view>
</view> </view>
<view class="empty" v-else>
暂无数据
</view>
</view>
<view class="btnBottom" @click="gotoKefu">
<view class="myBtn">
咨询客服
</view>
</view>
</view>
</view>
</template> </template>
<script> <script>
import dataHandling from "@/util/dataHandling";
import api from "@/api/api";
import { initJssdkShare, setWechatShare } from '@/util/fiveshare';
import {companyInfo} from "@/environments/environment";
import MultiSelectDropdown from '@/components/commonPopup/MultiSelectDropdown.vue'
export default {
components: {
MultiSelectDropdown
},
data() {
return {
dataObj:{withdrawalVOList:[],totalAmount:'0.00'},
statusOptions: [
{ label: '全部', value: '-1' },
{ label: '审核中', value: '0' },
{ label: '已到账', value: '1' },
{ label: '已拒绝', value: '3' }
],
selectedStatus: [],
selectedTxt:'提现状态',
showTotal:true
}
},
onLoad(options){
},
onShow() {
// #ifdef H5
initJssdkShare(() => {
setWechatShare();
}, window.location.href);
// #endif
this.selectedStatus = []
this.selectedTxt = '提现状态'
this.showTotal = true
this.getWithdrawalList()
},
methods: {
// 获取团队数据
getWithdrawalList() {
const status = this.selectedStatus.length === 0 || this.selectedStatus.includes('-1')
? []
: this.selectedStatus
api.withdrawalList({
userId: uni.getStorageSync('cffp_userId'),
status: status
}).then(res =>{
if(res['message']=='ok'){
this.dataObj = res.data
if(this.dataObj.withdrawalVOList){
this.dataObj.withdrawalVOList.forEach(item=>{
if(item.exchangeDate){
item.exchangeDate = dataHandling.dateFormat2(item.exchangeDate)
}
if(item.paidDate){
item.paidDate = dataHandling.dateFormat2(item.paidDate)
}
})
}
}else {
uni.showToast({
title: res['message'],
duration: 2000,
icon: 'none'
})
}
})
},
goBack(){
uni.navigateBack({
delta: 1
});
},
// 获取状态显示文本
getStatusText(selectedItems) {
if (selectedItems.length === 0 || selectedItems.includes('-1')) {
return '全部'
}
return this.statusOptions
.filter(item => selectedItems.includes(item.value))
.map(item => item.label)
.join('、')
},
// 状态变化处理 确定按钮
handleStatusChange(status) {
this.selectedTxt = this.getStatusText(status)
this.selectedStatus = status
if(status.length==1&&status.includes('3')){
this.showTotal = false
}else{
this.showTotal = true
}
this.getWithdrawalList()
},
gotoKefu(){
// #ifdef MP-WEIXIN
dataHandling.pocessTracking(
'咨询客服',
`用户咨询客服`,
'点击',
2,
'我的',
'pages/personalCenter/personalCenter'
)
uni.openCustomerServiceChat({
extInfo: {
url: 'https://work.weixin.qq.com/kfid/kfc08c55f4170e7fc9e'
},
corpId: 'ww43cac1cf9dd6a3d0', // 客服会话按钮打开后,在微信客服会话按钮处理的事件类型
showMessageCard: true,
sendMessageTitle: (uni.getStorageSync('hoservice_mobileNo')?(uni.getStorageSync('hoservice_mobileNo')+",") :"" ) + "进入个人中心-->咨询客服",
sendMessagePath: `/pages/index/mySelf.html`,
//sendMessageImg: cardItem.value['list'][0]['itemImg']
});
// #endif
// #ifndef MP-WEIXIN
dataHandling.pocessTracking(
'咨询客服',
`用户咨询客服`,
'点击',
2,
'我的',
'pages/personalCenter/personalCenter'
)
window.open('https://work.weixin.qq.com/kfid/kfc08c55f4170e7fc9e')
// #endif
}
},
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container{ .container{
display: flex;
flex-direction: column;
.backArrow{ .backArrow{
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
...@@ -33,5 +227,159 @@ ...@@ -33,5 +227,159 @@
position: absolute; position: absolute;
} }
} }
.content{
flex: 1;
display: flex;
flex-direction: column;
background-color: #fff;
.totalBox{
background-color: #fff;
padding: 30rpx 20rpx;
display: flex;
justify-content: space-between;
.left{
.totalTxt{
font-size: 30rpx;
font-weight: 600;
color: #383838;
}
.totalNum{
font-size: 30rpx;
color: #FF705D;
}
.des{
color: rgba(187, 189, 193, 1);
font-size: 26rpx;
margin-top: 5rpx;
}
}
.right{
.filterTxt, .icon-shaixuan{
font-size: 28rpx;
color: #383838;
}
.filterTxt {
font-size: 28rpx;
color: #383838;
margin-right: 5rpx;
max-width: 300rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
.icon-shaixuan{
margin-left: 5rpx;
font-size: 32rpx;
}
}
}
.recordBox{
padding: 10rpx;
box-sizing: border-box;
.itemBox{
box-sizing: border-box;
width: 100%;
padding: 20rpx;
background-color: #fff;
border-radius: 10rpx;
display: flex;
justify-content: flex-start;
margin-top: 20rpx;
box-shadow: 0rpx 12rpx 24rpx rgba(12, 57, 193, 0.05);
.left{
width: 50rpx;
margin-right: 10rpx;
background: #F7F8F9;
padding: 20rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10rpx;
.icon-zhifubao2{
color: #00A1E8;
font-size: 40rpx;
}
.icon-weixin{
color: #41C740;
font-size: 40rpx;
}
}
.right{
width: calc(100% - 50rpx);
.top,.bottom{
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.top{
.tixian{
font-size: 28rpx;
color: #383838;
}
.money{
font-size: 30rpx;
color: #FF705D;
}
}
.bottom{
margin-top: 3rpx;
.daozhang{
color: rgba(187, 189, 193, 1);
font-size: 26rpx;
display: flex;
align-items: center;
.refuse-reason {
width: 350rpx; /* 根据需要调整 */
display: inline-block; /* 或者 block */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap !important;
flex-shrink: 1; /* 允许缩小 */
}
}
.pay{
color: #2A36AD;
font-size: 28rpx;
flex-shrink: 0; /* 禁止缩小 */
}
}
}
}
// .itemBox:last-child{
// margin-top: 0rpx;
// }
}
.empty{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
color:#666;
font-size: 28rpx;
margin-top: 50rpx;
}
.btnBottom{
width: 100%;
padding-bottom: 40rpx;
display: flex;
align-items: center;
justify-content: center;
.myBtn{
background: rgba(32, 38, 155, 1);
font-size: 30rpx;
color: #fff;
text-align: center;
padding: 20rpx 100rpx;
border-radius: 80rpx;
}
}
}
} }
</style> </style>
\ No newline at end of file
...@@ -56,6 +56,92 @@ ...@@ -56,6 +56,92 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 团队相关的 -->
<view class="teamBox" v-if="currentBtn == '1' && loginType == 'codelogin'">
<view class="teamHeader">
<view class="oneHeader" v-if="!showTeamTab">
<text class="self">我的团队</text>
<text class="duiyuan">{{myTeamData.teamInfoVO.count}}位队员(包括您)</text>
</view>
<view class="twoHeader" v-if="showTeamTab">
<view class="teamTabBox" >
<scroll-view class="scroll-view_H" scroll-x="true" scroll-left="120">
<view
class="scroll-view-item_H"
v-for="item in myTeamTabList"
:key="item.orgInfoId"
@click="changeTeamTab(item)"
>
<text class="iconfont icon-jiantou2" v-if="item.icon"></text>
<text>{{item.name}}</text>
</view>
</scroll-view>
</view>
</view>
</view>
<view class="teamPeople">
<view class="oneLevel">
<view class="avatar">
<image :src="myTeamData.teamInfoVO.avatar ? myTeamData.teamInfoVO.avatar :companyLogo" mode="widthFix"></image>
</view>
<view class="topR">
<view class="top">
<text class="mySelfName">{{myTeamData.teamInfoVO.remarkName}}</text>
<view class="position">
团队长
</view>
<view class="leavelName" style="margin-right: 15rpx;">
{{myTeamData.teamInfoVO.levelName}}
</view>
<view class="leavelName" v-if="myTeamData.teamInfoVO.level == 1">
</view>
</view>
<view class="bottom" v-if="myTeamData.teamInfoVO.realName">
<text>实名:</text>
<text >{{myTeamData.teamInfoVO.realName}}</text>
</view>
</view>
</view>
<view v-if="myTeamData.teamInfoVO.subList">
<view class="twoLevel" v-for="child in myTeamData.teamInfoVO.subList" :key="child.orgInfoId">
<view class="left">
<view class="line" >
<view class="box"></view>
</view>
<view class="peopleInfo">
<view class="twoAvatar">
<image :src="child.avatar ? child.avatar :companyLogo" mode="widthFix"></image>
</view>
<view class="leftR">
<view class="top" @click="updateRmarkName(child)">
<text class="nickName">{{child.remarkName}}</text>
<text class="iconfont icon-xiugai" ></text>
<view class="nameLevel">{{child.levelName}}</view>
</view>
<view class="bottom" v-if="child.realName">
<text>实名:</text>
<text >{{child.realName}}</text>
</view>
</view>
</view>
</view>
<view class="right" v-if="child.subList" @click="lookData(child)">
<text class="rNum">{{child.count}}</text>
<text class="iconfont icon-jiantou2" ></text>
</view>
</view>
</view>
</view>
</view>
<view class="emptyTxt" v-if="currentBtn == '1' && (!loginType||loginType == 'visitor')">
暂无数据
</view>
<!-- 业绩相关的 -->
<view <view
v-if="currentBtn == '2'" v-if="currentBtn == '2'"
class="filterBox" class="filterBox"
...@@ -72,7 +158,11 @@ ...@@ -72,7 +158,11 @@
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view class="filterBox" :style="{marginTop:currentBtn=='1'?'20rpx':''}"> <view
class="filterBox"
v-if="currentBtn == '2'"
:style="{marginTop:currentBtn=='1'?'20rpx':''}"
>
<scroll-view class="scroll-view_H" scroll-x="true" scroll-left="120"> <scroll-view class="scroll-view_H" scroll-x="true" scroll-left="120">
<view <view
class="scroll-view-item_H" class="scroll-view-item_H"
...@@ -85,24 +175,14 @@ ...@@ -85,24 +175,14 @@
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view class="tableBox"> <view class="tableBox" v-if="currentBtn == '2'" >
<view class="table"> <view class="table">
<view class="content-box"> <view class="content-box">
<view class="content-box-title" v-for="(item,index) in tableHeaderList" :key="index"> <view class="content-box-title" v-for="(item,index) in tableHeaderList" :key="index">
<text class="title">{{item.title}}</text> <text class="title">{{item.title}}</text>
</view> </view>
</view> </view>
<view v-if="currentBtn == '2'&&currentFilterBtn!=='3'&& myTeamAchievementList.length>0">
<!-- 之前的做法 -->
<view v-if="currentBtn == '1'&&myTeamList.length>0">
<view class="content-sam-box" v-for="(pointItem,index) in myTeamList" :key="index">
<span class="content-box-title cell">{{pointItem.parentName}}</span>
<span class="content-box-title cell">{{pointItem.name}}</span>
<span class="content-box-title cell">{{pointItem.levelName}}</span>
<span class="content-box-title cell">{{pointItem.referrer}}</span>
</view>
</view>
<view v-else-if="currentBtn == '2'&&currentFilterBtn!=='3'&& myTeamAchievementList.length>0">
<view class="content-sam-box" v-for="(pointItem,index) in myTeamAchievementList" :key="index"> <view class="content-sam-box" v-for="(pointItem,index) in myTeamAchievementList" :key="index">
<span class="content-box-title cell">{{pointItem.name}}</span> <span class="content-box-title cell">{{pointItem.name}}</span>
<span class="content-box-title cell">{{pointItem.orderNum}}</span> <span class="content-box-title cell">{{pointItem.orderNum}}</span>
...@@ -131,6 +211,40 @@ ...@@ -131,6 +211,40 @@
@afterLogin="afterLogin" @afterLogin="afterLogin"
pageSource="myTeam" pageSource="myTeam"
></boot-page> ></boot-page>
<uni-popup ref="updatePop" type="center" background-color="#fff">
<view class="updateCon">
<view class="top">
<view class="title">
修改【{{updateItem.name}}】备注
</view>
<view class="inputBox">
<input
class="userInput"
v-model="remarkName"
maxlength="10"
type="text"
placeholder="请输入2~10个字符"
/>
<!-- v-if="updateItem.realName" -->
<view
v-if="updateItem.realName"
class="useReal"
@click="remarkName=updateItem.realName"
>
使用实名
</view>
</view>
</view>
<view class="bottomBtn">
<view class="left" @click="cancel">
取消
</view>
<view class="right" @click="confirmRemarkName">
确定
</view>
</view>
</view>
</uni-popup>
</view> </view>
</template> </template>
...@@ -140,6 +254,7 @@ ...@@ -140,6 +254,7 @@
import api from "@/api/api"; import api from "@/api/api";
import { initJssdkShare, setWechatShare } from '@/util/fiveshare'; import { initJssdkShare, setWechatShare } from '@/util/fiveshare';
import BootPage from "@/components/bootpage/bootpage.vue"; import BootPage from "@/components/bootpage/bootpage.vue";
import {companyInfo} from "@/environments/environment";
export default { export default {
components: { components: {
CommonTimePicker, CommonTimePicker,
...@@ -174,7 +289,13 @@ ...@@ -174,7 +289,13 @@
otherList: null, // 直辖团队 otherList: null, // 直辖团队
directList: null, //所辖团队数组 directList: null, //所辖团队数组
myTeamList:[],//我的团队表格数据, myTeamList:[],//我的团队表格数据,
myTeamData:{},//我的团队总数据, myTeamData:{
teamInfoVO:{
count:0,
subList:[],
avatar:''
}
},//我的团队总数据,
CffpOrgInfoReqVO: { CffpOrgInfoReqVO: {
startDate: `${new Date().getFullYear()}-${new Date().getMonth() + 1 > 9 ? new Date().getMonth() + 1 : '0'+ (new Date().getMonth() + 1)}`, startDate: `${new Date().getFullYear()}-${new Date().getMonth() + 1 > 9 ? new Date().getMonth() + 1 : '0'+ (new Date().getMonth() + 1)}`,
endDate: `${new Date().getFullYear()}-${new Date().getMonth() + 1 > 9 ? new Date().getMonth() + 1 : '0'+ (new Date().getMonth() + 1)}`, endDate: `${new Date().getFullYear()}-${new Date().getMonth() + 1 > 9 ? new Date().getMonth() + 1 : '0'+ (new Date().getMonth() + 1)}`,
...@@ -188,6 +309,16 @@ ...@@ -188,6 +309,16 @@
myTeamAchievementList:[],//我的业绩数据列表, myTeamAchievementList:[],//我的业绩数据列表,
marginTop:'30rpx', marginTop:'30rpx',
sharelogin: false, sharelogin: false,
companyType : companyInfo.companyType,
companyLogo : '../../static/logo2.png',
showTeam:false,
updateItem:{},
remarkName:'',//修改备注名称
oldMyTeamData:{},//我的团队旧值
myTeamTabList:[],
showTeamTab:false,//我的团队tab开关
currentTeam : {},
loginType:''
} }
}, },
watch: { watch: {
...@@ -195,16 +326,11 @@ ...@@ -195,16 +326,11 @@
deep: true, deep: true,
handler(newVal) { handler(newVal) {
if(newVal == '1') { if(newVal == '1') {
this.tableHeaderList = [ this.showTeamTab = false
{title:'上级',id:'1'},
{title:'成员',id:'2'},
{title:'职级',id:'3'},
{title:'关系',id:'4'},
]
// #ifdef H5 // #ifdef H5
this.marginTop = '30rpx' this.marginTop = '30rpx'
// #endif // #endif
this.getmyseatem() this.getmyseatem('1')
return return
} }
if(newVal == '2') { if(newVal == '2') {
...@@ -273,11 +399,16 @@ ...@@ -273,11 +399,16 @@
}, },
}, },
onLoad(options){ onLoad(options){
if(this.companyType == '1'){
this.companyLogo='../../static/myteam/Group1633.png';
}else if(this.companyType == '2'){
this.companyLogo='../../static/logo2.png';
}
// 未登录,弹出登录框 // 未登录,弹出登录框
if(options.myTeam&&(!uni.getStorageSync('loginType')||uni.getStorageSync('loginType')=='visitor' )){ if(options.myTeam&&(!uni.getStorageSync('loginType')||uni.getStorageSync('loginType')=='visitor' )){
this.sharelogin = true this.sharelogin = true
}else { }else {
this.getmyseatem() this.getmyseatem('1')
this.getqueryTeamAchievement() this.getqueryTeamAchievement()
} }
...@@ -288,9 +419,10 @@ ...@@ -288,9 +419,10 @@
setWechatShare(); setWechatShare();
}, window.location.href); }, window.location.href);
// #endif // #endif
this.currentBtn = '1'
this.loginType = uni.getStorageSync('loginType')
}, },
methods: { methods: {
sortswitch(obj) { sortswitch(obj) {
this.currentFilterBtn = obj.id this.currentFilterBtn = obj.id
this.CffpOrgInfoReqVO.sortType = obj.sortType this.CffpOrgInfoReqVO.sortType = obj.sortType
...@@ -332,24 +464,45 @@ ...@@ -332,24 +464,45 @@
}) })
}, },
// 获取团队数据 // 获取团队数据
getmyseatem() { getmyseatem(add = '1') {
// 1,代表刚进页面,2,代表修改了备注
this.myTeamList = [] this.myTeamList = []
api.queryMyTeamInfo({ api.queryMyTeamInfo({
userId: this.userId, userId: this.userId,
type: '1' type: '3'
}).then(res =>{ }).then(res =>{
if(res['success']){ if(res['success']){
delete res.data.commonResult
let data = res.data let data = res.data
this.myTeamData = res.data
if(data.orgInfo) { if(data.teamCount) {
this.teamCount = data.orgInfo.count this.teamCount = data.teamCount
}
if(data.teamInfoVO.name){
const remarkName = data.teamInfoVO.name ?
(data.teamInfoVO.name.length > 3 ?data.teamInfoVO.name.substring(0, 3) + '...' : data.teamInfoVO.name) :
'';
data.teamInfoVO.remarkName = remarkName
} }
if(data.other && data.other.length != 0 && data.other != null){ if(data.teamInfoVO.subList){
this.myTeamList.push(...data['other']) data.teamInfoVO.subList = this.processData2(res.data.teamInfoVO.subList);
} }
if(data.directList && data.directList.length != 0 && data.directList != null){ // data.teamInfoVO.subList[0].realName = '王玉珍'
this.myTeamList.push( ...data['directList']) this.oldMyTeamData = data.teamInfoVO
if(add=='1'){
this.myTeamData = data
this.currentTeam = data.teamInfoVO
this.myTeamTabList.push({
level:this.myTeamData.teamInfoVO.level,
orgInfoId:this.myTeamData.teamInfoVO.orgInfoId,
name:'我的团队'
})
}else if(add == '2'){
this.myTeamData.teamInfoVO = this.findItemInTree(data.teamInfoVO,this.currentTeam)
} }
this.showTeam = true
}else { }else {
uni.showToast({ uni.showToast({
title: res['message'], title: res['message'],
...@@ -394,9 +547,117 @@ ...@@ -394,9 +547,117 @@
} }
}, },
afterLogin(){ afterLogin(){
this.loginType = uni.getStorageSync('loginType')
this.sharelogin = false
this.userId = uni.getStorageSync('cffp_userId'), this.userId = uni.getStorageSync('cffp_userId'),
this.getmyseatem() this.getmyseatem('1')
this.getqueryTeamAchievement() this.getqueryTeamAchievement()
},
updateRmarkName(item){
this.updateItem = JSON.parse(JSON.stringify(item))
console.log('this.updateItem',this.updateItem);
this.$refs.updatePop.open()
},
cancel(){
this.remarkName = ''
this.$refs.updatePop.close()
},
confirmRemarkName(){
if(!this.remarkName){
uni.showToast({
title: '请输入备注',
duration: 2000,
icon: 'none'
})
return
}
api.editRemarkName({
orgInfoId: this.updateItem.orgInfoId,
remarkName: this.remarkName
}).then(res =>{
if(res['success']){
uni.showToast({
title: '备注修改成功',
duration: 2000,
icon: 'none'
})
this.$refs.updatePop.close()
this.remarkName = ''
this.getmyseatem('2')
}else {
uni.showToast({
title: res['message'],
duration: 2000,
icon: 'none'
})
}
})
},
lookData(item){
this.myTeamData.teamInfoVO = this.currentTeam = JSON.parse(JSON.stringify(item))
console.log('this.currentTeam ',this.currentTeam );
this.myTeamTabList.push({
icon:true,
level:this.myTeamData.teamInfoVO.level,
orgInfoId:this.myTeamData.teamInfoVO.orgInfoId,
name:this.myTeamData.teamInfoVO.realName?this.myTeamData.teamInfoVO.realName:this.myTeamData.teamInfoVO.name
})
this.showTeamTab = true
},
processData2(data) {
return data.map(item => {
// 创建 remarkName
const remarkName = item.name ?
(item.name.length > 3 ? item.name.substring(0, 3) + '...' : item.name) :
'';
// 创建新对象,保持原数据不变
const processedItem = {
...item,
remarkName
};
// 递归处理子项
if (item.subList && item.subList.length > 0) {
processedItem.subList = this.processData2(item.subList);
}
return processedItem;
});
},
changeTeamTab(item){
console.log('切换',item);
console.log('旧数据',this.oldMyTeamData);
if(item.level == 1){
this.showTeamTab = false
this.myTeamData.teamInfoVO = JSON.parse(JSON.stringify(this.oldMyTeamData))
}else{
this.myTeamData.teamInfoVO = this.findItemInTree(this.oldMyTeamData,item)
}
this.myTeamTabList.forEach((e,index)=>{
if(e.orgInfoId == item.orgInfoId){
this.myTeamTabList.splice(index + 1);
}
})
},
findItemInTree(treeData, target) {
// 检查当前节点是否匹配
if (treeData.orgInfoId === target.orgInfoId ) {
return treeData;
}
// 如果有子节点,递归查找
if (treeData.subList && treeData.subList.length > 0) {
for (let i = 0; i < treeData.subList.length; i++) {
const found = this.findItemInTree(treeData.subList[i], target);
if (found) return found;
}
}
// 没找到返回null
return null;
} }
}, },
...@@ -404,6 +665,10 @@ ...@@ -404,6 +665,10 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep .uni-popup .uni-popup__wrapper{
margin: 0 !important;
border-radius: 10rpx;
}
.container{ .container{
background-color: rgba(235, 239, 247, 1); background-color: rgba(235, 239, 247, 1);
display: flex; display: flex;
...@@ -487,9 +752,304 @@ ...@@ -487,9 +752,304 @@
} }
} }
} }
.teamBox{
margin-top: 10rpx;
.teamHeader{
background-color: #fff;
box-sizing: border-box;
.oneHeader{
padding: 30rpx 20rpx;
box-sizing: border-box;
.self{
font-size: 30rpx;
color: #333333;
}
.duiyuan{
font-size: 26rpx;
color: #ccc;
margin-left: 10rpx;
}
}
.twoHeader{
box-sizing: border-box;
width: 100%;
padding: 40rpx 20rpx 20rpx 20rpx;
.teamTabBox{
box-sizing: border-box;
width: 100%;
background-color: #fff;
// padding: 20rpx 60rpx 0 60rpx;
display: flex;
align-items: center;
justify-content: space-between;
.scroll-view_H {
white-space: nowrap;
width: 100%;
box-sizing: border-box;
}
.scroll-view-item {
text-align: center;
font-size: 36rpx;
}
.scroll-view-item_H {
margin-bottom: 20rpx;
display: inline-block;
margin-right: 5rpx;
text-align: center;
font-size: 28rpx;
color: rgba(46, 38, 29, 1);
&.active{
color: rgba(32, 39, 155, 1);
position: relative;
}
&.active::before{
display: block;
content: "";
position: absolute;
left: 50%;
transform: translate(-50%);
bottom: -3%;
width: 50%;
// height: 1rpx;
border: 1rpx solid rgba(32, 39, 155, 1);
border-radius: 5rpx;
}
.icon-jiantou2{
font-size: 26rpx;
color: #ccc;
margin-right: 5rpx;
}
}
.scroll-view-item_H:last-child{
margin-right: 50rpx;
}
.scrollBtn {
display: inline-block;
margin-right: 20rpx;
text-align: center;
font-size: 27rpx;
padding: 10rpx 20rpx;
color: rgba(46, 38, 29, 1);
&.active{
color: rgba(32, 39, 155, 1);
}
}
.scrollBtn:last-child{
margin-right: 0rpx;
}
.filterItem{
background: #f7f7f7;
font-size: 27rpx;
padding: 10rpx;
color: rgba(46, 38, 29, 1);
border-radius: 8rpx;
&.active{
background: rgba(32, 39, 155, 1);
color: #fff;
}
}
}
}
}
.teamPeople{
background-color: #fff;
padding: 30rpx 20rpx;
margin-top: 20rpx;
box-sizing: border-box;
.oneLevel{
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
box-sizing: border-box;
// .avatar{
// min-width: 150rpx;
// border-radius: 50%;
// overflow: hidden;
// }
.avatar{
flex-grow: 0;
width: 130rpx;
height: 130rpx;
border-radius: 50%;
overflow: hidden;
/* 背景图设置 */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
/* 添加以下属性强制硬件加速 */
transform: translateZ(0);
-webkit-transform: translateZ(0);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
image{
width: 100%;
height: 100%;
object-fit: cover;
/* 同样为图片添加硬件加速 */
transform: translateZ(0);
-webkit-transform: translateZ(0);
border-radius: none !important;
}
}
.topR{
flex: 1;
margin-left: 20rpx;
}
.mySelfName{
font-size: 30rpx;
color: #333333;
}
.position, .leavelName{
padding: 10rpx 15rpx;
border-radius: 5rpx;
border: 1rpx solid #FFBB00;
font-size: 26rpx;
color: #FFBB00;
}
.position{
margin: 0rpx 15rpx;
}
.top{
display: flex;
align-items: center;
justify-content: flex-start;
}
.bottom{
font-size: 24rpx;
color: #808080;
margin-top: 5rpx;
}
}
.twoLevel{
box-sizing: border-box;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 20rpx;
.left{
width: 76%;
display: flex;
align-items: center;
justify-content: flex-start;
.line{
width: 20%;
display: flex;
justify-content: flex-end;
margin-top: -40rpx;
.box{
width: 30rpx;
height: 30rpx;
border-left: 2rpx solid #ccc;
border-bottom: 2rpx solid #ccc;
}
.icon-lujing{
color: #ccc;
font-size: 24rpx;
transform: scaleX(-1); /* 水平翻转 */
display: inline-block; /* 确保 transform 生效 */
}
}
.peopleInfo{
margin-left: 40rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
.twoAvatar{
// width: 80rpx;
// border-radius: 50%;
flex-grow: 0;
width: 80rpx;
height: 80rpx;
border-radius: 50%;
overflow: hidden;
/* 背景图设置 */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
/* 添加以下属性强制硬件加速 */
transform: translateZ(0);
-webkit-transform: translateZ(0);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
image{
width: 100%;
height: 100%;
object-fit: cover;
/* 同样为图片添加硬件加速 */
transform: translateZ(0);
-webkit-transform: translateZ(0);
border-radius: none !important;
}
}
.leftR{
flex: 1;
margin-left: 20rpx;
.top{
display: flex;
align-items: center;
justify-content: flex-start;
.nickName{
font-size: 26rpx;
color: #333333;
}
.icon-xiugai{
font-size: 26rpx;
color: #333333;
margin: 0 15rpx;
}
.nameLevel{
padding: 5rpx 15rpx;
border-radius: 5rpx;
border: 1rpx solid #FFBB00;
font-size: 25rpx;
color: #FFBB00;
}
}
.bottom{
font-size: 24rpx;
color: #808080;
margin-top: 5rpx;
}
}
}
}
.right{
display: flex;
align-items: center;
.rNum{
color: #333333;
font-size: 28rpx;
margin-right: 5rpx;
}
.icon-jiantou2{
color: #ccc;
font-size: 26rpx;
}
}
}
.twoLevel:last-child{
margin-bottom: 0rpx;
}
}
}
.emptyTxt{
width: 100%;
margin-top: 50rpx;
color: #666666;
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: center;
}
.filterBox{ .filterBox{
box-sizing: border-box; box-sizing: border-box;
// margin: 20rpx 0;
width: 100%; width: 100%;
background-color: #fff; background-color: #fff;
padding: 20rpx 60rpx 0 60rpx; padding: 20rpx 60rpx 0 60rpx;
...@@ -617,5 +1177,149 @@ ...@@ -617,5 +1177,149 @@
} }
} }
.updateCon{
width: 500rpx;
.top{
padding: 30rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
box-sizing: border-box;
.title{
color: #333333;
font-size: 30rpx;
}
.inputBox{
box-sizing: border-box;
width: 100%;
background-color: #F2F2F2;
padding: 20rpx 20rpx;
border-radius: 5rpx;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 20rpx;
.userInput{
font-size: 26rpx;
flex: 1;
}
.useReal{
width: 100rpx;
color: #20269B;
font-size: 24rpx;
}
}
}
.bottomBtn{
width: 100%;
border-top: 1rpx solid rgba(0, 0, 0, .2);
display: flex;
align-items: center;
justify-content: space-between;
.left,.right{
width: 50%;
text-align: center;
padding: 30rpx 0rpx;
font-size: 28rpx;
}
.left{
border-right: 1rpx solid rgba(0, 0, 0, .2);
color: #666666;
}
.right{
color: #20269B;
}
}
}
@media (min-width: 768px) {
.teamBox {
.teamPeople{
.twoLevel{
.left{
.line{
width: 5%;
}
}
}
}
}
}
/* iPad mini 竖屏 */
@media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 1) {
.teamBox {
.teamPeople{
.twoLevel{
.left{
.line{
width: 20%;
}
}
}
}
}
}
/* iPad Air 竖屏 */
@media only screen
and (min-device-width: 820px)
and (max-device-width: 1180px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 1) {
.teamBox {
.teamPeople{
.twoLevel{
.left{
.line{
width: 20%;
}
}
}
}
}
}
/* iPad Pro 11-inch 竖屏 */
@media only screen
and (min-device-width: 834px)
and (max-device-width: 1194px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 2) {
.teamBox {
.teamPeople{
.twoLevel{
.left{
.line{
width: 7%;
}
}
}
}
}
}
/* iPad Pro 12.9-inch 竖屏 */
@media only screen
and (min-device-width: 1024px)
and (max-device-width: 1366px)
and (orientation: portrait)
and (-webkit-min-device-pixel-ratio: 2) {
.teamBox {
.teamPeople{
.twoLevel{
.left{
.line{
width: 7%;
}
}
}
}
}
}
} }
</style> </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 {
...@@ -45,7 +45,7 @@ export default { ...@@ -45,7 +45,7 @@ export default {
codeUrl: '', codeUrl: '',
loginType: '', loginType: '',
userInfo: {}, userInfo: {},
qrcodeSize: 100, // 二维码大小(单位px) qrcodeSize: 110, // 二维码大小(单位px)
generatedImage: '', // 生成的图片 generatedImage: '', // 生成的图片
isBgImageReady: false, // 背景图片是否准备就绪 isBgImageReady: false, // 背景图片是否准备就绪
retryCount: 0, // 重试次数 retryCount: 0, // 重试次数
...@@ -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();
...@@ -303,46 +299,6 @@ export default { ...@@ -303,46 +299,6 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// .container {
// display: flex;
// flex-direction: column;
// height: 100vh;
// width: 100vw;
// .imgBox {
// position: relative;
// .imgContainer {
// position: relative;
// .qrcode-container {
// position: absolute;
// bottom: 10rpx;
// right: 10rpx;
// background: #fff;
// padding: 10rpx;
// border-radius: 10rpx;
// box-shadow: 0 0 10rpx rgba(0,0,0,0.1);
// .qrcode-canvas {
// display: block;
// }
// }
// }
// }
// .preview-container{
// box-sizing: border-box;
// flex: 1;
// padding: 30rpx;
// width: 100%;
// height: 100%;
// .preview-image {
// width: 100%;
// height: auto;
// max-height: 100%;
// object-fit: contain;
// }
// }
// }
.container { .container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -397,4 +353,126 @@ export default { ...@@ -397,4 +353,126 @@ export default {
} }
} }
} }
.container {
display: flex;
flex-direction: column;
width: 100vw;
overflow: hidden;
/* 默认手机端样式 */
height: 100vh;
/* iPad竖屏 (768px-1024px) */
@media only screen and (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) {
height: 100vh;
.imgBox {
height: 100vh;
overflow: hidden;
.imgContainer {
height: 100%;
image {
height: 100%;
width: auto;
max-width: 100%;
object-fit: contain;
}
}
}
}
/* iPad横屏 (1024px-1366px) */
@media only screen and (min-width: 1024px) and (max-width: 1366px) and (orientation: landscape) {
height: 100vh;
width: 35vw;
.imgBox {
height: 100vh;
overflow: hidden;
.imgContainer {
height: 100%;
image {
height: 100%;
width: auto;
max-width: 100%;
object-fit: contain;
}
}
}
}
/* PC端 (大于1366px) */
@media only screen and (min-width: 1366px) {
height: 100vh;
width: 35vw;
.imgBox {
height: 100vh;
overflow: hidden;
.imgContainer {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
image {
height: auto;
max-height: 100%;
width: 500px;
max-width: 100%;
object-fit: contain;
}
}
}
}
.imgBox {
width: 100%;
height: auto;
.imgContainer {
width: 100%;
position: relative;
image {
width: 100%;
height: auto;
display: block;
}
.qrcode-container {
position: absolute;
bottom: 10rpx;
right: 10rpx;
background: #fff;
padding: 10rpx;
border-radius: 10rpx;
box-shadow: 0 0 10rpx rgba(0,0,0,0.1);
.qrcode-canvas {
display: block;
}
}
}
}
.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;
/* 大屏幕设备调整 */
@media only screen and (min-width: 768px) {
max-height: 100vh;
width: auto;
}
}
}
}
</style> </style>
\ No newline at end of file
...@@ -522,12 +522,12 @@ ...@@ -522,12 +522,12 @@
},{ },{
"path": "setting/logOff", "path": "setting/logOff",
"style": { "style": {
"navigationBarTitleText": "注销账号" "navigationBarTitleText": "合伙人解约"
} }
},{ },{
"path": "ruleAndContract/cancelProtocol", "path": "ruleAndContract/cancelProtocol",
"style": { "style": {
"navigationBarTitleText": "注销账号协议" "navigationBarTitleText": "合伙人解约协议"
} }
}, { }, {
"path": "login/login", "path": "login/login",
......
<template> <template>
<view class="container"> <view class="container">
<!-- 禁用弹窗 --> <!-- 禁用弹窗 -->
<restrictedTip ref="restrictedTip"/> <restrictedTip ref="restrictedTip"/>
<view v-if="!mpCffp">
<view class="shareheader" style="" v-if="coursesharing != 1 || deviceType==3"> <view class="shareheader" style="" v-if="coursesharing != 1 || deviceType==3">
<!-- #ifdef APP --> <!-- #ifdef APP -->
<view class="iconfont icon-youjiantou" style="margin-left: 30rpx;" @click="goBack()"></view> <view class="iconfont icon-youjiantou" style="margin-left: 30rpx;" @click="goBack()"></view>
<!-- #endif --> <!-- #endif -->
<view class="share-entrance"> <view class="share-entrance" >
<view style="z-index: 99999;"> <view style="z-index: 99999;">
<uni-popup ref="share" type="top" safeArea backgroundColor="#F4F2F3" :maskClick='true' <uni-popup ref="share" type="top" safeArea backgroundColor="#F4F2F3" :maskClick='true'
@change="maskClick"> @change="maskClick">
<uni-popup-share @select="sharechange"></uni-popup-share> <uni-popup-share @select="sharechange"></uni-popup-share>
</uni-popup> </uni-popup>
</view> </view>
<!-- v-if="isWxH5" --> <!-- v-if="isWxH5" -->
<view v-if="isWxH5" style="width: 40rpx;height: 40rpx;padding-right: 20rpx;"> <view v-if="isWxH5" style="width: 40rpx;height: 40rpx;padding-right: 20rpx;">
<image class="image" @click="reinvite" src="../../static/fastentry/Slice122.png" mode=""></image> <image class="image" @click="reinvite" src="../../static/fastentry/Slice122.png" mode=""></image>
...@@ -22,8 +26,12 @@ ...@@ -22,8 +26,12 @@
<view class="" style="width: 40rpx;height: 40rpx; "> <view class="" style="width: 40rpx;height: 40rpx; ">
<image class="image" @click="shareToggle" src="../../static/fastentry/Slice12.png" mode=""></image> <image class="image" @click="shareToggle" src="../../static/fastentry/Slice12.png" mode=""></image>
</view> </view>
</view>
</view> </view>
</view> </view>
<!-- 课程banner图 --> <!-- 课程banner图 -->
<!-- v-show="!sliceshare" --> <!-- v-show="!sliceshare" -->
<view class="courseBannerBox" v-if="!sliceshare && bannerViewType == '1'"> <view class="courseBannerBox" v-if="!sliceshare && bannerViewType == '1'">
...@@ -128,9 +136,29 @@ ...@@ -128,9 +136,29 @@
</h4> </h4>
<view v-html="lecturerInfo?.lecturerIntroduce" class="lecturerText richTextContent"></view> <view v-html="lecturerInfo?.lecturerIntroduce" class="lecturerText richTextContent"></view>
</view> </view>
<view v-if="!mpCffp">
<view class="buyBox" @click="saveOrder()" v-if="(courseInfo.status == 1 || courseInfo.status == 2) && courseInfo.coursePrice != 0"> <view class="buyBox" @click="saveOrder()" v-if="(courseInfo.status == 1 || courseInfo.status == 2) && courseInfo.coursePrice != 0">
<text>{{showName}}</text> <text>{{showName}}</text>
</view> </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>
</view> </view>
...@@ -180,8 +208,65 @@ ...@@ -180,8 +208,65 @@
@join="gotoJoinPartner" @join="gotoJoinPartner"
@continue="continueShare" @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> </view>
<!-- #endif -->
</view>
</template> </template>
<script> <script>
...@@ -197,7 +282,10 @@ ...@@ -197,7 +282,10 @@
import {nanoid} from 'nanoid'; import {nanoid} from 'nanoid';
import common from '../../common/common'; import common from '../../common/common';
import {baseURL,apiURL,cffpURL,companyInfo,shareURL} from "@/environments/environment"; 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 { export default {
components: { components: {
UniShareWx, UniShareWx,
...@@ -205,7 +293,9 @@ ...@@ -205,7 +293,9 @@
LoginPopup, LoginPopup,
VerifyPopup, VerifyPopup,
PartnerTipPopup, PartnerTipPopup,
restrictedTip restrictedTip,
sharePosterPop,
loadingIcon
}, },
data() { data() {
return { return {
...@@ -271,7 +361,20 @@ ...@@ -271,7 +361,20 @@
time: 3 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: { methods: {
...@@ -324,6 +427,23 @@ ...@@ -324,6 +427,23 @@
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
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分享 //app分享
// #ifdef APP-PLUS // #ifdef APP-PLUS
let dataWXform = { let dataWXform = {
...@@ -573,8 +693,6 @@ ...@@ -573,8 +693,6 @@
shareCode: this.shareCode, shareCode: this.shareCode,
dataSource: this.coursesharing == 1 ? '2' : this.dataSource dataSource: this.coursesharing == 1 ? '2' : this.dataSource
} }
console.log('param',param);
// return
api.saveOrder(param).then(res => { api.saveOrder(param).then(res => {
if (res['success']) { if (res['success']) {
this.orderId = res['data']['id']; this.orderId = res['data']['id'];
...@@ -589,6 +707,35 @@ ...@@ -589,6 +707,35 @@
'产品详情', '产品详情',
'pages/courseDetail/courseDetail' '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({ uni.navigateTo({
url: `/pages/orderConfirm/orderConfirm?fileId=${this.fileId}&orderId=${this.orderId}&userId=${this.userId}` url: `/pages/orderConfirm/orderConfirm?fileId=${this.fileId}&orderId=${this.orderId}&userId=${this.userId}`
}) })
...@@ -998,10 +1145,236 @@ ...@@ -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){ if(option.addSystemType){
this.addSystemType = option.addSystemType this.addSystemType = option.addSystemType
} }
...@@ -1027,7 +1400,7 @@ ...@@ -1027,7 +1400,7 @@
uni.setStorageSync('h5_coursesharing', this.coursesharing); uni.setStorageSync('h5_coursesharing', this.coursesharing);
this.getshareData() this.getshareData()
} }
let dataForm = JSON.parse(uni.getStorageSync('cffp_userInfo')) let dataForm = JSON.parse(JSON.stringify(uni.getStorageSync('cffp_userInfo')))
this.realName = dataForm.realName; this.realName = dataForm.realName;
if(!this.realName){ if(!this.realName){
this.queryInfo(); this.queryInfo();
...@@ -1036,7 +1409,13 @@ ...@@ -1036,7 +1409,13 @@
// this.switchTab(1); // this.switchTab(1);
}, },
onShow() { 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.loginType = uni.getStorageSync('loginType')
this.init(); this.init();
this.isWx_Miniprogram(); this.isWx_Miniprogram();
...@@ -1070,16 +1449,96 @@ ...@@ -1070,16 +1449,96 @@
setWechatShare(); setWechatShare();
}, window.location.href); }, window.location.href);
// #endif // #endif
},
onHide() {
this.$nextTick(()=>{
this.$refs.sharePosterPop.closeDropdown()
})
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container{ .container{
// background-color: #f7f7f7;
width: 100%; width: 100%;
height: auto; height: auto;
box-sizing: border-box; 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 { page {
padding: 0; padding: 0;
...@@ -1355,6 +1814,48 @@ ...@@ -1355,6 +1814,48 @@
text-align: center; text-align: center;
max-width: 60%; max-width: 60%;
margin: 0 auto; 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 @@ ...@@ -1385,5 +1886,63 @@
margin-top: 30%; margin-top: 30%;
padding: 0 30px; 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> </style>
...@@ -26,12 +26,61 @@ ...@@ -26,12 +26,61 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 家办商城跳cffp的分享功能 -->
<!-- #ifdef H5 -->
<!-- v-if="!generatedImage" -->
<view class="generateImageBox" ref="captureElement" v-if="!generatedImage">
<view class="imgBox">
<img
class="posterImg"
@load="handleBgImageLoad"
@error="handleBgImageError"
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">
{{sharePosterItem.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>
<!-- #endif -->
<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" >
...@@ -57,7 +106,11 @@ ...@@ -57,7 +106,11 @@
最高可赚¥{{item.income || '0.00'}} 最高可赚¥{{item.income || '0.00'}}
</view> </view>
<view class="right" @click="gotoShare(item)"> <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> </view>
</view> </view>
...@@ -71,6 +124,14 @@ ...@@ -71,6 +124,14 @@
@close="closeLogin" @close="closeLogin"
> >
</BootPage> </BootPage>
<!-- 海报弹窗 -->
<sharePosterPop
ref="sharePosterPop"
:generatedImage="generatedImage"
@closePoster="closePoster"
:sharePosterUrl="qrCodeUrl"
:sharePosterObj="sharePosterObj"
></sharePosterPop>
<uni-popup ref="popup" type="center" background-color="#fff"> <uni-popup ref="popup" type="center" background-color="#fff">
<view class="descriptionBox"> <view class="descriptionBox">
<view class="imageBox"> <view class="imageBox">
...@@ -110,7 +171,6 @@ ...@@ -110,7 +171,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 +184,10 @@ ...@@ -124,6 +184,10 @@
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 sharePosterPop from '@/components/commonPopup/sharePosterPop.vue';
import loadingIcon from '@/components/loading/loading.vue';
import UQRCode from 'uqrcodejs';
import { elementToImage } from '@/util/htmlToImage';
export default{ export default{
name:'courselist', name:'courselist',
props:{ props:{
...@@ -144,7 +208,9 @@ ...@@ -144,7 +208,9 @@
UniShareWx, UniShareWx,
BootPage, BootPage,
PartnerTipPopup, PartnerTipPopup,
restrictedTip restrictedTip,
sharePosterPop,
loadingIcon
}, },
watch: { watch: {
// 监听 prop 变化,更新本地副本 // 监听 prop 变化,更新本地副本
...@@ -170,15 +236,31 @@ ...@@ -170,15 +236,31 @@
shareItem:{},//分享的产品 shareItem:{},//分享的产品
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',
qrCodeUrl: 'https://example.com',//二维码的链接地址
qrCodeSize: 100,//二维码的尺寸
companyLogo : '../../static/logo2.png',
generatedImage:'',//生成的海报图片
sharePosterObj:{},//海报分享数据
sharePosterItem:{fileFirstImage:''},
isLoading: false
} }
}, },
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'){
this.companyLogo='../../static/myteam/Group1633.png';
}else if(this.companyType == '2'){
this.companyLogo='../../static/logo2.png';
}
}, },
onShow() { onShow() {
this.isLoading = false
this.generatedImage = ''
this.sharePosterItem = {fileFirstImage:''}
this.queryName = uni.getStorageSync('queryName') || ''; this.queryName = uni.getStorageSync('queryName') || '';
this.courseList(); this.courseList();
this.sourceType = uni.getStorageSync('addSystemType') || '1'; this.sourceType = uni.getStorageSync('addSystemType') || '1';
...@@ -191,6 +273,7 @@ ...@@ -191,6 +273,7 @@
setWechatShare(); setWechatShare();
}, window.location.href); }, window.location.href);
// #endif // #endif
}, },
created(){ created(){
this.queryName = uni.getStorageSync('queryName') || ''; this.queryName = uni.getStorageSync('queryName') || '';
...@@ -211,6 +294,7 @@ ...@@ -211,6 +294,7 @@
} }
} }
}, },
methods:{ methods:{
transform(value){ transform(value){
if(value == 'consult'){ if(value == 'consult'){
...@@ -239,7 +323,7 @@ ...@@ -239,7 +323,7 @@
if(uni.getStorageSync('cffp_userInfo')){ if(uni.getStorageSync('cffp_userInfo')){
this.userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo')) this.userInfo = JSON.parse(uni.getStorageSync('cffp_userInfo'))
} }
this.shareItem = JSON.parse(JSON.stringify(item)) // return
// 未登录去登录 // 未登录去登录
if(uni.getStorageSync('loginType')!=='codelogin'){ if(uni.getStorageSync('loginType')!=='codelogin'){
dataHandling.pocessTracking( dataHandling.pocessTracking(
...@@ -253,29 +337,31 @@ ...@@ -253,29 +337,31 @@
this.sharelogin = true this.sharelogin = true
return return
} }
if(this.runEnv == 'browser'){ this.shareItem = JSON.parse(JSON.stringify(item))
// 已登录,未成为合伙人
if(this.userInfo&&!this.userInfo['partnerType']) {
dataHandling.pocessTracking( dataHandling.pocessTracking(
'点击', '点击',
`用户在产品中心浏览器端点击产品分享按钮`, `用户在产品中心未加盟时点击产品分享按钮`,
'点击', '点击',
2, 2,
'产品中心', '产品中心',
'pages/courselist/courselist' 'pages/courselist/courselist'
) )
this.$refs.popup.open() this.$refs.partnerTipPopup.open()
return return
} }
// 已登录,未成为合伙人 // 正常逻辑先注释掉
if(this.userInfo&&!this.userInfo['partnerType']) { if(this.runEnv == 'browser'){
dataHandling.pocessTracking( dataHandling.pocessTracking(
'点击', '点击',
`用户在产品中心未加盟时点击产品分享按钮`, `用户在产品中心浏览器端点击产品分享按钮`,
'点击', '点击',
2, 2,
'产品中心', '产品中心',
'pages/courselist/courselist' 'pages/courselist/courselist'
) )
this.$refs.partnerTipPopup.open() this.$refs.popup.open()
return return
} }
this.continueShare() this.continueShare()
...@@ -284,6 +370,18 @@ ...@@ -284,6 +370,18 @@
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
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.qrCodeUrl = newLink
this.submitsuessc(shareCode,jumptime,this.shareItem)
return
}
//app分享 //app分享
// #ifdef APP-PLUS // #ifdef APP-PLUS
let dataWXform = { let dataWXform = {
...@@ -428,11 +526,13 @@ ...@@ -428,11 +526,13 @@
'产品中心', '产品中心',
'pages/courselist/courselist' 'pages/courselist/courselist'
) )
uni.setStorageSync('posterItem',item)
uni.navigateTo({ uni.navigateTo({
url: `/pages/courseDetail/courseDetail?fileId=${item.fileId}` url: `/pages/courseDetail/courseDetail?fileId=${item.fileId}`
}); });
}, },
courseList(){ courseList(){
console.log('执行了');
const param = { const param = {
queryName:this.queryName, queryName:this.queryName,
courseClassify:this.courseClassify courseClassify:this.courseClassify
...@@ -440,8 +540,11 @@ ...@@ -440,8 +540,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 +554,188 @@ ...@@ -451,17 +554,188 @@
}).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.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, 2000));
// 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();
}
},
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.sharePosterItem = {
fileFirstImage:""
}
this.generatedImage = ''
}
}, },
mounted() { mounted() {
this.fileUploadItemCFFPList = uni.getStorageSync('fileUploadItemCFFPList'); this.fileUploadItemCFFPList = uni.getStorageSync('fileUploadItemCFFPList');
...@@ -477,18 +751,107 @@ ...@@ -477,18 +751,107 @@
onHide() { onHide() {
this.queryName = '' this.queryName = ''
uni.removeStorageSync('queryName') uni.removeStorageSync('queryName')
} this.$nextTick(()=>{
this.$refs.sharePosterPop.closeDropdown()
})
},
} }
</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;
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;
}
}
}
}
}
.preview-container{
width: 100%;
box-sizing: border-box;
padding: 20rpx;
margin-bottom: 100rpx;
.preview-image{
width: 100%;
}
}
.tabBox{ .tabBox{
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -627,13 +990,12 @@ ...@@ -627,13 +990,12 @@
color: rgba(34, 35, 133, 1); color: rgba(34, 35, 133, 1);
} }
.right{ .right{
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 15rpx 10rpx 15rpx 15rpx; padding: 15rpx 10rpx 15rpx 15rpx;
background: rgba(36, 37, 137, 1); background: rgba(36, 37, 137, 1);
width: 20%;
font-size: 27rpx; font-size: 27rpx;
color: #fff; color: #fff;
border-radius: 0 10rpx 10rpx 0rpx; /* 左上 右上 右下 左下 */ border-radius: 0 10rpx 10rpx 0rpx; /* 左上 右上 右下 左下 */
...@@ -812,6 +1174,56 @@ ...@@ -812,6 +1174,56 @@
padding-top: 50rpx; 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> </style>
\ No newline at end of file
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
:showFlag="false" :showFlag="false"
:cffpCourseInfos="cffpCourseInfos" :cffpCourseInfos="cffpCourseInfos"
@changeCourseClassify="changeCourseClassify" @changeCourseClassify="changeCourseClassify"
ref="courselist"
></courselist> ></courselist>
<view class="productListBox"> <view class="productListBox">
...@@ -82,6 +83,7 @@ ...@@ -82,6 +83,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 +261,7 @@ ...@@ -259,7 +261,7 @@
loginType : uni.getStorageSync('loginType'), loginType : uni.getStorageSync('loginType'),
userInfo:{} ,//用户信息, userInfo:{} ,//用户信息,
productItem:{}, productItem:{},
dataToken:'' dataToken:'',
} }
}, },
components: { components: {
...@@ -270,10 +272,12 @@ ...@@ -270,10 +272,12 @@
courseItem, courseItem,
JoinPopup, JoinPopup,
PartnerTipPopup, PartnerTipPopup,
restrictedTip restrictedTip,
}, },
onShow() { onShow() {
console.log('webview',typeof wx !== 'undefined' && wx.miniProgram);
this.loginType = uni.getStorageSync('loginType') this.loginType = uni.getStorageSync('loginType')
this.init(); this.init();
...@@ -290,11 +294,12 @@ ...@@ -290,11 +294,12 @@
} }
}, },
onHide() {
this.$nextTick(()=>{
this.$refs.courselist.$refs.sharePosterPop.closeDropdown()
})
},
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 +458,6 @@ ...@@ -453,7 +458,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()
...@@ -789,6 +793,7 @@ ...@@ -789,6 +793,7 @@
} }
}, },
} }
</script> </script>
......
...@@ -4,7 +4,29 @@ ...@@ -4,7 +4,29 @@
<text class="iconfont icon-youjiantou zuojiantou" @click="goBack()" style="top: 20rpx;"></text> <text class="iconfont icon-youjiantou zuojiantou" @click="goBack()" style="top: 20rpx;"></text>
<!-- #endif --> <!-- #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"> <view class="tabTitle">
<text :class="{'actived': tabType===1}" @click="switchTab(1)">基本信息</text> <text :class="{'actived': tabType===1}" @click="switchTab(1)">基本信息</text>
<text :class="{'actived': tabType===2}" @click="switchTab(2)">邀请信息</text> <text :class="{'actived': tabType===2}" @click="switchTab(2)">邀请信息</text>
...@@ -33,7 +55,18 @@ ...@@ -33,7 +55,18 @@
</view> </view>
</view> </view>
<!-- <share></share> --> <!-- <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>
<!-- 邀请信息 --> <!-- 邀请信息 -->
<view class="inviteListsBox" v-if="tabType===2"> <view class="inviteListsBox" v-if="tabType===2">
...@@ -94,6 +127,13 @@ ...@@ -94,6 +127,13 @@
</view> </view>
</view> </view>
</view> </view>
<!-- 海报弹窗 -->
<sharePosterPop
ref="sharePosterPop"
:generatedImage="generatedImage"
@closePoster="closePoster"
btnBottom="-15%"
></sharePosterPop>
</view> </view>
</template> </template>
...@@ -103,7 +143,15 @@ ...@@ -103,7 +143,15 @@
import common from '../../common/common'; import common from '../../common/common';
import {hshare ,setWechatShare,initJssdkShare} from '@/util/fiveshare'; import {hshare ,setWechatShare,initJssdkShare} from '@/util/fiveshare';
import {baseURL,apiURL,cffpURL,companyInfo,shareURL} from "@/environments/environment"; 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 { export default {
components:{
sharePosterPop,
loadingIcon
},
data() { data() {
return { return {
companyType:companyInfo.companyType, companyType:companyInfo.companyType,
...@@ -134,9 +182,17 @@ ...@@ -134,9 +182,17 @@
realName: '', realName: '',
partnerLevel: '', partnerLevel: '',
invitationCode: '', invitationCode: '',
shareTipsFlag: false shareTipsFlag: false,
qrCodeUrl:'/myPackageA/applyFranchise/applyFranchise',
qrCodeSize: 80,//二维码的尺寸
generatedImage:'',//生成的海报图片
companyLogo : '../../static/logo2.png',
posterImg:'',
isLoading: false
}; };
}, },
onLoad(option) { onLoad(option) {
//this.partnerLevel = option.levelCode //this.partnerLevel = option.levelCode
this.partnerLevel = 'P1' this.partnerLevel = 'P1'
...@@ -146,6 +202,11 @@ ...@@ -146,6 +202,11 @@
}else { }else {
this.ydLogoShare = `${shareURL}/static/logo2.png`; 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')) let dataForm = JSON.parse(uni.getStorageSync('cffp_userInfo'))
this.realName = dataForm.realName || dataForm.nickName; this.realName = dataForm.realName || dataForm.nickName;
this.invitationCode = dataForm.invitationCode this.invitationCode = dataForm.invitationCode
...@@ -154,12 +215,20 @@ ...@@ -154,12 +215,20 @@
} }
}, },
onShow(){ onShow(){
this.isLoading = false
this.posterImg = ''
this.generatedImage = ''
// #ifdef H5 // #ifdef H5
initJssdkShare(() => { initJssdkShare(() => {
setWechatShare(); setWechatShare();
}, window.location.href); }, window.location.href);
// #endif // #endif
}, },
onHide() {
this.$nextTick(()=>{
this.$refs.sharePosterPop.closeDropdown()
})
},
methods: { methods: {
goBack() { goBack() {
uni.navigateBack({ uni.navigateBack({
...@@ -249,10 +318,20 @@ ...@@ -249,10 +318,20 @@
api.saveApplyInfo(this.dataForm).then(res => { api.saveApplyInfo(this.dataForm).then(res => {
if (res['success']) { if (res['success']) {
this.shareId = res.data.id; this.shareId = res.data.id;
// #ifdef APP-PLUS // #ifdef APP-PLUS
this.$refs.share.open() this.$refs.share.open()
// #endif // #endif
//#ifdef H5 //#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.shareTipsFlag = true;
this.getshareData() this.getshareData()
// #endif // #endif
...@@ -368,6 +447,150 @@ ...@@ -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> </script>
...@@ -376,7 +599,46 @@ ...@@ -376,7 +599,46 @@
.container { .container {
position: relative; position: relative;
height: 100vh; 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 { .tabTitle {
color: #666666; color: #666666;
background-color: #fff; background-color: #fff;
...@@ -509,6 +771,9 @@ ...@@ -509,6 +771,9 @@
background-color: #20269B; background-color: #20269B;
color: #fff; color: #fff;
font-size: 36rpx; font-size: 36rpx;
display: flex;
align-items: center;
justify-content: center;
} }
} }
......
...@@ -204,7 +204,8 @@ ...@@ -204,7 +204,8 @@
tipsFlag: false, tipsFlag: false,
isRedirect: null, isRedirect: null,
amount: 0, amount: 0,
calculatedPrice: 0 calculatedPrice: 0,
dataToken:'',
} }
}, },
computed: { computed: {
...@@ -505,8 +506,43 @@ ...@@ -505,8 +506,43 @@
}, 500) }, 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) { 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.fileId = option.fileId;
this.orderId = option.orderId; this.orderId = option.orderId;
if (option.userId) { if (option.userId) {
......
...@@ -200,30 +200,7 @@ ...@@ -200,30 +200,7 @@
} }
} }
}, },
// currentFilterBtn: {
// deep: true,
// handler(newVal) {
// if(newVal == '3'&&this.currentBtn=='2') {
// this.tableHeaderList = [
// {title:'销售日期',id:'1'},
// {title:'单数',id:'2'},
// {title:'销售额',id:'3'},
// {title:'标准销售额',id:'4'},
// ]
// this.getqueryTeamAchievement()
// return
// }else {
// this.tableHeaderList = [
// {title:'成员',id:'1'},
// {title:'单数',id:'2'},
// {title:'销售额',id:'3'},
// {title:'标准销售额',id:'4'},
// ]
// this.getqueryTeamAchievement()
// return
// }
// }
// },
}, },
onLoad(){ onLoad(){
......
...@@ -12,11 +12,18 @@ ...@@ -12,11 +12,18 @@
<view class="headerInfo"> <view class="headerInfo">
<view class="headerTop"> <view class="headerTop">
<view class="" style="margin-right: 15rpx;"> <view class="" style="margin-right: 15rpx;">
<view class="myName" v-if="loginType == 'codelogin'">{{showMyName || '点击头像完善信息'}}</view> <view class="myName" v-if="loginType == 'codelogin'">
{{showMyName || '点击头像完善信息'}}
<text v-if="customerBasicInfo.partnerType" class="typePartner">{{customerBasicInfo.partnerType}}</text>
</view>
<view class="myName" v-if="loginType == 'visitor'">游客</view> <view class="myName" v-if="loginType == 'visitor'">游客</view>
</view> </view>
<view class="desBox" v-if="loginType == 'codelogin'&&customerBasicInfo.partnerType"> <!-- &&customerBasicInfo.parentName 我的上级:{{customerBasicInfo.parentName}} -->
{{customerBasicInfo.partnerType}} <view class="desBox" v-if="loginType == 'codelogin'">
<!-- 上级的显示 -->
<text class="desTxt" v-if="customerBasicInfo.parentRealName&&customerBasicInfo.parentNickName">我的上级:{{customerBasicInfo.parentRealName}}({{customerBasicInfo.parentNickName}})</text>
<text v-else-if="customerBasicInfo.parentRealName">我的上级:{{customerBasicInfo.parentRealName}} </text>
<text v-else-if="!customerBasicInfo.parentRealName&&customerBasicInfo.parentNickName">我的上级:{{customerBasicInfo.parentNickName}}</text>
</view> </view>
</view> </view>
</view> </view>
...@@ -163,6 +170,7 @@ ...@@ -163,6 +170,7 @@
@continue="jumpPage('1')" @continue="jumpPage('1')"
/> />
<restrictedTip ref="restrictedTip"/> <restrictedTip ref="restrictedTip"/>
</view> </view>
</template> </template>
...@@ -206,8 +214,8 @@ ...@@ -206,8 +214,8 @@
children:[ children:[
{title:'申请加盟',icon:'icon-hezuo',link:'/myPackageA/applyFranchise/applyFranchise?',isOpen:true,isShow:true,isApply:true}, {title:'申请加盟',icon:'icon-hezuo',link:'/myPackageA/applyFranchise/applyFranchise?',isOpen:true,isShow:true,isApply:true},
{key:'06',title:'邀请加盟',icon:'icon-yaoqing',link:'/pages/inviteJoin/inviteJoin',isOpen:true,isShow:true,identity: true}, {key:'06',title:'邀请加盟',icon:'icon-yaoqing',link:'/pages/inviteJoin/inviteJoin',isOpen:true,isShow:true,identity: true},
{title:'我的团队',icon:'icon-tuandui',link:'/pages/personalCenter/myTeam',isOpen:true,isShow:true,identity: true}, // {title:'我的团队',icon:'icon-tuandui',link:'/pages/personalCenter/myTeam',isOpen:true,isShow:true,identity: true},
// {title:'我的团队',icon:'icon-tuandui',link:'/myPackageA/myTeam/myTeam',isOpen:true,isShow:true,identity: true}, {title:'我的团队',icon:'icon-tuandui',link:'/myPackageA/myTeam/myTeam',isOpen:true,isShow:true,identity: true},
{title:'育成团队',icon:'icon-yuchengguanxi',link:'/pages/personalCenter/myTeamIncubate',isOpen:true,isShow:true,identity: true}, {title:'育成团队',icon:'icon-yuchengguanxi',link:'/pages/personalCenter/myTeamIncubate',isOpen:true,isShow:true,identity: true},
], ],
}, },
...@@ -265,8 +273,8 @@ ...@@ -265,8 +273,8 @@
uni.$on("handClick", res => { uni.$on("handClick", res => {
this.customerBasicInfo = res.data this.customerBasicInfo = res.data
let name = this.customerBasicInfo.realName || this.customerBasicInfo.nickName let name = this.customerBasicInfo.realName || this.customerBasicInfo.nickName
if(name && name.length>5){ if(name && name.length>4){
this.showMyName =name.substring(0, 5) + '...' this.showMyName =name.substring(0, 4) + '...'
}else { }else {
this.showMyName = name this.showMyName = name
} }
...@@ -594,13 +602,19 @@ ...@@ -594,13 +602,19 @@
if(res['success']){ if(res['success']){
this.customerBasicInfo = res['data']; this.customerBasicInfo = res['data'];
let name = this.customerBasicInfo.realName || this.customerBasicInfo.nickName let name = this.customerBasicInfo.realName || this.customerBasicInfo.nickName
console.log('name',name); if(name && name.length>4){
if(name && name.length>5){ this.showMyName = name.substring(0, 4) + '...'
this.showMyName = name.substring(0, 5) + '...'
}else { }else {
this.showMyName = name this.showMyName = name
} }
// this.customerBasicInfo.parentNickName = '除非进行相对路径配置'
// this.customerBasicInfo.parentRealName = '除非进行相对路径配置'
if(this.customerBasicInfo.parentRealName&&this.customerBasicInfo.parentNickName && this.customerBasicInfo.parentNickName.length>3){
this.customerBasicInfo.parentNickName = this.customerBasicInfo.parentNickName.substring(0, 3) + '..'
}
if(this.customerBasicInfo.parentRealName&&this.customerBasicInfo.parentNickName&& this.customerBasicInfo.parentRealName.length>3){
this.customerBasicInfo.parentRealName = this.customerBasicInfo.parentRealName.substring(0, 3) + '..'
}
this.inviteEqrode = this.customerBasicInfo.invitationCode; this.inviteEqrode = this.customerBasicInfo.invitationCode;
uni.setStorageSync('user_mobile', res.data.mobile) uni.setStorageSync('user_mobile', res.data.mobile)
...@@ -611,7 +625,6 @@ ...@@ -611,7 +625,6 @@
this.loginType = 'visitor' this.loginType = 'visitor'
} }
console.log('this.showMyName',this.showMyName);
}) })
} }
}, },
...@@ -675,6 +688,7 @@ ...@@ -675,6 +688,7 @@
} }
.headerInfo{ .headerInfo{
box-sizing: border-box;
margin-left: 20rpx; margin-left: 20rpx;
display: flex; display: flex;
font-size: 36rpx; font-size: 36rpx;
...@@ -684,6 +698,20 @@ ...@@ -684,6 +698,20 @@
justify-content: flex-start; justify-content: flex-start;
.headerTop{ .headerTop{
color:#fff; color:#fff;
.myName{
display: flex;
align-items: center;
.typePartner{
margin-left: 15rpx;
padding: 5rpx 10rpx;
background-color: #fff;
color: #FFBB00;
border-radius: 10rpx;
font-weight: normal;
font-size: 26rpx;
}
}
} }
.desBox{ .desBox{
...@@ -691,6 +719,22 @@ ...@@ -691,6 +719,22 @@
padding: 0 2rpx; padding: 0 2rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: normal; font-weight: normal;
max-width: 400rpx;
display: flex;
align-items: center;
margin-top: 10rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap !important;
flex-shrink: 1;
.desTxt{
width: 350rpx; /* 根据需要调整 */
display: inline-block; /* 或者 block */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap !important;
flex-shrink: 1;
}
} }
.nickName{ .nickName{
font-size: 27rpx; font-size: 27rpx;
...@@ -918,6 +962,7 @@ ...@@ -918,6 +962,7 @@
} }
} }
} }
/* 新增:iPad mini 和 iPad Air 竖屏的媒体查询 */ /* 新增:iPad mini 和 iPad Air 竖屏的媒体查询 */
/* iPad mini 竖屏 */ /* iPad mini 竖屏 */
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
isShow: true, isShow: true,
isTips: false, isTips: false,
isType: 'text', isType: 'text',
isJump: true isJump: false
}, },
{ {
key:'2', key:'2',
......
...@@ -96,6 +96,9 @@ ...@@ -96,6 +96,9 @@
'pages/personalCenter/system/settings' 'pages/personalCenter/system/settings'
) )
try { try {
if(uni.getStorageSync('savedShareImage')){
uni.removeStorageSync('savedShareImage')
}
uni.setStorageSync('loginType','visitor'); uni.setStorageSync('loginType','visitor');
} catch (e) { } catch (e) {
console.log(e) console.log(e)
......
...@@ -295,37 +295,37 @@ ...@@ -295,37 +295,37 @@
uni.showToast({title: '昵称为2~10个字符',duration: 2000,icon: 'none'}); uni.showToast({title: '昵称为2~10个字符',duration: 2000,icon: 'none'});
return return
} }
const validateResult = this.validateForm(); // const validateResult = this.validateForm();
if(!validateResult.isValid) { // if(!validateResult.isValid) {
let message = '请完善以下信息:\n'; // let message = '请完善以下信息:\n';
validateResult.emptyFields.forEach((field, index) => { // validateResult.emptyFields.forEach((field, index) => {
message += `${index + 1}. ${field}\n`; // message += `${index + 1}. ${field}\n`;
}); // });
uni.showModal({ // uni.showModal({
title: '提示', // title: '提示',
content: message, // content: message,
showCancel: false, // showCancel: false,
confirmText: '我知道了' // confirmText: '我知道了'
}); // });
return; // return;
} // }
if (!common.nameValid(this.realInfo.shiming.realName)) { // if (!common.nameValid(this.realInfo.shiming.realName)) {
uni.showToast({title: '请填写真实姓名',duration: 2000,icon: 'none'}); // uni.showToast({title: '请填写真实姓名',duration: 2000,icon: 'none'});
this.realInfo.shiming.realName = '' // this.realInfo.shiming.realName = ''
return // return
} // }
if(this.realInfo.shiming.idType == 'IDENTITY_CARD'&&this.realInfo.shiming.idNumber.length<18 ){ // if(this.realInfo.shiming.idType == 'IDENTITY_CARD'&&this.realInfo.shiming.idNumber.length<18 ){
uni.showToast({title: '请输入18位实名身份证号',duration: 2000,icon: 'none'}); // uni.showToast({title: '请输入18位实名身份证号',duration: 2000,icon: 'none'});
return // return
} // }
if(this.realInfo.shiming.idType == 'IDENTITY_CARD' ){ // if(this.realInfo.shiming.idType == 'IDENTITY_CARD' ){
let obj = common.IdCodeValid(this.realInfo.shiming.idNumber) // let obj = common.IdCodeValid(this.realInfo.shiming.idNumber)
if(!obj.pass){ // if(!obj.pass){
uni.showToast({title: '请输入有效的实名身份证号',duration: 2000,icon: 'none'}); // uni.showToast({title: '请输入有效的实名身份证号',duration: 2000,icon: 'none'});
return // return
} // }
} // }
this.saveUserInfo(); this.saveUserInfo();
}, },
...@@ -346,7 +346,7 @@ ...@@ -346,7 +346,7 @@
// 创建两个Promise // 创建两个Promise
const updateInfoPromise = api.updateinfo(UserRequestVO).then(res => { const updateInfoPromise = api.updateinfo(UserRequestVO).then(res => {
if (res.success) { if (res.success) {
uni.showToast({title: '修改成功', duration: 2000, icon: 'none'}); uni.showToast({title: '修改成功', duration: 1000, icon: 'none'});
dataHandling.pocessTracking( dataHandling.pocessTracking(
'个人资料', '个人资料',
`成功修改个人资料`, `成功修改个人资料`,
......
...@@ -26,7 +26,10 @@ ...@@ -26,7 +26,10 @@
<view class="bottomItem" v-for="score in scoreList " :key="score.id"> <view class="bottomItem" v-for="score in scoreList " :key="score.id">
<!-- @click="gotoRecord(score.id)" --> <!-- @click="gotoRecord(score.id)" -->
<view class="one" > <view class="one" >
<view style="font-size:28rpx;color: rgba(199, 199, 199, 1);"> <view
@click="gotoRecord(score.id)"
style="font-size:28rpx;color: rgba(199, 199, 199, 1);"
>
{{score.name}} {{score.name}}
</view> </view>
<uni-tooltip class="item" :content="score.content" :placement="score.position"> <uni-tooltip class="item" :content="score.content" :placement="score.position">
......
...@@ -476,6 +476,9 @@ ...@@ -476,6 +476,9 @@
color: #fff; color: #fff;
border-radius: 40rpx; border-radius: 40rpx;
background-color: #20269B; background-color: #20269B;
display: flex;
align-items: center;
justify-content: center;
} }
} }
.orderNum{ .orderNum{
......
...@@ -55,6 +55,30 @@ ...@@ -55,6 +55,30 @@
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib"> <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>
</li>
<li class="dib">
<span class="icon iconfont">&#xe334;</span> <span class="icon iconfont">&#xe334;</span>
<div class="name">微信</div> <div class="name">微信</div>
<div class="code-name">&amp;#xe334;</div> <div class="code-name">&amp;#xe334;</div>
...@@ -426,9 +450,9 @@ ...@@ -426,9 +450,9 @@
<pre><code class="language-css" <pre><code class="language-css"
>@font-face { >@font-face {
font-family: 'iconfont'; font-family: 'iconfont';
src: url('iconfont.woff2?t=1754993772709') format('woff2'), src: url('iconfont.woff2?t=1755827337778') format('woff2'),
url('iconfont.woff?t=1754993772709') format('woff'), url('iconfont.woff?t=1755827337778') format('woff'),
url('iconfont.ttf?t=1754993772709') format('truetype'); url('iconfont.ttf?t=1755827337778') format('truetype');
} }
</code></pre> </code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
...@@ -455,6 +479,42 @@ ...@@ -455,6 +479,42 @@
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib"> <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">
对号
</div>
<div class="code-name">.icon-duihao
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-weixin1"></span> <span class="icon iconfont icon-weixin1"></span>
<div class="name"> <div class="name">
微信 微信
...@@ -1014,6 +1074,38 @@ ...@@ -1014,6 +1074,38 @@
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <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>
<div class="code-name">#icon-duihao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-weixin1"></use> <use xlink:href="#icon-weixin1"></use>
</svg> </svg>
<div class="name">微信</div> <div class="name">微信</div>
......
@font-face { @font-face {
font-family: "iconfont"; /* Project id 4933433 */ font-family: "iconfont"; /* Project id 4933433 */
src: url('iconfont.woff2?t=1754993772709') format('woff2'), src: url('iconfont.woff2?t=1755827337778') format('woff2'),
url('iconfont.woff?t=1754993772709') format('woff'), url('iconfont.woff?t=1755827337778') format('woff'),
url('iconfont.ttf?t=1754993772709') format('truetype'); url('iconfont.ttf?t=1755827337778') format('truetype');
} }
.iconfont { .iconfont {
...@@ -13,6 +13,22 @@ ...@@ -13,6 +13,22 @@
-moz-osx-font-smoothing: grayscale; -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";
}
.icon-weixin1:before { .icon-weixin1:before {
content: "\e334"; content: "\e334";
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -6,6 +6,34 @@ ...@@ -6,6 +6,34 @@
"description": "", "description": "",
"glyphs": [ "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",
"unicode": "e338",
"unicode_decimal": 58168
},
{
"icon_id": "859693", "icon_id": "859693",
"name": "微信", "name": "微信",
"font_class": "weixin1", "font_class": "weixin1",
......
...@@ -392,5 +392,17 @@ export default{ ...@@ -392,5 +392,17 @@ export default{
// 3. 刘海屏设备safe-area-inset-top通常大于20(非刘海屏为0) // 3. 刘海屏设备safe-area-inset-top通常大于20(非刘海屏为0)
return computedHeight > 20; 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
...@@ -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 = {
...@@ -131,3 +103,53 @@ export function setWechatShare(data) { ...@@ -131,3 +103,53 @@ export function setWechatShare(data) {
},url) },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
import html2canvas from 'html2canvas'; import html2canvas from 'html2canvas';
import {baseURL,apiURL,cffpURL,sfpUrl,imgUrl,scrmUrl} from "../environments/environment";
/** /**
* 将DOM元素转换为图片 * 将DOM元素转换为图片
...@@ -13,10 +14,10 @@ export const elementToImage = async (element, options = {}) => { ...@@ -13,10 +14,10 @@ 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) {
...@@ -24,3 +25,29 @@ export const elementToImage = async (element, options = {}) => { ...@@ -24,3 +25,29 @@ export const elementToImage = async (element, options = {}) => {
throw error; throw error;
} }
}; };
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";
// // 白名单,不需要携带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`,
// ];
// // 判断是否为资源请求(图片、字体等)
// const isResourceRequest = (url) => {
// const resourceExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.ttf', '.woff', '.woff2'];
// return resourceExtensions.some(ext => url.includes(ext));
// };
// export const interceptor = () => {
// uni.addInterceptor('request', {
// // 请求拦截器
// invoke(args) {
// // 资源请求不添加认证头,避免触发OPTIONS预检请求
// if (isResourceRequest(args.url)) {
// // 对于资源请求,使用更简单的请求头
// args.header = {
// 'content-type': 'application/x-www-form-urlencoded'
// };
// return;
// }
// // 当本地没有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();
// }
// }
// })
// }
// // 设置API请求头及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') : '',
// }
// },
// // 响应拦截器,可以对数据进行预处理
// 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"; import api from "@/api/api";
// 白名单,不需要携带token就允许被访问的接口 // 白名单,不需要携带token就允许被访问的接口
const whiteApiList = [`${apiURL}/authorize/obtainToken`, const whiteApiList = [`${apiURL}/authorize/obtainToken`,
......
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