|
|
@@ -0,0 +1,399 @@
|
|
|
+<script lang="ts" setup>
|
|
|
+import { storeToRefs } from 'pinia'
|
|
|
+import { ref } from 'vue'
|
|
|
+import CustomNavigationBar from '@/components/CustomNavigationBar.vue'
|
|
|
+import { useInviteCodeStore } from '@/store/inviteQCCode'
|
|
|
+import { useInviterStore } from '@/store/inviter'
|
|
|
+import { safeAreaInsets } from '@/utils'
|
|
|
+import { getImageUrl } from '@/utils/imageUtil'
|
|
|
+
|
|
|
+definePage({
|
|
|
+ style: {
|
|
|
+ navigationBarTitleText: '我的邀请人',
|
|
|
+ navigationStyle: 'custom',
|
|
|
+ },
|
|
|
+})
|
|
|
+
|
|
|
+const inviteCodeStore = useInviteCodeStore()
|
|
|
+const inviterStore = useInviterStore()
|
|
|
+const { inviter: inviterInfo } = storeToRefs(inviterStore)
|
|
|
+const title = ref('掌柜369')
|
|
|
+const descText = ref('天天领券,笔笔省!吃喝玩乐,优惠随身!')
|
|
|
+const telephoneText = ref('400-633-3016')
|
|
|
+const qrCode = ref('')
|
|
|
+
|
|
|
+async function drawQRCode() {
|
|
|
+ const qrCodeImg = await inviteCodeStore.getInviteCode()
|
|
|
+ if (qrCodeImg) {
|
|
|
+ try {
|
|
|
+ let imgSrc = qrCodeImg
|
|
|
+ let tempFilePath = ''
|
|
|
+
|
|
|
+ // 检查是否已经是临时文件路径
|
|
|
+ const isTempFile = typeof qrCodeImg === 'string' && !qrCodeImg.startsWith('data:image')
|
|
|
+
|
|
|
+ // 如果是临时文件路径,直接使用
|
|
|
+ if (isTempFile) {
|
|
|
+ tempFilePath = qrCodeImg
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 处理base64图片数据
|
|
|
+ if (typeof qrCodeImg === 'string') {
|
|
|
+ // 安全地尝试解码URI,避免URIError
|
|
|
+ try {
|
|
|
+ if (qrCodeImg.includes('%')) {
|
|
|
+ imgSrc = decodeURIComponent(qrCodeImg)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (uriError) {
|
|
|
+ console.warn('URI解码失败,使用原始数据:', uriError)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保base64数据有正确的前缀
|
|
|
+ if (!imgSrc.startsWith('data:image')) {
|
|
|
+ imgSrc = `data:image/png;base64,${imgSrc}`
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 尝试使用临时文件方式
|
|
|
+ try {
|
|
|
+ // #ifdef MP-WEIXIN
|
|
|
+ const fs = uni.getFileSystemManager()
|
|
|
+ const tempFileName = `temp_qr_${Date.now()}.png`
|
|
|
+ tempFilePath = `${uni.env.USER_DATA_PATH}/${tempFileName}`
|
|
|
+
|
|
|
+ // 提取base64数据部分
|
|
|
+ let base64Data = imgSrc
|
|
|
+ if (imgSrc.includes('base64,')) {
|
|
|
+ base64Data = imgSrc.split('base64,')[1]
|
|
|
+ }
|
|
|
+
|
|
|
+ fs.writeFileSync(tempFilePath, base64Data, 'base64')
|
|
|
+ console.log('Base64已转换为临时文件:', tempFilePath)
|
|
|
+ // #endif
|
|
|
+ }
|
|
|
+ catch (fileError) {
|
|
|
+ console.warn('转换base64为临时文件失败,尝试直接使用base64:', fileError)
|
|
|
+ // 清除临时文件路径,确保使用base64
|
|
|
+ tempFilePath = ''
|
|
|
+ }
|
|
|
+ }
|
|
|
+ qrCode.value = tempFilePath || imgSrc
|
|
|
+
|
|
|
+ console.log('二维码绘制成功')
|
|
|
+ }
|
|
|
+ catch (error) {
|
|
|
+ console.error('绘制二维码失败:', error)
|
|
|
+
|
|
|
+ // 增加更详细的错误日志
|
|
|
+ if (typeof qrCodeImg === 'string') {
|
|
|
+ console.log('二维码数据源类型:', qrCodeImg.startsWith('data:image') ? 'base64' : '临时文件路径')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onShow(async () => {
|
|
|
+ await drawQRCode()
|
|
|
+})
|
|
|
+
|
|
|
+// 保存图片到相册
|
|
|
+async function handleSaveImage() {
|
|
|
+ if (!qrCode.value) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请先生成分享图片',
|
|
|
+ icon: 'none',
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ uni.showLoading({
|
|
|
+ title: '保存中...',
|
|
|
+ mask: true,
|
|
|
+ })
|
|
|
+
|
|
|
+ try {
|
|
|
+ await uni.saveImageToPhotosAlbum({
|
|
|
+ filePath: qrCode.value,
|
|
|
+ })
|
|
|
+
|
|
|
+ uni.hideLoading()
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存成功',
|
|
|
+ icon: 'success',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ catch (error) {
|
|
|
+ uni.hideLoading()
|
|
|
+ console.error('保存失败:', error)
|
|
|
+
|
|
|
+ if (error.errMsg && error.errMsg.includes('auth deny')) {
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '需要您授权保存到相册',
|
|
|
+ confirmText: '去设置',
|
|
|
+ success: (res) => {
|
|
|
+ if (res.confirm) {
|
|
|
+ uni.openSetting()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ uni.showToast({
|
|
|
+ title: '保存失败,请重试',
|
|
|
+ icon: 'none',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <view class="my-inviter-container"
|
|
|
+ :style="{ backgroundImage: `url(${getImageUrl('@img/me/myInviter-card-bg.png')})`, paddingTop: `calc(${safeAreaInsets.top}px + 88rpx)`, height: `calc(100vh - ${safeAreaInsets.top}px - 88rpx)` }">
|
|
|
+ <custom-navigation-bar :show-back="true" title="我的邀请人" back-icon-color="#ffffff" text-color="#ffffff"
|
|
|
+ background-color="transparent" :is-shadow="false" />
|
|
|
+ <view />
|
|
|
+ <view class="inviter-content" :style="{ backgroundImage: `url(${getImageUrl('@img/me/myInviter-bg.png')})` }">
|
|
|
+ <view class="my-inviter-content">
|
|
|
+ <view class="title">
|
|
|
+ <view class="icon" />
|
|
|
+ <text class="text">我的邀请人</text>
|
|
|
+ </view>
|
|
|
+ <view class="content">
|
|
|
+ <up-image :src="inviterInfo.avatarUrl" width="114rpx" height="114rpx" shape="circle" />
|
|
|
+ <view class="inviter-name">
|
|
|
+ <text class="text">{{ inviterInfo.nickname }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="my-qcCode">
|
|
|
+ <view class="title">
|
|
|
+ <view class="icon" />
|
|
|
+ <text class="text">我的邀请码</text>
|
|
|
+ </view>
|
|
|
+ <view class="qcCode-content">
|
|
|
+ <view class="qcCode-image">
|
|
|
+ <image :src="qrCode" class="qcCode" />
|
|
|
+ </view>
|
|
|
+ <view class="qcCode-title">
|
|
|
+ 邀请码
|
|
|
+ </view>
|
|
|
+ <view class="qcCode-desc">
|
|
|
+ 发放优惠券、分享得佣金,下单尽享优惠,快来<br>邀请好友吧!
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="invite-button">
|
|
|
+ <up-button class="btn" shape="circle" @tap="handleSaveImage">
|
|
|
+ 保存到相册
|
|
|
+ </up-button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="bottom-content">
|
|
|
+ <view class="logo">
|
|
|
+ <image :src="getImageUrl('@img/index/logo.jpg')" class="logo-image" />
|
|
|
+ <view class="logo-title-text">
|
|
|
+ {{ title }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="desc-text">
|
|
|
+ {{ descText }}
|
|
|
+ </view>
|
|
|
+ <view class="telephone">
|
|
|
+ <view class="telephone-text">
|
|
|
+ <up-icon name="phone-fill" color="#974542" size="24rpx" />
|
|
|
+ <text class="text">客服热线:{{ telephoneText }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.my-inviter-container {
|
|
|
+ width: 100vw;
|
|
|
+ background-repeat: repeat-y;
|
|
|
+ background-position: right;
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .inviter-content {
|
|
|
+ width: 634rpx;
|
|
|
+ height: 943rpx;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: cover;
|
|
|
+ margin-top: 61rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .my-inviter-content {
|
|
|
+ height: 194rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .content {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ padding-left: 47rpx;
|
|
|
+ align-items: center;
|
|
|
+ gap: 21rpx;
|
|
|
+
|
|
|
+ .inviter-name {
|
|
|
+ font-weight: bolder;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .my-qcCode {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .qcCode-content {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-around;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .qcCode-image {
|
|
|
+ width: 317rpx;
|
|
|
+ height: 313rpx;
|
|
|
+
|
|
|
+ margin-bottom: 53rpx;
|
|
|
+
|
|
|
+ .qcCode {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .qcCode-title {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ margin-bottom: 9rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .qcCode-desc {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #979797;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .invite-button {
|
|
|
+ height: 145rpx;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ width: 262rpx;
|
|
|
+ height: 70rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .title {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ gap: 16rpx;
|
|
|
+ padding: 20rpx 26rpx;
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ width: 6rpx;
|
|
|
+ height: 33rpx;
|
|
|
+ background: #ed6b66;
|
|
|
+ border-radius: 3rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .text {
|
|
|
+ height: 25rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom-content {
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ padding: 30rpx 40rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 14rpx;
|
|
|
+
|
|
|
+ .logo {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ gap: 16rpx;
|
|
|
+
|
|
|
+ .logo-image {
|
|
|
+ width: 80rpx;
|
|
|
+ height: 80rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ border: 2rpx solid #ffffff;
|
|
|
+ box-shadow: 0rpx 0rpx 5rpx 0rpx rgba(175, 175, 175, 0.39);
|
|
|
+ }
|
|
|
+
|
|
|
+ .logo-title-text {
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #974542;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .desc-text {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #974542;
|
|
|
+ }
|
|
|
+
|
|
|
+ .telephone {
|
|
|
+ width: 414rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ border-radius: 19rpx;
|
|
|
+ border: 1px solid #974542;
|
|
|
+
|
|
|
+ padding: 9rpx 68rpx;
|
|
|
+
|
|
|
+ .telephone-text {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .text {
|
|
|
+ margin-left: 6rpx;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #974542;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|