| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- <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>
|