🐞 fix(ID1000938): 【蜘蛛管家】邀请码- UI还原不足

【蜘蛛管家】邀请码- UI还原不足】 https://www.tapd.cn/53459131/bugtrace/bugs/view/1153459131001000938
This commit is contained in:
xuan
2022-12-09 13:44:43 +08:00
parent fa267fa5a9
commit e73c87cf6f
10 changed files with 1179 additions and 95 deletions
+45 -38
View File
@@ -7,11 +7,11 @@ page {
display: flex;
flex-flow: column nowrap;
height: 100%;
background: linear-gradient(to bottom, #E4EEFD 25%, $color_bg_one 42%);
background: linear-gradient(to bottom, #e4eefd 25%, $color_bg_one 42%);
padding-bottom: 0;
box-sizing: border-box;
overflow-y: scroll;
.content{
.content {
flex: 1 1 auto;
overflow: scroll;
}
@@ -24,85 +24,88 @@ page {
align-items: center;
justify-content: space-between;
overflow: hidden;
.left{
.title{
padding-bottom: 15px;
.left {
.title {
padding-bottom: 5px;
font-size: 60px;
font-weight: 500;
}
.description{
.description {
font-size: 28px;
color: #848689;
font-weight: 400;
}
}
.right{
.iconContainer{
.right {
.iconContainer {
width: 260px;
position: relative;
bottom: -36px;
.icon{
.icon {
width: 130%;
}
}
}
}
.codeBar{
.inviteCodeContent {
position: relative;
top: -20px;
}
.codeBar {
border-radius: 15px;
background-color: #f7f8fa;
padding: 40px 0;
.inviteCodeBar{
.inviteCodeBar {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
margin-bottom: 16px;
.invite{
.invite {
padding: 0 40px;
font-size: 46px;
font-weight: 500;
color: #337FFF;
color: #337fff;
line-height: 65px;
}
}
}
.tips{
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
font-size: 24px;
font-weight: 400;
color: #9fa0a1;
line-height: 28px;
padding: 0 40px;
}
.inviteListTitle{
.tips {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
font-size: 24px;
font-weight: 400;
color: #9fa0a1;
line-height: 28px;
padding: 0 40px;
}
.inviteListTitle {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
padding-top: 15px;
padding-bottom: 30px;
.listTitle{
.listTitle {
padding: 0 20px;
font-size: 32px;
font-weight: 500;
color: #000000;
}
.titleIconLeft{
.titleIconLeft {
width: 24px;
height: 4px;
background: linear-gradient(270deg, #333333 0%, rgba(51,51,51,0) 100%);
background: linear-gradient(270deg, #333333 0%, rgba(51, 51, 51, 0) 100%);
opacity: 0.3;
}
.titleIconRight{
.titleIconRight {
width: 24px;
height: 4px;
background: linear-gradient(270deg, rgba(51,51,51,0) 0%, #333333 100%);
background: linear-gradient(270deg, rgba(51, 51, 51, 0) 0%, #333333 100%);
opacity: 0.3;
}
}
.bottomBar {
flex: none;
@@ -111,27 +114,31 @@ page {
justify-content: space-between;
align-items: center;
padding-top: 24px;
padding-right: 24px;
padding-left: 24px;
padding-right: 48px;
padding-left: 48px;
background-color: #ffffff;
padding-bottom: calc(20px + constant(safe-area-inset-bottom));
padding-bottom: calc(20px + env(safe-area-inset-bottom));
&__text{
font-weight: 500;
}
}
.codePreview{
.codePreview {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
position: relative;
.imageContainer{
top: -120px;
.imageContainer {
width: 80vw;
height: auto;
.image{
.image {
width: 100%;
height: 100%;
}
}
.previewTips{
.previewTips {
position: absolute;
bottom: -80px;
font-size: 40px;
+130 -55
View File
@@ -1,9 +1,9 @@
import { Canvas, Image, Text, View } from '@tarojs/components'
import Taro, { useReady } from '@tarojs/taro'
import { useCallback, useRef, useState } from 'react'
import React, { useCallback, useRef, useState } from 'react'
import { imageAudit } from '@tarojs/taro-h5'
import style from './index.module.scss'
import inviteCodePng from './inviteCode.png'
import inviteCodePng from './inviteCodePopupX2.png'
import QRcode from './inviteCodePopup.png'
import Dialog from '@/components/Dialog'
import LayoutBlock from '@/components/layoutBlock'
@@ -14,6 +14,40 @@ import NormalButton from '@/components/normalButton'
import { alert } from '@/common/common'
import { GenBarCodeOrQrCode, GetInvitationInfo } from '@/api'
import { getCDNSource } from '@/common/constant'
import Painter from '@/components/painter'
const SystemInfo = Taro.getSystemInfoSync()
let screenK = 5
/**
* 是否支持负数
* @param {Boolean} minus 是否支持负数
*/
const toPx = (num: string, minus = false) => {
let reg
if (minus) {
reg = /^-?[0-9]+([.]{1}[0-9]+){0,1}(rpx|px)$/g
}
else {
reg = /^[0-9]+([.]{1}[0-9]+){0,1}(rpx|px)$/g
}
const results = reg.exec(num)
console.log('results', results)
if (!num || !results) {
console.log(`The size: ${num} is illegal`)
return 0
}
const unit = results[2]
const value = parseFloat(num)
let res = 0
if (unit === 'rpx') {
res = Math.round(value * screenK)
}
else if (unit === 'px') {
res = value
}
return res
}
// 需要传进来的表头数据示例
const inviteColumns = [
{
@@ -29,8 +63,13 @@ const inviteColumns = [
width: '50%',
},
]
// 邀请码
const InviteCode = () => {
screenK = SystemInfo.screenWidth / 750
const { fetchData } = GetInvitationInfo()
const { fetchData: genCode } = GenBarCodeOrQrCode()
const [inviteInfo, setInviteInfo] = useState<any>({})
@@ -71,14 +110,14 @@ const InviteCode = () => {
}
const [, setForceUpdate] = useState({})
const canvasNode = useRef<any>()
const ctx = useRef<any>(null)
const canvasNode = useRef<Taro.Canvas | null>(null)
const ctx = useRef<Taro.RenderingContext | null>(null)
const [showPopup, setShowPopup] = useState(false)
const [targetImageUrl, setTargetImageUrl] = useState('')
const getImageObject = (canvas, src) => {
return new Promise((resolve, reject) => {
const getImageObject = (canvas: Taro.Canvas, src: string) => {
return new Promise<Taro.Image>((resolve, reject) => {
console.log('getImageObject param', canvas, src)
const img = canvas.createImage()
img.src = src
@@ -95,6 +134,7 @@ const InviteCode = () => {
}
// canvas 生成 图片
const saveCanvasToImage = (canvas) => {
console.log('pixelRatio', SystemInfo.pixelRatio, canvas)
Taro.canvasToTempFilePath({
canvas,
fileType: 'png',
@@ -102,6 +142,9 @@ const InviteCode = () => {
console.log('tempFilePath', res.tempFilePath)
setTargetImageUrl(res.tempFilePath)
},
fail: (error) => {
console.log('error', error)
},
complete: () => {
setLoading(false)
},
@@ -133,44 +176,56 @@ const InviteCode = () => {
})
})
}
const startPaint = async(ctx, canvas, image) => {
console.log('startPaint param', ctx, canvas, image)
const doublePick = (num, minus = false) => {
if (minus) {
return num / 2
}
else {
return num * 2
}
}
const [canvasStyle, setCanvasStyle] = useState<React.CSSProperties>({})
const painter = useRef<any>(null)
const startPaint = async(ctx: Taro.RenderingContext, canvas: Taro.Canvas, image: Taro.Image) => {
// 开始绘制
const { width, height } = canvas
console.log('startPaint param', ctx, canvas, image)
const cCanvasCtx = ctx as any
cCanvasCtx.clearRect(0, 0, canvas.width, canvas.height)
cCanvasCtx.drawImage(image, 0, 0, canvas.width, canvas.height)
cCanvasCtx.clearRect(0, 0, width, height)
cCanvasCtx.drawImage(image, 0, 0, width, height)
cCanvasCtx.save()
cCanvasCtx.font = `${40}px 微软雅黑`
cCanvasCtx.font = `${doublePick(40)}px 微软雅黑`
cCanvasCtx.fillStyle = '#000000'
cCanvasCtx.fillText('蜘蛛管家', 40, 80) // text up above canvas
cCanvasCtx.fillText('蜘蛛管家', doublePick(40), doublePick(80)) // text up above canvas
cCanvasCtx.save()
cCanvasCtx.font = `${26}px 微软雅黑`
cCanvasCtx.font = `${doublePick(26)}px 微软雅黑`
cCanvasCtx.fillStyle = '#8f9398'
cCanvasCtx.fillText('真挚邀请您建立合作关系', 40, 130) // text up above canvas
cCanvasCtx.fillText('真挚邀请您建立合作关系', doublePick(40), doublePick(130)) // text up above canvas
cCanvasCtx.save()
cCanvasCtx.font = `${24}px 微软雅黑`
cCanvasCtx.font = `${doublePick(24)}px 微软雅黑`
cCanvasCtx.fillStyle = '#a6a6a6'
cCanvasCtx.fillText('请前往邀请码页面,进行扫描邀请', 100, 630) // text up above canvas
cCanvasCtx.fillText('请前往邀请码页面,进行扫描邀请', doublePick(100), doublePick(630)) // text up above canvas
cCanvasCtx.save()
cCanvasCtx.font = `${36}px 微软雅黑`
cCanvasCtx.font = `${doublePick(36)}px 微软雅黑`
cCanvasCtx.fillStyle = '#7f7f7f'
cCanvasCtx.fillText('邀 请 码', 72, 730) // text up above canvas
cCanvasCtx.fillText('邀 请 码', doublePick(72), doublePick(730)) // text up above canvas
cCanvasCtx.save()
cCanvasCtx.font = `${24}px 微软雅黑`
cCanvasCtx.font = `${doublePick(24)}px 微软雅黑`
cCanvasCtx.fillStyle = '#cccccc'
cCanvasCtx.fillText('|', 258, 724) // text up above canvas
cCanvasCtx.fillText('|', doublePick(258), doublePick(724)) // text up above canvas
cCanvasCtx.save()
cCanvasCtx.font = `${36}px 微软雅黑`
cCanvasCtx.font = `${doublePick(36)}px 微软雅黑`
cCanvasCtx.fillStyle = '#7f7f7f'
cCanvasCtx.fillText(`${inviteInfo.invitation_code}`, 311, 730) // text up above canvas
cCanvasCtx.fillText(`${inviteInfo.invitation_code}`, doublePick(311), doublePick(730)) // text up above canvas
cCanvasCtx.save()
const codeUrl = await genQRcode()
try {
const code: any = await getImageObject(canvas, codeUrl)
cCanvasCtx.drawImage(code, 110, 213, 342, 342)
const code = await getImageObject(canvas, codeUrl)
cCanvasCtx.drawImage(code, doublePick(110), doublePick(213), doublePick(342), doublePick(342))
}
catch (err) {
console.error('合成二维邀请码失败')
console.error('合成二维邀请码失败', err)
setLoading(false)
throw new Error('合成二维邀请码失败')
}
@@ -186,16 +241,21 @@ const InviteCode = () => {
// 重新初始化canvas
await initCanvas()
}
const canvas = canvasNode.current
const canvas = canvasNode.current!
Taro.getImageInfo({
src: getCDNSource('/user/inviteCodePopup.png'),
success: (res) => {
canvas.width = res.width / 2
canvas.height = res.height / 2
console.log('res==>', res)
canvas.width = res.width
canvas.height = res.height
setCanvasStyle({
width: `${doublePick(canvas.width, true)}px`,
height: `${doublePick(canvas.height, true)}px`,
})
getImageObject(canvas, `${res.path}`).then(async(image) => {
try {
// 开始绘制
await startPaint(ctx.current, canvasNode.current, image)
await startPaint(ctx.current!, canvas, image)
resolve(true)
}
catch (err) {
@@ -217,6 +277,7 @@ const InviteCode = () => {
}
const handleQRcodeShare = async() => {
try {
// painter.current.startPaint()
const flag = await drawPictorial()
if (flag) {
setShowPopup(true)
@@ -233,8 +294,6 @@ const InviteCode = () => {
})
}
const handleChange = (value: boolean) => {
console.log('value', value)
setShowPopup(value)
}
useReady(() => {
@@ -243,7 +302,19 @@ const InviteCode = () => {
initCanvas()
}, 200)
})
const onImgErr = (e) => {
Taro.hideLoading()
console.error('onImgErr', e.error)
Taro.showToast({
title: '生成分享图失败,请刷新页面重试',
})
}
const onImgOK = (e) => {
console.log('onImgOK', e.path)
setTargetImageUrl(e.path)
setShowPopup(true)
Taro.hideLoading()
}
return <View className={style.main}>
<View className={style.content}>
<View className={style.background}>
@@ -257,34 +328,38 @@ const InviteCode = () => {
</View>
</View>
</View>
<LayoutBlock circle customStyle={{ paddingTop: '10px', paddingBottom: '10px' }}>
<View className={style.codeBar}>
<View className={style.inviteCodeBar}>
<View className={style.invite}>邀请码</View>
<Divider direction="vertical" />
<View className={style.invite}>{inviteInfo.invitation_code}</View>
<View className={style.inviteCodeContent}>
<LayoutBlock circle>
<View className={style.codeBar}>
<View className={style.inviteCodeBar}>
<View className={style.invite}>邀请码</View>
<Divider direction="vertical" />
<View className={style.invite}>{inviteInfo.invitation_code}</View>
</View>
<View className={style.tips}>填写邀请码,即可在蜘蛛管家下单购物</View>
</View>
<View className={style.tips}>填写邀请码,即可在蜘蛛管家下单购物</View>
</View>
</LayoutBlock>
<LayoutBlock circle customStyle={{ paddingTop: '10px', paddingBottom: '10px' }}>
<View className={style.inviteListTitle}>
<View className={style.titleIconLeft}></View>
<Text className={style.listTitle}>成功邀请</Text>
<View className={style.titleIconRight}></View>
</View>
<View className={style.inviteList}>
<Table columns={currentTable.columns} emptyText="暂无邀请信息" safeAreaInsetBottom={false} dataSource={currentTable.dataSource} onLoadMore={handleLoadMore}></Table>
</View>
</LayoutBlock>
<View className={style.tips} style={{ justifyContent: 'flex-start' }}>温馨提示:邀请码确定绑定后,不支持解绑。</View>
</LayoutBlock>
<LayoutBlock circle customStyle={{ paddingTop: '10px', paddingBottom: '10px' }}>
<View className={style.inviteListTitle}>
<View className={style.titleIconLeft}></View>
<Text className={style.listTitle}>成功邀请</Text>
<View className={style.titleIconRight}></View>
</View>
<View className={style.inviteList}>
<Table columns={currentTable.columns} emptyText="暂无邀请信息" safeAreaInsetBottom={false} dataSource={currentTable.dataSource} onLoadMore={handleLoadMore}></Table>
</View>
</LayoutBlock>
<View className={style.tips} style={{ justifyContent: 'flex-start' }}>温馨提示:邀请码确定绑定后,不支持解绑。</View>
</View>
</View>
<Canvas style="position: absolute; left: -9999rpx" id="canvas" canvas-id="canvas" type="2d" />
{/* <Painter ref={painter} onImgErr={onImgErr} onImgOK={onImgOK} palette={imgDraw} customStyle={{ position: 'absolute', left: '-9999rpx' }}></Painter> */}
{/* 已踩坑,这里必须设置canvas的style的width和height,单单只设置canvas实例的width和height是不行的。会模糊! */}
<Canvas style={{ position: 'absolute', left: '-9999rpx', ...canvasStyle }} id="canvas" type="2d" />
<View className={style.bottomBar}>
<NormalButton loading={loading} plain type="primary" customStyles={{ width: '45%' }} round onClick={handleQRcodeShare}>
<NormalButton loading={loading} plain type="primary" customTextClassName={style.bottomBar__text} customStyles={{ width: '45%' }} round onClick={handleQRcodeShare}>
二维码分享
</NormalButton>
<NormalButton type="primary" round customStyles={{ width: '45%' }} onClick={handleCopyInviteCode}>
<NormalButton type="primary" round customTextClassName={style.bottomBar__text} customStyles={{ width: '45%' }} onClick={handleCopyInviteCode}>
复制邀请码
</NormalButton>
</View>
Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB