Commit eea00ded authored by 天马流星拳's avatar 天马流星拳

feat(首页): 新增理财排行榜功能及相关弹窗

添加理财排行榜模块,包含月榜/总榜切换、奖品展示、用户排名及持仓分布查看功能
新增持仓分布弹窗组件positionpop
添加相关图片资源及样式调整
parent 8fd8883c
{"proName":"华夏理财-模拟理财-20250701","proDesc":"","proPath":"D:\\duiba\\华夏银行\\HuaXiaSimulate_20250701","createTime":1729847802806}
{"proName":"华夏理财-模拟理财-20250701","proDesc":"","proPath":"E:\\兑吧\\code\\tiangongkaiwu-20251203","createTime":1729847802806}
......@@ -7,7 +7,8 @@
top: 0px;
position: relative;
background-color: #e86a3c;
padding-top: 700px;
// padding-top: 700px;
padding-top: 576px;
padding-bottom: 85px;
box-sizing: border-box;
......@@ -242,7 +243,409 @@
.flex_center();
}
}
.ranking_list{
width: 732px;
height: 1071px;
// height: auto;
position: relative;
left: 18px;
// margin-top: 596px;
.sparkBg("homePage/ranking-bg.png");
.ranking_list_title{
width: 100%;
display: flex;
justify-content: center;
padding-top: 12px;
span{
width: 488px;
height: 77px;
.sparkBg("homePage/ranking-title-bg.png");
}
}
.ranking_list_tab{
margin-left: 89.78px;
width: 543px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
padding: 2px 4px;
box-sizing: border-box;
.sparkBg("homePage/ranking-tab.png");
span{
width: 50%;
// height: 60px;
line-height: 51px;
text-align: center;
font-size: 29px;
color: #8c8c8c;
}
.rankingActive{
color: #fff;
width: 295px;
height: 51px;
.sparkBg("homePage/ranking-tab-bg.png");
}
}
.ranking_list_prize{
margin-left: 47.94px;
margin-top: 21px;
width: 620px;
height: auto;
overflow-y: hidden;
overflow-x: auto;
display: flex;
/* 隐藏滚动条 */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
&::-webkit-scrollbar {
display: none; /* Chrome, Safari and Opera */
}
.ranking_list_prize_item{
width: 132px;
margin-right: 8px;
.item_img{
width: 132px;
height: 132px;
border-radius: 19px;
overflow: hidden;
position: relative;
.sparkBg("homePage/ranking-prize-bg.png");
.img{
width: 100%;
height: 100%;
}
.item_img_rank{
position: absolute;
left: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background: #fd7d20;
width: 100%;
height: 36px;
font-size: 20.68px;
color: #fff;
}
}
.item_name{
width: 100%;
text-align: center;
margin-top: 6px;
font-size: 20.3px;
color: #b37513;
font-weight: bold;
}
}
}
.ranking_list_prizeT{
margin-left: 47.94px;
margin-top: 21px;
width: 620px;
height: auto;
overflow: hidden;
display: flex;
justify-content: space-between;
/* 隐藏滚动条 */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
&::-webkit-scrollbar {
display: none; /* Chrome, Safari and Opera */
}
.ranking_list_prize_item{
width: 132px;
.item_img{
width: 132px;
height: 132px;
border-radius: 19px;
overflow: hidden;
position: relative;
.sparkBg("homePage/ranking-prize-bg.png");
.img{
width: 100%;
height: 100%;
}
.item_img_rank{
position: absolute;
left: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
background: #fd7d20;
width: 100%;
height: 36px;
font-size: 20.68px;
color: #fff;
}
}
.item_name{
width: 100%;
text-align: center;
margin-top: 6px;
font-size: 20.3px;
color: #b37513;
font-weight: bold;
}
}
}
.ranking_list_topThree{
margin-top: 15px;
margin-left: 68.47px;
position: relative;
display: flex;
height: 318px;
.topThree-2{
position: absolute;
left: 0;
bottom: 0;
width: 193px;
height: 279px;
.sparkBg("homePage/top-2-bg.png");
.userName{
position: absolute;
left: 0;
width: 100%;
text-align: center;
top: 85px;
}
.score{
position: absolute;
left: 0;
width: 100%;
text-align: center;
top: 115px;
}
}
.topThree-1{
position: absolute;
left: 182px;
bottom: 0;
width: 224px;
height: 318px;
.sparkBg("homePage/top-1-bg.png");
.userName{
position: absolute;
left: 0;
width: 100%;
text-align: center;
top: 95px;
}
.score{
position: absolute;
left: 0;
width: 100%;
text-align: center;
top: 130px;
}
}
.topThree-3{
position: absolute;
left: 390px;
bottom: 0;
width: 193px;
height: 245px;
.sparkBg("homePage/top-3-bg.png");
.userName{
position: absolute;
left: 0;
width: 100%;
text-align: center;
top: 75px;
}
.score{
position: absolute;
left: 0;
width: 100%;
text-align: center;
top: 102px;
}
}
.btn-bg1{
width: 166px;
height: 56px;
.sparkBg("homePage/top-btn1.png");
}
.btn-bg2{
width: 136px;
height: 47px;
.sparkBg("homePage/top-btn2.png");
}
.topThree-2_btn{
position: absolute;
left: 32px;
top: 186px;
}
.topThree-3_btn{
position: absolute;
left: 32px;
top: 160px;
}
.topThree-1_btn{
position: absolute;
left: 31px;
top: 215px;
}
.userName{
font-size: 20.85px;
color: #fff;
font-weight: bold;
}
.score{
font-size: 25.45px;
color: #fff602;
font-weight: bold;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); /* 添加字体投影,增强立体感 */
}
}
.ranking_list_postRanking{
position: absolute;
top: 630px;
left: 31.5px;
width: 655px;
height: 400px;
border-radius: 19px;
overflow: hidden;
padding: 1px 1px 0 1px;
// padding: 10px 15px 15px 15px;
box-sizing: border-box;
background: #fff;
// .sparkBg("homePage/top-list-bg.png");
.postRanking_title{
width: 100%;
display: flex;
// margin-left: 15px;
padding: 0 12px;
// align-items: center;
// padding-top: 10px;
box-sizing: border-box;
height: 89px;
border-radius: 19px 19px 0 0;
overflow: hidden;
justify-content: space-evenly;
.sparkBg("homePage/top-info2-bg.png");
span{
display: inline-block;
height: 89px;
line-height: 89px;
font-size: 27px;
color: #b37513;
font-weight: bold;
text-align: center;
}
.span-1{
width: 15%;
}
.span-2{
width: 25%;
}
.span-3{
width: 25%;
}
.span-4{
width: 25%;
}
}
.postRanking_item_box{
margin-top: 0.1rem;
margin-left: 14px;
height: 160px;
overflow: hidden;
.postRanking_item{
width: 629px;
height: 76px;
border-radius: 9px;
margin-bottom: 15px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: space-evenly;
.sparkBg("homePage/top-info-bg.png");
span{
text-align: center;
}
.span-1{
font-size: 31px;
color: #b37513;
width: 15%;
}
.span-2{
font-size: 18px;
color: #b37513;
width: 25%;
}
.span-3{
font-size: 26px;
color: #fd2b1b;
width: 25%;
}
.span-4{
width: 136px;
height: 47px;
width: 25%;
.sparkBg("homePage/top-btn2.png");
}
}
}
.postRanking_myRanking{
width: 629px;
height: 77px;
display: flex;
align-items: center;
justify-content: space-evenly;
margin-left: 14px;
margin-top: 10px;
color: #fff;
.sparkBg("homePage/top-my-bg.png");
span{
text-align: center;
}
.span-1{
font-size: 31px;
width: 15%;
}
.span-2{
font-size: 18px;
width: 25%;
}
.span-3{
font-size: 26px;
width: 25%;
}
.span-4{
width: 136px;
height: 47px;
width: 25%;
.sparkBg("homePage/top-btn2.png");
}
}
}
.postRanking_expand{
margin-top: 15px;
display: flex;
align-content: center;
justify-content: center;
span{
width: 76px;
height: 24px;
.sparkBg("homePage/top-expand.png");
}
}
}
.expandSty1{
height: 1580px;
}
.expandSty2{
height: 890px !important;
}
.expandSty3{
height: 640px !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.actual_assets {
width: 732px;
height: 459px;
......
......@@ -4,6 +4,7 @@ import './HomePage.less';
import store from "@/store/store.ts";
import { Button, Toast } from "@grace/ui";
import Rulepop from '@/panels/rulepop/rulepop';
import Positionpop from '@/panels/positionpop/positionpop';
import { PageCtrl } from '@/core/ctrls/PageCtrl';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { _asyncThrottle, dateFormatter, formatThousand } from '@/utils/utils';
......@@ -28,6 +29,7 @@ class HomePage extends React.Component<any, any> {
root: HTMLDivElement;
state = {
rankingTab: 1,
curTab: 1, // 1-产品列表 2-我的持仓
unlockObj: {
prizeImg: '',
......@@ -35,6 +37,109 @@ class HomePage extends React.Component<any, any> {
},
order: 0,
backOrder: 1,
// 理财排行榜-奖品列表
rankOptions: [
{
ranking: 1, //排名
name: '100元', //奖品名称
image: '', //图片
},
{
ranking: 2, //排名
name: '100元', //奖品名称
image: '', //图片
},
{
ranking: 3, //排名
name: '100元', //奖品名称
image: '', //图片
}, {
ranking: 4, //排名
name: '100元', //奖品名称
image: '', //图片
}
],
// 理财排行榜-用户信息
rankInfos:[
{
index: 1, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId: 1, //用户id
score: 43.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 2, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 33.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 3, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 23.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 4, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 13.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 5, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 3.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 6, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 43.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 7, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 43.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 8, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 43.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 9, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 43.18, //收益率
meFlag: false //是否是我,为true是
},
{
index: 10, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 43.18, //收益率
meFlag: false //是否是我,为true是
}
],
// 理财排行榜-我的排名
myRank:{
index: 99, //排名,null表示未上榜,前端判断大于等于100,展示99+
userName:'136xxxx7894', // 用户名
userId:1, //用户id
score: 43.18, //收益率
},
isExpand: false,
};
lockArr = [];
......@@ -187,12 +292,19 @@ class HomePage extends React.Component<any, any> {
toggleTab = async (type) => {
this.setState({ curTab: type })
}
// 理财排行榜切换
rankingTab_click = async (type) => {
this.setState({ rankingTab: type })
}
// 查看分布按钮
viewDistribution = (item) => {
console.log("🚀 ~ HomePage ~ item:", item)
ModalCtrl.showModal(Positionpop, { item })
}
settleMoney = (num) => {
return formatThousand((num / 100).toFixed(2))
}
componentWillUnmount(): void {
clearTimeout(this.timer);
/*
......@@ -235,7 +347,7 @@ class HomePage extends React.Component<any, any> {
}
*/
render() {
const { curTab } = this.state;
const { curTab, rankingTab, rankOptions, rankInfos, myRank } = this.state;
const { bigStartConfig, virtualAssets, checkIn, recommendProductConfig, productEnd, endPoint, currentTime, redRainConfig, giftPop } = store.indexData
/*
const redDownTime = this.getRedCountDown(redRainConfig || []);
......@@ -305,6 +417,113 @@ class HomePage extends React.Component<any, any> {
<span className="canuse_popover_text"></span>
</div>
</div> */}
{/* 理财排行榜 */}
<div className={`ranking_list ${this.state.isExpand ? 'expandSty1' : ''}`}>
<div className="ranking_list_title">
<span></span>
</div>
{/* tab切换 */}
<div className="ranking_list_tab">
<span className={rankingTab == 1 ? "rankingActive" : ""} onClick={() => this.rankingTab_click(1)}>月榜</span>
<span className={rankingTab == 2 ? "rankingActive" : ""} onClick={() => this.rankingTab_click(2)}>总榜</span>
</div>
{/* 月榜奖品列表 */}
{ rankingTab == 1 && <div className='ranking_list_prize'>
{
rankOptions?.map((item, index) => (
<div className="ranking_list_prize_item" key={`ranking_prize_${index}`}>
<div className="item_img">
<img className="img" src={item.image}/>
<span className="item_img_rank">
{item.ranking}
</span>
</div>
<div className="item_name">
{item.name}
</div>
</div>
))
}
</div>
}
{/* 总榜奖品列表 */}
{ rankingTab == 2 && <div className='ranking_list_prizeT'>
{
rankOptions?.map((item, index) => (
<div className="ranking_list_prize_item" key={`ranking_prize_${index}`}>
<div className="item_img">
<img className="img" src={item.image}/>
<span className="item_img_rank">
{item.ranking}
</span>
</div>
<div className="item_name">
{item.name}
</div>
</div>
))
}
</div>
}
{/* 前三名 */}
<div className='ranking_list_topThree'>
{/* 第二名 */}
<div className='topThree-2'>
<span className='userName'>{rankInfos[1].userName}</span>
<span className='score'>+{rankInfos[1].score}%</span>
<span className='topThree-2_btn btn-bg2' onClick={() => this.viewDistribution(rankInfos[1])}></span>
</div>
{/* 第三名 */}
<div className='topThree-3'>
<span className='userName'>{rankInfos[2].userName}</span>
<span className='score'>+{rankInfos[2].score}%</span>
<span className='topThree-3_btn btn-bg2' onClick={() => this.viewDistribution(rankInfos[2])}></span>
</div>
{/* 第一名 */}
<div className='topThree-1'>
<span className='userName'>{rankInfos[0].userName}</span>
<span className='score'>+{rankInfos[0].score}%</span>
<span className='topThree-1_btn btn-bg1' onClick={() => this.viewDistribution(rankInfos[0])}></span>
</div>
</div>
{/* 第四名以后以及我的排名 */}
<div className={`ranking_list_postRanking ${this.state.isExpand ? 'expandSty2' : ''}`}>
<div className='postRanking_title'>
<span className='span-1'>排名</span>
<span className='span-2'>用户信息</span>
<span className='span-3'>收益率</span>
<span className='span-4'>持仓分布</span>
</div>
<div className={`postRanking_item_box ${this.state.isExpand ? 'expandSty3' : ''}`}>
{rankInfos
.filter(item => item.index && item.index >= 4 && item.index <= 100)
.map((item, index) => (
<div key={`rank_${item.index}`} className={`postRanking_item`}>
<span className='span-1'>{item.index}</span>
<span className='span-2'>{item.userName}</span>
<span className='span-3'>+{item.score}%</span>
<span className='span-4' onClick={() => this.viewDistribution(item)}></span>
</div>
))
}
</div>
{/* 我的排名 */}
<div className='postRanking_myRanking'>
<span className='span-1'>{myRank.index == null ? '未上榜' : myRank.index >= 100 ? '99+' : myRank.index}</span>
<span className='span-2'>{myRank.userName}</span>
<span className='span-3'>+{myRank.score}%</span>
<span className='span-4' onClick={() => this.viewDistribution(myRank)}></span>
</div>
{/* 展开 */}
<div className='postRanking_expand'>
<span onClick={() => this.setState({isExpand: !this.state.isExpand})}></span>
</div>
</div>
</div>
{/* 真实持仓 */}
<div className="actual_assets">
<div className="rate_wrap">
......
'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import './positionpop.less';
@observer
class Positionpop extends React.Component {
constructor(props) {
super(props);
this.state = {
info:{}
};
}
componentDidMount(){
console.log(this.props);
this.setState({
info:this.props.item,
infoList:[
{
productName:'华夏理财固收增强 最短持有120天A款A',
profit:'17.72%',
ratio:'35.50%',
},
{
productName:'华夏理财固收增强 最短持有120天A款B',
profit:'17.72%',
ratio:'35.50%',
},
{
productName:'华夏理财固收增强 最短持有120天A款C',
profit:'17.72%',
ratio:'35.50%',
},
{
productName:'华夏理财固收增强 最短持有120天A款D',
profit:'17.72%',
ratio:'35.50%',
},
{
productName:'华夏理财固收增强 最短持有120天A款E',
profit:'17.72%',
ratio:'35.50%',
},
]
})
}
clickClose = () => {
ModalCtrl.closeModal();
}
render() {
return (
<div className="positionpop modal_center">
<span className="iconbg"></span>
<span className="iconclose" onClick={this.clickClose}></span>
<span className="iconc"></span>
<span className="icony"></span>
<div className='info-list'>
{/* <span className="iconbg1"></span> */}
<span className="iconbg2"></span>
<div className="info-list-title">
<span className="chanPinMingCheng">产品名称</span>
<span className="shouYiLu">收益率</span>
<span className="chiCangZhanBi">持仓占比</span>
</div>
<div className="info-list-box">
{
this.state.infoList?.map((item, index) => (
<div key={index} className="list4">
<span className="productName">
{item.productName}
</span>
<span className="profit">{item.profit}</span>
<span className="ratio">{item.ratio}</span>
</div>
))
}
</div>
</div>
{/* <div className="list2">
<span className="juXing7_2"></span>
<span className="huaXiaLiCaiGuShouZengQiangZuiDuanChiYou120tianAkuanA_2">
华夏理财固收增强 最短持有120天A款A
</span>
<span className="_1772_2">17.72%</span>
<span className="_3550_2">35.50%</span>
</div>
<div className="list1">
<span className="juXing7_3"></span>
<span className="huaXiaLiCaiGuShouZengQiangZuiDuanChiYou120tianAkuanA_3">
华夏理财固收增强 最短持有120天A款A
</span>
<span className="_1772_3">17.72%</span>
<span className="_3550_3">35.50%</span>
</div> */}
<span className="name">{this.state.info.userName}</span>
<span className="title">持仓情况</span>
{/* <span className="icon1"></span> */}
</div>
);
}
}
export default Positionpop;
@import "../../res.less";
.positionpop {
width: 750px;
height: 1624px;
left: 0px;
top: 0px;
position: absolute;
.iconbg {
width: 542px;
height: 566px;
left: 111px;
top: 492px;
position: absolute;
.sparkBg("positionPop/icon-bg.png");
}
.iconclose {
width: 57px;
height: 57px;
left: 360px;
top: 1097px;
position: absolute;
.sparkBg("positionPop/icon-close.png");
}
.iconc {
width: 586px;
height: 652px;
left: 177px;
top: 333px;
position: absolute;
opacity: 0.26;
.sparkBg("positionPop/icon-c.png");
}
.icony {
width: 289px;
height: 251px;
left: 384px;
top: 444px;
position: absolute;
.sparkBg("positionPop/icon-y.png");
}
.info-list {
width: 516px;
height: 410px;
left: 124px;
top: 620px;
border-radius: 40px;
position: absolute;
overflow: hidden;
.sparkBg("positionPop/icon-bg1.png");
}
.iconbg1 {
width: 516px;
height: 325px;
left: 124px;
top: 620px;
position: absolute;
.sparkBg("positionPop/icon-bg1.png");
}
.iconbg2 {
width: 516px;
height: 94px;
left: 0px;
top: -20px;
position: absolute;
.sparkBg("positionPop/icon-bg2.png");
}
.info-list-title {
width: 496px;
height: 94px;
left: 10px;
top: -20px;
display: flex;
align-items: center;
justify-content: space-evenly;
position: absolute;
}
.chanPinMingCheng {
width: 185px;
height: 25px;
// left: 194px;
// top: 640px;
// position: absolute;
font-size: 25px;
line-height: 40px;
text-align: center;
color: rgba(179, 117, 19, 1);
}
.shouYiLu {
width: 100px;
height: 24px;
// left: 383px;
// top: 640px;
// position: absolute;
font-size: 25px;
line-height: 40px;
text-align: center;
color: rgba(179, 117, 19, 1);
}
.chiCangZhanBi {
width: 100px;
height: 25px;
// left: 498px;
// top: 640px;
// position: absolute;
font-size: 25px;
line-height: 40px;
text-align: center;
color: rgba(179, 117, 19, 1);
}
.info-list-box {
width: 496px;
height: 333px;
left: 10px;
top: 80px;
position: absolute;
overflow-x: hidden;
overflow-y: auto;
.list4 {
width: 496px;
height: 77px;
display: flex;
align-items: center;
justify-content: space-evenly;
margin-bottom: 8px;
.sparkBg("positionPop/list-bg.png");
.productName {
width: 185px;
height: 45px;
font-size: 20px;
color: rgba(99, 38, 6, 1);
text-align: center;
}
.profit {
width: 100px;
height: 15px;
text-align: center;
font-size: 20px;
line-height: 15px;
color: rgba(99, 38, 6, 1);
}
.ratio {
width: 100px;
height: 15px;
font-size: 20px;
line-height: 15px;
color: rgba(99, 38, 6, 1);
text-align: center;
}
}
}
.name {
width: 109px;
height: 25px;
left: 145px;
top: 522px;
position: absolute;
font-size: 25px;
line-height: 25px;
color: rgba(211, 26, 25, 1);
}
.title {
width: 201px;
height: 46px;
left: 144px;
top: 561px;
position: absolute;
font-size: 48px;
line-height: 46px;
color: rgba(91, 34, 0, 1);
}
.icon1 {
width: 441px;
height: 389px;
left: 13px;
top: 425px;
position: absolute;
.sparkBg("positionPop/icon-1.png");
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment