feat: update
This commit is contained in:
3
src/pages/partner-share-vip/index.config.ts
Normal file
3
src/pages/partner-share-vip/index.config.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '赠送会员',
|
||||
});
|
||||
182
src/pages/partner-share-vip/index.less
Normal file
182
src/pages/partner-share-vip/index.less
Normal file
@ -0,0 +1,182 @@
|
||||
@import '@/styles/variables.less';
|
||||
@import '@/styles/common.less';
|
||||
|
||||
.share-vip {
|
||||
background: #eae5fb;
|
||||
padding-top: 200px;
|
||||
position: relative;
|
||||
padding-bottom: calc(142px + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(142px + env(safe-area-inset-bottom));
|
||||
|
||||
&__bg {
|
||||
width: 100%;
|
||||
height: 705px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&__slogan {
|
||||
top: 66px;
|
||||
left: 44px;
|
||||
position: absolute;
|
||||
font-family: 'Alimama ShuHeiTi';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 44px;
|
||||
line-height: 62px;
|
||||
color: #333333;
|
||||
|
||||
> div {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
&-highlight {
|
||||
display: inline-block;
|
||||
padding-left: 12px;
|
||||
padding-right: 9px;
|
||||
font-size: 64px;
|
||||
line-height: 62px;
|
||||
background: linear-gradient(87.53deg, #683DE3 0.4%, #39227D 84.55%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&__main {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&__highlight {
|
||||
color: @blHighlightColor;
|
||||
font-family: 'DIN Alternate';
|
||||
padding: 0 8px;
|
||||
font-weight: 700;
|
||||
display: inline-block;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
&__block {
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__card {
|
||||
background: #fff;
|
||||
border-radius: 24px;
|
||||
padding: 68px 32px 44px;
|
||||
}
|
||||
|
||||
&__h1 {
|
||||
font-weight: 500;
|
||||
font-size: 32px;
|
||||
line-height: 40px;
|
||||
color: #1d2129;
|
||||
margin-bottom: 16px;
|
||||
margin-top: 32px;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: #ffd236;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: -6px;
|
||||
top: -3px;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
&__body {
|
||||
font-weight: 400;
|
||||
font-size: 28px;
|
||||
line-height: 40px;
|
||||
color: @blColor;
|
||||
|
||||
&.grey {
|
||||
color: @blColorG2;
|
||||
}
|
||||
|
||||
&.center {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin-left: 48px;
|
||||
margin-right: 48px;
|
||||
font-weight: 500;
|
||||
font-size: 32px;
|
||||
line-height: 80px;
|
||||
height: 80px;
|
||||
transform: translateY(50%);
|
||||
background: #ffd236;
|
||||
box-shadow: 0px 12px 0px #ffa35d;
|
||||
border-radius: 60px;
|
||||
color: #1d2129;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__service {
|
||||
.button(@height: 72px; @width: 384px; @fontSize: 28px; @fontWeight: 400; @borderRadius: 44px; @highlight: 0);
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
&__tip {
|
||||
margin-top: 24px;
|
||||
font-size: 24px;
|
||||
line-height: 40px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
width: 100vw;
|
||||
background: #ffffff;
|
||||
padding: 12px 32px;
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 12px);
|
||||
/* 兼容 iOS < 11.2 */
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 12px);
|
||||
/* 兼容 iOS >= 11.2 */
|
||||
box-shadow: 0px -4px 20px 0px #00000014;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
box-sizing: border-box;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__download-button {
|
||||
flex: 1 1;
|
||||
.button(@height: 88px; @fontSize: 32px; @fontWeight: 500; @borderRadius: 44px; @highlight: 0);
|
||||
}
|
||||
|
||||
&__share-button {
|
||||
flex: 2 2;
|
||||
width: 406px;
|
||||
.button(@height: 88px; @fontSize: 32px; @fontWeight: 500; @borderRadius: 44px;);
|
||||
margin-left: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
#posterCanvas {
|
||||
position: fixed;
|
||||
bottom: -99999px;
|
||||
left: -99999px;
|
||||
visibility: hidden;
|
||||
}
|
||||
191
src/pages/partner-share-vip/index.tsx
Normal file
191
src/pages/partner-share-vip/index.tsx
Normal file
@ -0,0 +1,191 @@
|
||||
import { Button, Canvas, Image } from '@tarojs/components';
|
||||
import Taro, { useShareAppMessage } from '@tarojs/taro';
|
||||
|
||||
import { PageUrl } from '@/constants/app';
|
||||
import useInviteCode from '@/hooks/use-invite-code';
|
||||
import { generateMembershipCoupon, getCouponQrCode } from '@/utils/coupon';
|
||||
import { getCommonShareMessage } from '@/utils/share';
|
||||
|
||||
import './index.less';
|
||||
|
||||
const PREFIX = 'share-vip';
|
||||
|
||||
export default function PartnerShareVip() {
|
||||
const inviteCode = useInviteCode();
|
||||
|
||||
Taro.showShareMenu({
|
||||
withShareTicket: true,
|
||||
});
|
||||
|
||||
useShareAppMessage(async () => {
|
||||
console.log('Partner inviteCode', inviteCode);
|
||||
const { code } = await generateMembershipCoupon();
|
||||
return getCommonShareMessage({
|
||||
useCapture: false,
|
||||
inviteCode,
|
||||
title: '宝子,送你个播络会员,免费找主播工作',
|
||||
path: PageUrl.GiveVip,
|
||||
params: { d: code },
|
||||
imageUrl: 'https://publiccdn.neighbourhood.com.cn/img/share-coupon1.png',
|
||||
});
|
||||
});
|
||||
|
||||
const getQrcode = async () => {
|
||||
try {
|
||||
const { code } = await generateMembershipCoupon();
|
||||
const data = await getCouponQrCode(code);
|
||||
const base64 = Taro.arrayBufferToBase64(data);
|
||||
return `data:image/png;base64,${base64}`;
|
||||
} catch (error) {
|
||||
console.error('获取二维码失败', error);
|
||||
Taro.showToast({ title: '获取二维码失败', icon: 'none' });
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
const saveCanvasToTempFile = (): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const query = Taro.createSelectorQuery().select('#posterCanvas');
|
||||
query.fields({ node: true }).exec(async res => {
|
||||
const canvas = res[0].node;
|
||||
const tempFilePath = await Taro.canvasToTempFilePath({
|
||||
canvas,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 1500, // 实际绘制宽度
|
||||
height: 2668, // 实际绘制高度
|
||||
destWidth: 750, // 目标显示宽度
|
||||
destHeight: 1334, // 目标显示高度
|
||||
fileType: 'png',
|
||||
});
|
||||
|
||||
resolve(tempFilePath.tempFilePath);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('保存 Canvas 到临时文件失败', error);
|
||||
Taro.showToast({ title: '保存 Canvas 失败', icon: 'none' });
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
const drawCanvas = (qrCode: string): Promise<string> => {
|
||||
const query = Taro.createSelectorQuery().select('#posterCanvas');
|
||||
return new Promise(resolve => {
|
||||
query.fields({ node: true, size: true }).exec(async res => {
|
||||
const canvas = res[0].node;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = 550 * 2;
|
||||
canvas.height = 918 * 2;
|
||||
ctx.scale(2, 2);
|
||||
|
||||
// 绘制背景图片
|
||||
const bgImage = canvas.createImage();
|
||||
const poster = 'https://publiccdn.neighbourhood.com.cn/img/share-coupon-poster2.png';
|
||||
bgImage.src = poster;
|
||||
bgImage.onload = () => {
|
||||
ctx.drawImage(bgImage, 0, 0, 550, 918);
|
||||
|
||||
const qrCodeImage = canvas.createImage();
|
||||
qrCodeImage.src = qrCode; // 假设 getQrcode() 返回的是二维码图片的路径
|
||||
qrCodeImage.onload = () => {
|
||||
ctx.drawImage(qrCodeImage, 196, 600, 180, 160); // 绘制二维码,位置和大小
|
||||
saveCanvasToTempFile().then(tempPath => {
|
||||
resolve(tempPath);
|
||||
});
|
||||
};
|
||||
};
|
||||
bgImage.onerror = err => {
|
||||
console.error(err);
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
const savePoster = async () => {
|
||||
Taro.showLoading({ title: '正在生成海报' });
|
||||
const qrCode = await getQrcode();
|
||||
const filePath = await drawCanvas(qrCode);
|
||||
Taro.hideLoading();
|
||||
|
||||
const res = await Taro.getSetting();
|
||||
const hasPermission = res.authSetting['scope.writePhotosAlbum'];
|
||||
if (hasPermission === false) {
|
||||
Taro.showModal({
|
||||
title: '提示',
|
||||
content: '需要访问相册权限才能保存图片,请前往设置开启权限',
|
||||
showCancel: false,
|
||||
success() {
|
||||
Taro.openSetting();
|
||||
},
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
await Taro.authorize({ scope: 'scope.writePhotosAlbum' });
|
||||
await Taro.saveImageToPhotosAlbum({ filePath });
|
||||
Taro.showToast({ title: '保存成功', icon: 'success' });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
Taro.showToast({ title: '保存失败', icon: 'none' });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={PREFIX}>
|
||||
<Image
|
||||
src="https://publiccdn.neighbourhood.com.cn/img/partner-share-vip-bg.png"
|
||||
className={`${PREFIX}__bg`}
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<div className={`${PREFIX}__slogan`}>
|
||||
<div>
|
||||
会员可每日<div className={`${PREFIX}__slogan-highlight`}>免费查看</div>
|
||||
</div>
|
||||
<div>通告联系方式</div>
|
||||
</div>
|
||||
<div className={`${PREFIX}__main`}>
|
||||
<div className={`${PREFIX}__block`}>
|
||||
<div className={`${PREFIX}__title`}>赠送会员</div>
|
||||
<div className={`${PREFIX}__card`}>
|
||||
<div className={`${PREFIX}__h1`}>方法一:</div>
|
||||
<div className={`${PREFIX}__body`}>点击下方"立即赠送"即可分享赠送卡片,对方点击卡片即可领取</div>
|
||||
<div className={`${PREFIX}__h1`}>方法二:</div>
|
||||
<div className={`${PREFIX}__body`}>点击"朋友圈海报"获得图片,分享到朋友圈,对方扫码即可领取</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${PREFIX}__block`}>
|
||||
<div className={`${PREFIX}__title`}>赠送规则</div>
|
||||
<div className={`${PREFIX}__card`}>
|
||||
<div className={`${PREFIX}__body`}>
|
||||
<div className={`${PREFIX}__h1`}>规则一:</div>
|
||||
<div>每次分享的赠送链接或者图片在7天内有效</div>
|
||||
<div className={`${PREFIX}__h1`}>规则二:</div>
|
||||
<div>每个用户一周最多只能领取一次会员</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${PREFIX}__block`}>
|
||||
<div className={`${PREFIX}__title`}>分享建议</div>
|
||||
<div className={`${PREFIX}__card`}>
|
||||
<div className={`${PREFIX}__body`}>
|
||||
<div className={`${PREFIX}__h1`}>建议一:</div>
|
||||
<div>每周在朋友圈或者群中分享一次,效果最佳 可以写明:新会员来啦</div>
|
||||
<div className={`${PREFIX}__h1`}>建议二:</div>
|
||||
<div>分享得越多,邀请的人会越多,也会更活跃,更容易获得分成</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Canvas id="posterCanvas" canvas-id="posterCanvas" type="2d" style="width: 750px; height: 1334px;" />
|
||||
|
||||
<div className={`${PREFIX}__footer`}>
|
||||
<Button className={`${PREFIX}__download-button`} onClick={savePoster}>
|
||||
朋友圈海报
|
||||
</Button>
|
||||
<Button className={`${PREFIX}__share-button`} openType="share">
|
||||
立即赠送
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user