feat: banner

This commit is contained in:
eleanor.mao
2025-04-24 00:43:55 +08:00
parent 7988725223
commit 7aafc3a789
16 changed files with 367 additions and 52 deletions

View File

@ -46,16 +46,31 @@
}
&__kanban {
min-height: 280px;
box-sizing: border-box;
border-radius: 16px;
margin-bottom: 24px;
padding: 36px 40px;
position: relative;
background: #6d3df5;
color: #fff;
&-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
&-content {
position: relative;
min-height: 280px;
box-sizing: border-box;
padding: 36px 40px;
z-index: 1;
}
&-button {
position: absolute;
z-index: 2;
top: 44px;
right: 56px;
font-size: 24px;

View File

@ -1,49 +1,93 @@
import { Button, Image } from '@tarojs/components';
import { BaseEventOrig, Button, ButtonProps, Image } from '@tarojs/components';
import { useState } from 'react';
import { useCallback, useState } from 'react';
import { PageUrl } from '@/constants/app';
import useUserInfo from '@/hooks/use-user-info';
import { navigateTo } from '@/utils/route';
import Toast from '@/utils/toast';
import { requestUserInfo, setPhoneNumber } from '@/utils/user';
import './index.less';
const PREFIX = 'partner-fragment-entry';
function JoinEntry() {
type JoinEntryProps = {
onBindSuccess: () => void;
};
function JoinEntry({ onBindSuccess }: JoinEntryProps) {
const userInfo = useUserInfo();
const hasPhone = !!userInfo.phone;
const handleGetPhoneNumber = useCallback(async (e: BaseEventOrig<ButtonProps.onGetPhoneNumberEventDetail>) => {
const encryptedData = e.detail.encryptedData;
const iv = e.detail.iv;
if (!encryptedData || !iv) {
return Toast.error('取消授权');
}
try {
await setPhoneNumber({ encryptedData, iv });
await requestUserInfo();
Toast.success('绑定成功');
onBindSuccess();
} catch (err) {
Toast.error('绑定失败');
}
}, []);
return (
<div className={`${PREFIX}__join`}>
<div className={`${PREFIX}__join-title`}>
<span className="highlight">75%</span>
</div>
<div className={`${PREFIX}__join-desc`}></div>
<Button className={`${PREFIX}__join-button`}></Button>
{hasPhone && (
<Button className={`${PREFIX}__join-button`} onClick={onBindSuccess}>
</Button>
)}
{!hasPhone && (
<Button className={`${PREFIX}__join-button`} openType="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
</Button>
)}
</div>
);
}
function PartnerKanban() {
const handleNavigate = useCallback(() => {
navigateTo(PageUrl.Partner);
}, []);
return (
<div className={`${PREFIX}__kanban`}>
<div className={`${PREFIX}__kanban-button`}>
<Image
className={`${PREFIX}__kanban-button__image`}
mode="aspectFit"
src={require('@/statics/svg/caret-right.svg')}
/>
</div>
<div className={`${PREFIX}__kanban-total`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>1666.66</div>
</div>
<div className={`${PREFIX}__kanban-details`}>
<div className={`${PREFIX}__kanban-details-part`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>666.23</div>
<Image className={`${PREFIX}__kanban-bg`} src={require('@/statics/png/partner_bg.png')} mode="scaleToFill" />
<div className={`${PREFIX}__kanban-content`}>
<div className={`${PREFIX}__kanban-button`} onClick={handleNavigate}>
<Image
className={`${PREFIX}__kanban-button__image`}
mode="aspectFit"
src={require('@/statics/svg/caret-right.svg')}
/>
</div>
<div className={`${PREFIX}__kanban-details-part`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>666.23</div>
<div className={`${PREFIX}__kanban-total`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>1666.66</div>
</div>
<div className={`${PREFIX}__kanban-details-part`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>666.23</div>
<div className={`${PREFIX}__kanban-details`}>
<div className={`${PREFIX}__kanban-details-part`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>666.23</div>
</div>
<div className={`${PREFIX}__kanban-details-part`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>666.23</div>
</div>
<div className={`${PREFIX}__kanban-details-part`}>
<div className={`${PREFIX}__kanban-title`}></div>
<div className={`${PREFIX}__kanban-money`}>666.23</div>
</div>
</div>
</div>
</div>
@ -51,10 +95,14 @@ function PartnerKanban() {
}
export default function PartnerEntry() {
const [state] = useState(1);
const [state, setState] = useState(1);
// TODO: 开通状态检查
const handleBindSuccess = useCallback(() => {
setState(0);
}, []);
if (state === 0) {
return <JoinEntry />;
return <JoinEntry onBindSuccess={handleBindSuccess} />;
}
return <PartnerKanban />;
}

View File

@ -0,0 +1,123 @@
@import '@/styles/variables.less';
@import '@/styles/common.less';
.partner-intro {
padding-top: 112px;
padding-bottom: calc(112px + constant(safe-area-inset-bottom));
padding-bottom: calc(112px + env(safe-area-inset-bottom));
&__banner {
background: fade(@blHighlightBg, 8);
height: 88px;
line-height: 88px;
text-align: center;
font-size: 28px;
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100vw;
}
&__main {
padding-left: 24px;
padding-right: 24px;
}
&__highlight {
color: @blHighlightColor;
font-family: 'DIN Alternate';
padding: 0 8px;
font-weight: 700;
display: inline-block;
font-size: 40px;
}
&__block {
margin-bottom: 40px;
}
&__card {
background: #fff;
border-radius: 24px;
padding: 24px 32px;
}
&__h1 {
font-weight: 500;
font-size: 32px;
line-height: 40px;
color: #1d2129;
margin-bottom: 16px;
margin-top: 32px;
&:first-child {
margin-top: 0;
}
}
&__body {
font-weight: 400;
font-size: 28px;
line-height: 40px;
}
&__title {
margin-bottom: 24px;
font-weight: 500;
font-size: 32px;
line-height: 32px;
color: #1d2129;
}
&__special {
padding: 32px;
.flex-column();
.partner-intro__body {
text-align: center;
}
}
&__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;
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;
}
&__download-button {
flex: 1 1;
.button(@height: 88px; @fontSize: 32px; @fontWeight: 500; @borderRadius: 44px; @highlight: 0);
}
&__share-button {
flex: 2 2;
.button(@height: 88px; @fontSize: 32px; @fontWeight: 500; @borderRadius: 44px;);
margin-left: 32px;
}
}

View File

@ -0,0 +1,61 @@
import { Button } from '@tarojs/components';
import { useCallback } from 'react';
import { openCustomerServiceChat } from '@/utils/common';
import './index.less';
const PREFIX = 'partner-intro';
export default function PartnerIntro() {
const handleOpenService = useCallback(() => {
openCustomerServiceChat('https://work.weixin.qq.com/kfid/kfc4fcf6b109b3771d7');
}, []);
return (
<div className={PREFIX}>
<div className={`${PREFIX}__banner`}>
<span className={`${PREFIX}__highlight`}>75%</span>
</div>
<div className={`${PREFIX}__main`}>
<div className={`${PREFIX}__block`}>
<div className={`${PREFIX}__card`}>
<div className={`${PREFIX}__h1`}></div>
<div className={`${PREFIX}__body`}>
<span className={`${PREFIX}__highlight`}>20%</span>
</div>
<div className={`${PREFIX}__h1`}></div>
<div className={`${PREFIX}__body`}>
<span className={`${PREFIX}__highlight`}>50%</span>
</div>
<div className={`${PREFIX}__h1`}></div>
<div className={`${PREFIX}__body`}>
<span className={`${PREFIX}__highlight`}>5%</span>
</div>
</div>
</div>
<div className={`${PREFIX}__block`}>
<div className={`${PREFIX}__title`}></div>
<div className={`${PREFIX}__card ${PREFIX}__special`}>
<div className={`${PREFIX}__body`}></div>
<div className={`${PREFIX}__body`}></div>
<Button className={`${PREFIX}__service`} onClick={handleOpenService}>
</Button>
</div>
<div className={`${PREFIX}__tip`}></div>
</div>
</div>
</div>
);
}
export function PartnerIntroFooter() {
return (
<div className={`${PREFIX}__footer`}>
<Button className={`${PREFIX}__download-button`}></Button>
<Button className={`${PREFIX}__share-button`} openType="share">
</Button>
</div>
);
}