Commit 14c6a4c8 authored by 王勇霞's avatar 王勇霞

feat: 实盘逻辑完善

parent 4d9953ad
......@@ -85,12 +85,13 @@ export default [
"pop": false,
"show": true
},
"lastMonthRankPop": true,
"overallRankPop": {
"prizeId": "anim",
"prizeImg": "officia velit dolor ex",
"prizeName": "culpa non dolore"
},
"lastMonthRankPop": false,
overallRankPop: null ,
// "overallRankPop": {
// "prizeId": "anim",
// "prizeImg": "officia velit dolor ex",
// "prizeName": "culpa non dolore"
// },
"bannerInfo": new Array(7).fill(1).map((item, index) => ({
"bannerImg": `http://xqtpl.com/bg/300/300/banner${index+1}?color=fff`,
"bannerLink": "http://xqtpl.com/bg/300/300?color=fff"
......
......@@ -14,12 +14,9 @@ import { GetCurrSkinId, getCustomShareId } from "@/utils/utils.ts";
import HomePage from "@/pages/HomePage/HomePage.tsx";
import Auth from "@/pages/auth/auth.jsx";
import LoadingDemo from "@/pages/LoadingDemo/LoadingDemo.tsx";
import { loadFont } from "@/core/preload.ts";
import DetailPage from "@/pages/DetailPage/DetailPage.tsx";
import RecordPage from "@/pages/RecordPage/RecordPage.tsx";
import ResPage from "@/pages/ResPage/ResPage.tsx";
import PrizePage from "@/pages/PrizePage/PrizePage.tsx";
import SharePage from "@/pages/sharePage/sharePage.jsx";
......
export * from "./output.module";
// export * from "../../Game/debug/output.module"
This diff is collapsed.
src/assets/NoPrizePanel/btn.png

9.88 KB | W: | H:

src/assets/NoPrizePanel/btn.png

21.8 KB | W: | H:

src/assets/NoPrizePanel/btn.png
src/assets/NoPrizePanel/btn.png
src/assets/NoPrizePanel/btn.png
src/assets/NoPrizePanel/btn.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jumpConfirmPop/bg.png

2.99 KB | W: | H:

src/assets/jumpConfirmPop/bg.png

114 KB | W: | H:

src/assets/jumpConfirmPop/bg.png
src/assets/jumpConfirmPop/bg.png
src/assets/jumpConfirmPop/bg.png
src/assets/jumpConfirmPop/bg.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/jumpConfirmPop/think_btn.png

4.16 KB | W: | H:

src/assets/jumpConfirmPop/think_btn.png

11.9 KB | W: | H:

src/assets/jumpConfirmPop/think_btn.png
src/assets/jumpConfirmPop/think_btn.png
src/assets/jumpConfirmPop/think_btn.png
src/assets/jumpConfirmPop/think_btn.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/setupPop/bg.png

125 KB | W: | H:

src/assets/setupPop/bg.png

127 KB | W: | H:

src/assets/setupPop/bg.png
src/assets/setupPop/bg.png
src/assets/setupPop/bg.png
src/assets/setupPop/bg.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -5,22 +5,18 @@ 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 Managepop from '@/panels/managepop/managepop';
import Endpop from '@/panels/endPop/index.jsx';
import { PageCtrl } from '@/core/ctrls/PageCtrl';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { _asyncThrottle, dateFormatter, formatThousand } from '@/utils/utils';
import RecordPage from '../RecordPage/RecordPage';
import NewRecordPage from '../newRecordPage/index.jsx';
import { diffJump, RATE_NAME } from '@/AppTools';
import API from '@/api';
import DetailPage from '../DetailPage/DetailPage';
import ResPage from '../ResPage/ResPage';
import MyQradesPage from '../myQradesPage/myqradesPage';
import MyQradesPage from '../myQradesPage/myqradespage';
import Countdown from '@/core/components/ComCountdown/index.jsx';
import ProductListPage from '../productListPage/productListPage';
import PrizePage from "@/pages/PrizePage/PrizePage.tsx";
import SignCom from '@/panels/signCom/signCom.jsx';
import RedPackCountPanel from '@/panels/redPackCountPanel/index.jsx';
import SetupSuccessPop from '@/panels/setupSuccessPop';
@observer
......@@ -144,14 +140,14 @@ class HomePage extends React.Component<any, any> {
componentDidMount() {
store.updateIndex()
// ModalCtrl.showModal(Managepop)
// ModalCtrl.showModal(Endpop)
}
/** 跳转模拟交易记录 */
recordHadnle = _asyncThrottle(() => {
if (!store.judgeActTime()) return
PageCtrl.changePage(NewRecordPage, { tab: 1 });
})
// recordHadnle = _asyncThrottle(() => {
// if (!store.judgeActTime()) return
// PageCtrl.changePage(NewRecordPage, { tab: 1 });
// })
/** 跳转“模拟”产品详情页 */
jumpVirtualDetailHandle = _asyncThrottle((item) => {
......@@ -160,13 +156,13 @@ class HomePage extends React.Component<any, any> {
})
/** 跳转“真实”产品详情页 */
jumpRealDetailHandle = _asyncThrottle((item) => {
if (!store.judgeActTime()) return
const { curTab } = this.state
if (curTab != 2) return false
// 我的持仓才可以跳转
diffJump(item.realBuyJumpUrl)
})
// jumpRealDetailHandle = _asyncThrottle((item) => {
// if (!store.judgeActTime()) return
// const { curTab } = this.state
// if (curTab != 2) return false
// // 我的持仓才可以跳转
// diffJump(item.realBuyJumpUrl)
// })
/** 规则 */
ruleHandle = _asyncThrottle(() => {
......@@ -184,15 +180,9 @@ class HomePage extends React.Component<any, any> {
if (!store.judgeActTime()) return
ModalCtrl.showModal(SetupSuccessPop)
})
// 倒计时
countDownFun = _asyncThrottle(() => {
if (!store.judgeActTime(true, false)) return
ModalCtrl.showModal(RedPackCountPanel)
})
/** 跳转结果页 */
prizeHandle = _asyncThrottle(() => {
if (!store.judgeActTime(true, false)) return
// PageCtrl.changePage(ResPage)
PageCtrl.changePage(MyQradesPage)
})
......
......@@ -105,7 +105,6 @@
top: 58px;
width: 18px;
height: 32px;
.webpBg("ResPage/backBtn.png");
.webpBg("common/backBtn.png");
}
}
@import "../../res.less";
.RecordPage {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
overflow: hidden;
.webpBg("RecordPage/bg.jpg");
background-size: 750px 1746px;
background-position: left top;
display: flex;
align-items: center;
justify-content: center;
.pageTitle {
position: absolute;
left: 253px;
top: 57px;
width: 243px;
height: 33px;
.webpBg("RecordPage/title.png");
}
.backBtn {
position: absolute;
left: 28px;
top: 58px;
width: 18px;
height: 32px;
.webpBg("RecordPage/backBtn.png");
}
.listNone {
position: absolute;
top: 400px;
left: 0;
width: 100%;
font-size: 32px;
color: #d62928;
text-align: center;
font-weight: bold;
}
.list {
position: absolute;
top: 143px;
bottom: 0;
width: 710px;
border-top-left-radius: 30px;
border-top-right-radius: 30px;
overflow-x: hidden;
overflow-y: auto;
.item {
position: relative;
width: 100%;
height: 141px;
.title {
position: absolute;
left: 56px;
top: 57px;
font-size: 30px;
color: black;
font-weight: bold;
width: 390px;
.lineClamp1();
}
.date {
position: absolute;
left: 56px;
top: 104px;
font-size: 24px;
color: rgba(0, 0, 0, 0.6);
}
.num {
position: absolute;
right: 60px;
top: 61px;
font-size: 30px;
color: black;
font-weight: bold;
}
.state {
position: absolute;
right: 60px;
top: 100px;
font-size: 24px;
color: rgba(0, 0, 0, 0.6);
// #ee4e32
// #1b8a4f
}
}
}
}
import React from 'react';
import { observer } from 'mobx-react';
import styles from './RecordPage.module.less';
import { Button } from "@grace/ui";
import API from "@/api";
import { dateFormatter } from "@/utils/utils.ts";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
import HomePage from "@/pages/HomePage/HomePage.tsx";
@observer
class RecordPage extends React.Component<any, any> {
state = {
list: [],
}
async componentDidMount() {
this.updateList();
}
pageNum: number = 1;
pageSize: number = 50;
haveMore: boolean = true;
async updateList() {
const { pageNum, pageSize, haveMore } = this;
if (!haveMore) return;
const { success, data } = await API.tradeRecords({ pageNum, pageSize });
if (!success) return;
this.pageNum++;
this.haveMore = data.haveMore;
const list = this.state.list.concat(data.list);
this.setState({ list, })
}
clickBack = () => {
PageCtrl.changePage(HomePage);
}
render() {
const { list } = this.state;
return <div className={styles.RecordPage}>
<div className={styles.pageTitle}/>
<Button className={styles.backBtn} onClick={this.clickBack}/>
{list?.length
? <div className={styles.list}>
{
list.map((item) => {
const state = {
0: { txt: "购买待确认", color: "rgba(0,0,0,0.6)" },
1: { txt: "购买成功", color: "#ee4e32" },
2: { txt: "赎回成功", color: "#1b8a4f" },
3: { txt: "购买失败", color: "rgba(0,0,0,0.6)" },
}[item.tradeStatus];
return <div className={styles.item}>
<div className={styles.title}>{item.desc}</div>
<div
className={styles.date}>{dateFormatter(item.gmtCreate, "yyyy.MM.dd hh:mm:ss")}</div>
<div className={styles.num}>¥{item.amount / 100}</div>
{/*<div className={styles.num}>¥0000000.00</div>*/}
<div className={styles.state} style={{ color: state.color }}>{state.txt}</div>
</div>
})
}
</div>
: <div className={styles.listNone}>暂无交易记录哦</div>
}
</div>;
}
}
export default RecordPage;
@import "../../res.less";
.ResPage {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
overflow-x: hidden;
overflow-y: auto;
display: flex;
align-items: center;
justify-content: center;
.bg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1624px;
.webpBg("ResPage/bg.png");
background-size: 750px 1746px;
background-position: left top;
}
.rankBg {
position: absolute;
left: 21px;
top: 112px;
width: 709px;
height: 407px;
.webpBg("ResPage/rankBg.png");
.rankTip {
position: absolute;
background-color: rgb(249, 231, 208);
left: 234px;
border-radius: 11px;
width: 417px;
height: 52px;
display: flex;
align-items: center;
justify-content: flex-start;
padding-left: 21px;
box-sizing: border-box;
font-size: 24px;
color: #a3741f;
font-weight: bold;
span {
margin-left: 16px;
font-weight: normal;
}
}
.rankImg {
position: absolute;
left: 45px;
top: 131px;
width: 176px;
height: 202px;
//.webpBg("ResPage/理财大明星.png");
}
.rank1 {
top: 109px;
background: none;
span {
margin-left: 4px;
font-size: 20px;
color: #ee4e32;
font-weight: bold;
height: 40px;
line-height: 40px;
}
}
.rank2 {
top: 169px;
}
.rank3 {
top: 229px;
}
.rank4 {
top: 287px;
}
}
.tab {
position: absolute;
left: 19px;
top: 536px;
width: 713px;
height: 1041px;
&.tab1 {
.webpBg("ResPage/bg1.png");
}
&.tab2 {
.webpBg("ResPage/bg2.png");
}
.tabBtn1 {
position: absolute;
left: 0;
top: 0;
width: 50%;
height: 80px;
}
.tabBtn2 {
position: absolute;
left: 50%;
top: 0;
width: 50%;
height: 80px;
}
}
.listNone {
position: absolute;
left: 223px;
top: 913px;
width: 271px;
height: 264px;
.webpBg("ResPage/空状态.png");
}
.prizeList {
position: absolute;
left: 19px;
top: 630px;
width: 713px;
height: 930px;
overflow-x: hidden;
overflow-y: auto;
.prizeItem {
position: relative;
width: 713px;
height: 146px;
.itemImg {
border-radius: 20px;
background-color: #f0f0f0;
position: absolute;
left: 31px;
top: 16px;
width: 110px;
height: 110px;
}
.itemName {
font-size: 30px;
color: #262626;
position: absolute;
width: 350px;
left: 164px;
top: 39px;
font-weight: bold;
.lineClamp1();
}
.itemDate {
position: absolute;
left: 164px;
top: 80px;
font-size: 24px;
color: rgb(133, 133, 133);
}
.itemBtn {
position: absolute;
left: 530px;
top: 37px;
width: 157px;
height: 64px;
.webpBg("ResPage/去查看.png");
}
.itemBtnEd {
position: absolute;
left: 530px;
top: 37px;
width: 157px;
height: 64px;
.webpBg("ResPage/已使用.png");
}
}
}
.backBtn {
position: absolute;
left: 28px;
top: 58px;
width: 18px;
height: 32px;
.webpBg("ResPage/backBtn.png");
}
}
import React from 'react';
import { observer } from 'mobx-react';
import styles from './ResPage.module.less';
import { Button } from "@grace/ui";
import classNames from "classnames";
import TurnTable from "@/pages/ResPage/TurnTable/TurnTable.tsx";
import resStore from "@/store/ResStore.ts";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
import HomePage from "@/pages/HomePage/HomePage.tsx";
import { dateFormatter } from "@/utils/utils.ts";
@observer
class ResPage extends React.Component<any, any> {
state = {
tab: 1,
}
async componentDidMount() {
resStore.updateInfo();
}
clickBack = () => {
PageCtrl.changePage(HomePage);
}
changeTab = (tab: number) => {
this.setState({ tab, });
}
clickItem = (item) => {
if (item.url) {
location.href = item.url
} else {
location.href = `/aaw/projectx/takePrize?projectOrderNo=${item.id}`
}
}
render() {
const { tab } = this.state;
const { prizeList, info } = resStore;
const { titleImg, interval, cycleEndTime, cycleStartTime, profit, remainDrawTime, prizeInfo, amount } = info;
const tabCls = classNames(styles.tab, {
[styles.tab1]: tab === 1,
[styles.tab2]: tab === 2,
});
return <div className={styles.ResPage}>
<div className={styles.bg}/>
<div className={styles.rankBg}>
<img className={styles.rankImg} src={titleImg}/>
<div className={classNames(styles.rankTip, styles.rank1)}>
我的收益区间在<span>{interval}</span>
</div>
<div className={classNames(styles.rankTip, styles.rank2)}>
理财资金<span>{amount/100}</span>
</div>
<div className={classNames(styles.rankTip, styles.rank3)}>
累计收益<span>{profit/100}</span>
</div>
<div className={classNames(styles.rankTip, styles.rank4)}>
理财周期<span>{dateFormatter(cycleStartTime, `yyyy.MM.dd`)}-{dateFormatter(cycleEndTime, `yyyy.MM.dd`)}</span>
</div>
</div>
<div className={tabCls}>
<div className={styles.tabBtn1} onClick={() => this.changeTab(1)}/>
<div className={styles.tabBtn2} onClick={() => this.changeTab(2)}/>
</div>
<div style={{ display: tab == 1 ? "block" : "none" }}>
<TurnTable/>
</div>
<div style={{ display: tab == 2 ? "block" : "none" }}>
{
prizeList?.length
? <div className={styles.prizeList} style={{ display: tab == 2 ? "block" : "none" }}>
{prizeList?.map((item, index) => {
return <div className={styles.prizeItem}>
<img className={styles.itemImg} src={item.extra.icon}/>
<div className={styles.itemName}>{item.extra.name}</div>
<div className={styles.itemDate}>{dateFormatter(item.gmtCreate, "yyyy-MM-dd hh:mm:ss 获得")}</div>
{
item.extra.receiveStatus == 1
? <Button className={styles.itemBtnEd} onClick={() => this.clickItem(item)}/>
: <Button className={styles.itemBtn} onClick={() => this.clickItem(item)}/>
}
</div>
})}
</div>
: <div className={styles.listNone}></div>
}
</div>
<Button className={styles.backBtn} onClick={this.clickBack}/>
</div>;
}
}
export default ResPage;
@import "../../../res.less";
.TurnTable {
.tt_box {
width: 614px;
height: 614px;
left: 68px;
top: 694px;
position: absolute;
.turntable_bg {
width: 614px;
height: 614px;
left: 0;
top: 0;
position: absolute;
.sparkBg("ResPage/转盘背景.png");
}
.prize_item {
width: 70px;
height: 70px;
text-align: center;
color: #6a2913;
font-size: 22px;
margin-bottom: 15px;
margin-left: -65px;
transform: rotateZ(-8deg);
.prize_name {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: -40px;
width: 300%;
font-size: 25.75px;
color: #e3a754;
.lineClamp1();
font-weight: bold;
}
.prize_img {
width: 80px;
height: 80px;
object-fit: contain;
}
}
}
.ttBtn {
position: absolute;
left: 278px;
top: 895px;
width: 193px;
height: 204px;
.webpBg("ResPage/点击抽奖.png");
}
.drawBtn {
position: absolute;
left: 167px;
top: 1361px;
width: 416px;
height: 142px;
&.enable {
.webpBg("ResPage/可抽奖.png");
}
&.disable {
.webpBg("ResPage/不可抽奖.png");
}
}
}
import React from 'react';
import { observer } from 'mobx-react';
import './TurnTable.less';
import { CircleTurntable } from "@spark/circle-turntable";
// import turnTableStore from "@src/store/TurnTableStore";
import { Button, Toast } from "@grace/ui";
import { _asyncThrottle } from "@/utils/utils.ts";
import API from "@/api";
import resStore from "@/store/ResStore.ts";
import classNames from "classnames";
import { NoPrizePanel } from "@/panels/NoPrizePanel/NoPrizePanel.tsx";
import { ModalCtrl } from "@/core/ctrls/ModalCtrl.tsx";
import { PrizePanel } from "@/panels/PrizePanel/PrizePanel.tsx";
import store from '@/store/store';
@observer
class TurnTable extends React.Component {
turntableRef = null; // 大转盘
btnStarting = false; // 转盘是否启动
drawResultInfo: any = {};
async componentDidMount() {
}
onStop = () => {
this.btnStarting = false;
resStore.updateInfo();
if (this.drawResultInfo.prizeId == "thanks") {
ModalCtrl.showModal(NoPrizePanel, {type: 'final_turntable', ...this.drawResultInfo});
} else {
ModalCtrl.showModal(PrizePanel, {type: 'final_turntable', ...this.drawResultInfo});
}
}
// 开始抽奖
drawHandle = _asyncThrottle(async () => {
if (this.btnStarting) return false;
if (store.indexData.currentTime >= resStore.info.drawEndTime) {
return Toast.show("活动已结束");
}
if (resStore.info.remainDrawTime <= 0) {
return Toast.show("已抽过奖哦");
}
this.btnStarting = true;
const { success, data } = await API.drawJoin();
if (!success) {
this.btnStarting = false;
return;
}
this.drawResultInfo = data;
this.turntableRef.launch();
const index = resStore.info.prizeInfo?.findIndex((item) => item.prizeId === this.drawResultInfo.prizeId);
this.turntableRef.braking(index);
});
render() {
const { prizeInfo, remainDrawTime } = resStore.info;
return <div className="TurnTable">
<CircleTurntable
className="tt_box"
// @ts-ignore
ref={(ref) => (this.turntableRef = ref)}
options={prizeInfo || []}
angleOffset={180 / 6 + 10} // 角度偏移量
radian={100} // 奖项半径
launchDuration={1000} // 启动时间
// 大转盘背景
renderBackground={<div className="turntable_bg"></div>}
// 大转盘指针
renderStartButton={<div className="ttBtn"/>}
// 渲染奖品信息
renderOption={(option) => {
return <div className="prize_item">
<div className="prize_name">{option.prizeName}</div>
<img className="prize_img" src={option.prizeImg} alt=""/>
</div>;
}}
didStop={this.onStop}
/>
<Button className={classNames("drawBtn md32", {
enable: remainDrawTime > 0,
disable: remainDrawTime <= 0,
})} onClick={this.drawHandle}/>
</div>;
}
}
export default TurnTable;
@import "../../res.less";
.productListPage {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
overflow: hidden;
background-color: rgb(255, 227, 216);
.pageTitle {
position: absolute;
left: 270px;
top: 45px;
width: 210px;
height: 49px;
.webpBg("productListPage/title.png");
}
.backBtn {
position: absolute;
left: 47px;
top: 53px;
width: 16px;
height: 31px;
.webpBg("productListPage/back.png");
}
.listNone {
position: absolute;
top: 400px;
left: 0;
width: 100%;
font-size: 32px;
color: #d62928;
text-align: center;
font-weight: bold;
}
.list_bg {
position: absolute;
left: 19px;
top: 124px;
width: 713px;
height: 1604px;
.webpBg("productListPage/list_bg.png");
}
.products_list {
width: 680px;
// height: 696px;
left: 50px;
top: 130px;
bottom: 0;
position: absolute;
overflow-y: auto;
padding-top: 50px;
padding-right: 27px;
box-sizing: border-box;
.product_item {
width: 653px;
height: 173px;
position: relative;
&:not(:last-child) {
margin-bottom: 50px;
}
.product_name {
width: 650px;
height: 30px;
left: 0px;
top: 0px;
position: absolute;
font-size: 28px;
line-height: 30px;
color: rgba(1, 1, 1, 1);
font-weight: bold;
}
.product_rate {
width: 200px;
height: 63px;
left: 0px;
top: 57px;
position: absolute;
.product_rate_label {
width: 100%;
height: 20px;
left: 0px;
top: 46px;
position: absolute;
opacity: 0.6;
font-size: 20px;
line-height: 20px;
color: rgba(1, 1, 1, 1);
.lineClamp1();
}
.product_rate_value {
width: 100%;
height: 32px;
left: 2px;
top: 0px;
position: absolute;
font-size: 32px;
line-height: 32px;
color: rgba(211, 26, 25, 1);
font-weight: bold;
.lineClamp1();
}
}
.product_shu {
width: 280px;
height: 63px;
left: 222px;
top: 57px;
position: absolute;
.product_shu_label {
width: 100%;
height: 20px;
left: 1px;
top: 45px;
position: absolute;
opacity: 0.6;
font-size: 20px;
line-height: 20px;
color: rgba(1, 1, 1, 1);
.lineClamp1();
}
.product_shu_value {
width: 100%;
height: 30px;
left: 0px;
top: 0px;
position: absolute;
font-size: 28px;
line-height: 30px;
color: rgba(0, 0, 0, 1);
font-weight: bold;
.lineClamp1();
}
}
.real_btn {
width: 140px;
height: 49px;
left: 513px;
top: 65px;
position: absolute;
.sparkBg("productListPage/real_btn.png");
}
.product_line {
width: 652px;
height: 2px;
left: 1px;
top: 171px;
position: absolute;
.sparkBg("productListPage/item_line.png");
}
}
}
}
import React from 'react';
import { observer } from 'mobx-react';
import './productListPage.less';
import { Button } from "@grace/ui";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
import HomePage from "@/pages/HomePage/HomePage.tsx";
import store from '@/store/store';
import { diffJump, RATE_NAME } from '@/AppTools';
import JumpConfirmPop from '@/panels/jumpConfirmPop/jumpConfirmPop.jsx';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
@observer
class ProductListPage extends React.Component<any, any> {
state = {
}
/** 跳转“真实”产品详情页 */
jumpRealDetailHandle = (item) => {
ModalCtrl.showModal(JumpConfirmPop, {
confirmCb: () => {
diffJump(item.realBuyJumpUrl)
}
})
}
clickBack = () => {
PageCtrl.changePage(HomePage);
}
render() {
const { recommendProductConfig } = store.indexData
return <div className="productListPage">
<div className="pageTitle" />
<Button className="backBtn" onClick={this.clickBack} />
<div className="list_bg"></div>
{recommendProductConfig?.length
? <div className="products_list">
{recommendProductConfig?.map((item, index) => (
<div className="product_item" key={`r_prdct_${index}`} onClick={() => this.jumpRealDetailHandle(item)}>
<span className="product_name">{item.name}</span>
<div className="product_rate">
{!!item.rate && <span className="product_rate_value">{(item.rate / 100).toFixed(2)}%</span>}
<span className="product_rate_label">{RATE_NAME[item.type] || '年化收益率'}</span>
</div>
<div className="product_shu">
<span className="product_shu_value">{item.shenShuGuiZei}</span>
<span className="product_shu_label">{item.fengXian}{item.qigouText}</span>
</div>
<Button className="real_btn"></Button>
<span className="product_line"></span>
</div>
))}
</div>
: <div className="listNone">暂无产品哦</div>
}
</div>;
}
}
export default ProductListPage;
......@@ -8,47 +8,49 @@
position: absolute;
.bg {
left: 100px;
top: 529px;
width: 539px;
height: 310px;
position: absolute;
left: 82px;
top: 448px;
width: 585px;
height: 388px;
.webpBg("BuyPanel/bg.png");
.sparkBg("jumpConfirmPop/bg.png");
}
.btn {
position: absolute;
left: 374px;
top: 673px;
width: 257px;
height: 138px;
.webpBg("BuyPanel/确认.png");
left: 376px;
top: 713px;
width: 213px;
height: 78px;
.sparkBg("jumpConfirmPop/confirm_btn.png");
}
.cancel {
position: absolute;
left: 135px;
top: 677px;
width: 231px;
height: 110px;
.webpBg("BuyPanel/再想想.png");
left: 150px;
top: 713px;
width: 216px;
height: 82px;
.sparkBg("jumpConfirmPop/think_btn.png");
}
.tip {
font-size: 36px;
color: rgb(1, 1, 1);
text-align: center;
width: 505px;
height: 90px;
left: 118px;
top: 576px;
position: absolute;
left: 125px;
width: 500px;
top: 525px;
font-size: 40px;
line-height: 50px;
color: #5b2200;
font-weight: bold;
text-align: center;
}
.close {
position: absolute;
left: 346px;
top: 961px;
top: 886px;
width: 58px;
height: 58px;
.webpBg("common/close.png");
......
......@@ -9,26 +9,26 @@
.bg {
position: absolute;
left: 82px;
top: 448px;
width: 585px;
height: 388px;
left: 100px;
top: 402px;
width: 539px;
height: 310px;
.webpBg("NoPrizePanel/noPrize.png");
}
.btn {
position: absolute;
left: 120px;
top: 673px;
width: 510px;
height: 138px;
left: 157px;
top: 585px;
width: 426px;
height: 86px;
.webpBg("NoPrizePanel/btn.png");
}
.close {
position: absolute;
left: 346px;
top: 958px;
top: 748px;
width: 58px;
height: 58px;
.webpBg("common/close.png");
......
......@@ -8,47 +8,49 @@
position: absolute;
.bg {
left: 100px;
top: 529px;
width: 539px;
height: 310px;
position: absolute;
left: 82px;
top: 448px;
width: 585px;
height: 388px;
.webpBg("BuyPanel/bg.png");
.sparkBg("jumpConfirmPop/bg.png");
}
.btn {
position: absolute;
left: 374px;
top: 673px;
width: 257px;
height: 138px;
.webpBg("BuyPanel/确认.png");
position: absolute;
left: 376px;
top: 713px;
width: 213px;
height: 78px;
.sparkBg("jumpConfirmPop/confirm_btn.png");
}
.cancel {
position: absolute;
left: 135px;
top: 677px;
width: 231px;
height: 110px;
.webpBg("BuyPanel/再想想.png");
position: absolute;
left: 150px;
top: 713px;
width: 216px;
height: 82px;
.sparkBg("jumpConfirmPop/think_btn.png");
}
.tip {
font-size: 36px;
color: rgb(1, 1, 1);
text-align: center;
width: 505px;
height: 90px;
left: 118px;
top: 576px;
position: absolute;
left: 125px;
width: 500px;
top: 525px;
font-size: 40px;
line-height: 50px;
color: #5b2200;
font-weight: bold;
text-align: center;
}
.close {
position: absolute;
left: 346px;
top: 961px;
top: 886px;
width: 58px;
height: 58px;
.webpBg("common/close.png");
......
......@@ -5,35 +5,33 @@ import { observer } from 'mobx-react';
import MyQradesPage from '@/pages/myQradesPage/myqradespage';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { PageCtrl } from '@/core/ctrls/PageCtrl';
import './managepop.less';
import './index.less';
@observer
class Managepop extends React.Component {
class Endpop extends React.Component {
constructor(props) {
super(props);
}
// 关闭
close_click = () => {
ModalCtrl.closeModal(Managepop);
closeClick = () => {
ModalCtrl.closeModal();
};
// 查看
view_click = () => {
ModalCtrl.closeModal(Managepop);
viewClick = () => {
ModalCtrl.closeModal();
PageCtrl.changePage(MyQradesPage)
};
render() {
return (
<div className="managepop modal_center">
<div className="endpop modal_center">
<span className="bg"></span>
<span className="titlebg"></span>
<span className="btnbg"></span>
<span className="liJiChaKan" onClick = { ()=> this.view_click()} >立即查看</span>
<span className="liJiChaKan" onClick = { ()=> this.viewClick()} >立即查看</span>
<span className="kuaiQuChaKanLiCaiChengJiCanYuChouJiangBa">快去查看理财成绩,参与抽奖吧!</span>
<span className="close" onClick = { ()=> this.close_click()}></span>
<span className="close" onClick = { ()=> this.closeClick()}></span>
</div>
);
}
}
export default Managepop;
export default Endpop;
@import "../../res.less";
.managepop {
.endpop {
width: 750px;
height: 1624px;
left: 0px;
......@@ -11,7 +11,7 @@
left: 98px;
top: 572px;
position: absolute;
.sparkBg("managePop/bg.png");
.sparkBg("endPop/bg.png");
}
.btnbg {
width: 428px;
......@@ -19,7 +19,7 @@
left: 156px;
top: 753px;
position: absolute;
.sparkBg("managePop/btn-bg.png");
.sparkBg("endPop/btn-bg.png");
}
.liJiChaKan {
width: 150px;
......@@ -45,9 +45,9 @@
width: 57px;
height: 57px;
left: 347px;
top: 1003px;
top: 943px;
position: absolute;
.sparkBg("managePop/close.png");
.sparkBg("endPop/close.png");
}
.titlebg {
......@@ -56,6 +56,6 @@
left: 143px;
top: 633px;
position: absolute;
.sparkBg("managePop/title-bg.png");
.sparkBg("endPop/title-bg.png");
}
}
'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import './invalidPop.less';
import store from '../../store/store';
import { Button } from '@grace/ui';
import { _asyncThrottle } from "../../utils/utils";
import { ModalCtrl } from "@/core/ctrls/ModalCtrl";
import { Toast } from '@grace/ui';
@observer
class InvalidPop extends React.Component {
constructor(props) {
super(props);
}
async componentDidMount() {
}
handleClose = _asyncThrottle(() => {
Toast.show('请退出活动哦~');
// ModalCtrl.closeModal()
})
render() {
return (
<div className="invalidPop modal_center">
<span className="bg"></span>
<div className="text">本次活动适用于零基础投资者<br />感谢您对本次模拟理财大赛的关注</div>
<Button className="know_btn md1" onClick={this.handleClose} />
{/* <Button className="close" onClick={this.handleClose} /> */}
</div>
);
}
}
export default InvalidPop;
@import "../../res.less";
.invalidPop {
width: 750px;
height: 1624px;
left: 0px;
top: 0px;
position: absolute;
.bg {
left: 82px;
top: 588px;
width: 585px;
height: 328px;
position: absolute;
.sparkBg("invalidPop/bg.png");
}
.know_btn {
position: absolute;
left: 120px;
top: 753px;
width: 510px;
height: 138px;
.sparkBg("invalidPop/know_btn.png");
}
.text {
width: 505px;
height: 90px;
left: 122px;
top: 644px;
position: absolute;
font-size: 30px;
line-height: 46px;
color: rgb(0, 0, 0);
text-align: center;
}
.close {
left: 346px;
top: 986px;
width: 58px;
height: 58px;
position: absolute;
.sparkBg("common/close.png");
}
}
......@@ -8,48 +8,48 @@
position: absolute;
.bg {
left: 82px;
left: 100px;
top: 529px;
width: 585px;
height: 388px;
width: 539px;
height: 310px;
position: absolute;
.sparkBg("jumpConfirmPop/bg.png");
}
.think_btn {
position: absolute;
left: 135px;
top: 758px;
width: 231px;
height: 110px;
left: 150px;
top: 713px;
width: 216px;
height: 82px;
.sparkBg("jumpConfirmPop/think_btn.png");
}
.confirm_btn {
position: absolute;
left: 374px;
top: 754px;
width: 257px;
height: 138px;
left: 376px;
top: 713px;
width: 213px;
height: 78px;
.sparkBg("jumpConfirmPop/confirm_btn.png");
}
.text {
width: 505px;
height: 90px;
left: 122px;
top: 610px;
left: 118px;
top: 576px;
position: absolute;
font-size: 36px;
font-size: 40px;
line-height: 50px;
color: rgb(0, 0, 0);
color: #5b2200;
font-weight: bold;
text-align: center;
}
.close {
left: 346px;
top: 986px;
top: 886px;
width: 58px;
height: 58px;
position: absolute;
......
'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import './loginpop.less';
import API from '@/api';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { Button, Toast } from '@grace/ui';
import { _asyncThrottle, getUrlParam } from '@/utils/utils';
import LightSDK from 'light-sdk/dist/index.umd'
import { CHANNEL } from '@/AppTools';
import Privacypop from '../privacypop/privacypop';
import { startNecCaptcha } from '@spark/utils';
/* 电话号码验证规则 **/
export const REG_TEL = /^1[0-9]{10}$/;
@observer
class Loginpop extends React.Component {
constructor(props) {
super(props);
this.state = {
uid: "",
loginPhone: "",
loginCode: "",
countDown: 60, // 获取验证码倒计时
showCountDown: false, // 显示获取验证码
showSendAgain: false, // 显示再次发送按钮
showSend: true, // 显示发送按钮
showPrivacyPop: false, // 显示隐私协议弹窗
privacyChecked: false, // 隐私协议-是否勾选
}
}
componentDidMount() {
// 微信端(通过下线二维码进入) 不需要隐私协议
if (getUrlParam("off") != 1) {
this.queryAgreement()
}
// 不用前端拿了 后端能拿到
// if (CFG.channel === CHANNEL.HXLC) {
// this.getUserInfo()
// }
}
// 查询服务协议
queryAgreement = async () => {
const { success, data } = await API.coop_queryAgreement()
if (success) {
this.setState({
agreementInfo: data || {},
})
}
}
getUserInfo = () => {
LightSDK.native.readData({
key: "K_USERID",
component_scope: "global"
}, res => {
console.info("LightSDK 请求结果>>>>>>>>>>>>>>>>", res)
const uid = res.data?.result
this.setState({ uid })
})
}
/** 输入事件 */
changeEvent = async (e, type) => {
const value = e.target.value
switch (type) {
// 手机号
case "loginPhone":
const val = value.replace(/[^\d]/g, '')
this.setState({ loginPhone: val })
break;
// 验证码
case "loginCode":
this.setState({ loginCode: value.replace(/[^\d]/g, '') })
break;
default:
break;
}
}
// 点击获取验证码
clickGetCode = _asyncThrottle(async () => {
// 已经开始倒计时
if (this.state.showCountDown) return false;
if (!this.state.loginPhone || this.state.loginPhone == "") {
Toast.show('请输入手机号')
} else if (!REG_TEL.test(this.state.loginPhone)) {
Toast.show('请输入正确手机号')
} else {
let validate = await startNecCaptcha(
"1ee4615751874cbeaea4dd4681930f61", // 文字点选
// "a869bfdfb9bd4cdf88e1ff2f8667a114", // 滑块验证
5
).catch(e => {
Toast.show("校验失败,请再次尝试哦")
});
// 对准了有值才往下走
if (!validate) {
return false;
}
// 获取验证码
this.getCode(this.state.loginPhone, validate)
}
})
// 获取验证码
getCode = async (phoneNum, validate) => {
const params = {
phoneNumber: phoneNum,
validate: validate,
}
const { success, data } = await API.coop_sendCode(params)
if (success) {
if (data?.resCode == "0000") {
Toast.show("验证码已发送");
this.setState({
showSend: false,
showCountDown: true,
countDown: 60,
showSendAgain: false
})
this.codeCountDown()
} else {
data?.errorMsg && Toast.show(data.errorMsg)
}
}
}
// 验证码倒计时
codeCountDown = () => {
clearInterval(this.timer)
this.timer = setInterval(() => {
if (this.state.countDown == 0) {
clearInterval(this.timer)
this.setState({
showCountDown: false,
showSendAgain: true,
})
} else {
this.setState({
countDown: this.state.countDown - 1
})
}
}, 1000)
}
// 确认提交
handleSubmit = _asyncThrottle(() => {
const { loginPhone, loginCode } = this.state;
const { agreementTitle } = this.state.agreementInfo || {};
if (!!agreementTitle && !this.state.privacyChecked) { // 未勾选隐私协议
Toast.show('请仔细阅读服务协议并勾选')
return false
} else if (!loginPhone) { // 未输入手机号
Toast.show('请输入手机号')
return false
} else if (!REG_TEL.test(loginPhone)) {
Toast.show('请输入正确手机号')
return false
} else if (!loginCode) { // 未输入验证码
Toast.show('请输入验证码')
return false
}
this.bindPhone();
})
// 绑定手机号
bindPhone = async () => {
const { loginPhone, loginCode, uid } = this.state;
const params = {
"phoneNumber": loginPhone,
"smsCode": loginCode,
// 不用前端传了 后端能拿到
// "origenUid": uid || '', // 华夏理财渠道才拿得到 其他渠道不用传
// "redirectUrl": CFG.domain + (getUrlParam("off") == 1 ? CFG.prize : CFG.index)
"redirectUrl": location.href
}
const { success, data } = await API[
CFG.channel == CHANNEL.KUNLUN ? "coop_checkCode" : "checkCode"
](params)
if (success) {
location.replace(data);
}
}
close = () => {
ModalCtrl.closeModal()
}
render() {
const { loginPhone, loginCode, showCountDown, countDown, showSendAgain, showSend } = this.state;
const { showPrivacyPop, privacyChecked } = this.state;
const { agreementTitle, agreementText } = this.state.agreementInfo || {};
return (<>
<div className={`loginpop modal_center ${!agreementTitle ? 'no_check' : ''}`}>
<span className="bg"></span>
<span className="title"></span>
{/* 手机号 */}
<div className="phone">
<input
className="phoneinput"
type="tel"
maxLength="11"
placeholder="请输入手机号"
value={loginPhone}
onChange={(e) => this.changeEvent(e, 'loginPhone')}
/>
</div>
{/* 验证码 */}
<div className="verification">
<input
className="verifyinput"
maxLength="6"
placeholder="请输入验证码"
value={loginCode}
onChange={(e) => this.changeEvent(e, 'loginCode')}
/>
{showSend && <span className="get_btn" onClick={this.clickGetCode}>获取验证码</span>}
{showSendAgain && <span className="get_btn resend" onClick={this.clickGetCode}>重新发送</span>}
{showCountDown && <span className="get_btn">{countDown}s</span>}
</div>
{!!agreementTitle && <div className="check_box">
<div className={`check_icon ${privacyChecked ? 'checked' : ''}`} onClick={() => this.setState({ privacyChecked: !this.state.privacyChecked })}></div>
<div>请仔细阅读
<span className="content_title" onClick={() => this.setState({ showPrivacyPop: true })} dangerouslySetInnerHTML={{ __html: agreementTitle }}></span>
</div>
</div>}
<Button className={`btn ${getUrlParam("off") == 1 ? 'enter_btn md36' : 'md2'}`} onClick={this.handleSubmit}></Button>
{/* <Button className="close" onClick={this.close}></Button> */}
</div>
{/* 二级弹出遮罩 */}
{(showPrivacyPop) && <div className="mask"></div>}
{/* 隐私协议弹窗 */}
{showPrivacyPop && <Privacypop agreementText={agreementText} closeCb={() => this.setState({ showPrivacyPop: false })} />}
</>);
}
}
export default Loginpop;
@import "../../res.less";
.loginpop {
width: 750px;
height: 1624px;
left: 0;
top: 0;
position: absolute;
&.no_check {
.title {
top: 500px;
}
.phone {
top: 607px;
}
.verification {
top: 753px;
}
.btn {
top: 921px;
}
}
.bg {
left: 82px;
top: 434px;
width: 585px;
height: 665px;
position: absolute;
.sparkBg("loginPop/bg.png");
}
.title {
left: 239px;
top: 480px;
width: 274px;
height: 52px;
position: absolute;
.sparkBg("loginPop/title.png");
}
.btn {
left: 120px;
top: 931px;
width: 510px;
height: 138px;
position: absolute;
.sparkBg("loginPop/bind_btn.png");
&.enter_btn {
.sparkBg("loginPop/enter_btn.png");
}
}
input::placeholder {
color: rgb(155, 155, 155);
}
.phone {
left: 114px;
top: 577px;
width: 516px;
height: 96px;
position: absolute;
padding: 23px 30px;
box-sizing: border-box;
border: 2px solid rgb(244, 215, 211);
border-radius: 17px;
background-color: rgb(255, 255, 255);
.phoneinput {
width: 100%;
height: 100%;
color: rgb(0, 0, 0);
font-size: 28px;
}
}
.verification {
left: 114px;
top: 713px;
width: 279px;
height: 92px;
position: absolute;
.verifyinput {
width: 283px;
height: 96px;
left: 0px;
top: 0px;
position: absolute;
padding: 23px 30px;
color: rgb(0, 0, 0);
font-size: 28px;
box-sizing: border-box;
border: 2px solid rgb(244, 215, 211);
border-radius: 17px;
background-color: rgb(255, 255, 255);
}
.get_btn {
width: 207px;
height: 88px;
line-height: 88px;
left: 310px;
top: 5px;
position: absolute;
font-size: 28px;
color: rgb(255, 255, 255);
text-align: center;
background-image: linear-gradient(90deg, rgb(240, 87, 68) 0%, rgb(221, 42, 42) 100%);
border-radius: 17px;
}
}
.check_box {
position: absolute;
left: 159px;
top: 857px;
width: 450px;
max-height: 70px;
line-height: 35px;
font-size: 24px;
color: rgb(155, 155, 155);
margin-bottom: 28px;
padding-left: 45px;
font-weight: bold;
.lineClampN(2);
.check_icon {
position: absolute;
left: 0;
top: 0;
width: 34px;
height: 34px;
.sparkBg("loginPop/check_bg.png");
&.checked::after {
content: "";
position: absolute;
left: 4px;
top: 3px;
width: 33px;
height: 24px;
.sparkBg("loginPop/checked.png");
}
}
.content_title {
color: #d62928;
text-decoration: underline;
}
}
.close {
left: 346px;
top: 1186px;
width: 58px;
height: 58px;
position: absolute;
.sparkBg("common/close.png");
}
}
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
}
'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import './privacypop.less';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { Button } from '@grace/ui';
@observer
class Privacypop extends React.Component {
constructor(props) {
super(props);
}
close = () => {
const { closeCb } = this.props;
// 组件形式使用
if (closeCb) {
closeCb()
} else {
ModalCtrl.closeModal()
}
}
render() {
const { agreementText } = this.props || {}
return (
<div className="privacypop modal_center">
<span className="light"></span>
<span className="bg"></span>
<span className="title">个人信息收集声明</span>
<div className="text" dangerouslySetInnerHTML={{ __html: agreementText }}></div>
<Button className="close" onClick={this.close}></Button>
</div>
);
}
}
export default Privacypop;
@import "../../res.less";
.privacypop {
width: 750px;
height: 1624px;
left: 0px;
top: 0px;
position: absolute;
.bg {
left: 82px;
top: 406px;
width: 585px;
height: 711px;
position: absolute;
.sparkBg("privacyPop/bg.png");
}
.text {
width: 510px;
height: 540px;
left: 120px;
top: 530px;
position: absolute;
font-size: 24px;
line-height: 30px;
color: rgb(0, 0, 0);
word-wrap: break-word;
white-space: pre-wrap;
overflow-x: hidden;
overflow-y: auto;
}
.close {
left: 346px;
top: 1186px;
width: 58px;
height: 58px;
position: absolute;
.sparkBg("common/close.png");
}
}
'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import './index.less';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { Button, Toast } from '@grace/ui';
import { _asyncThrottle, dateFormatter, formatThousand } from '@/utils/utils';
import Countdown from '@/core/components/ComCountdown/index.jsx';
import store from '@/store/store';
/* 电话号码验证规则 **/
export const REG_TEL = /^1[0-9]{10}$/;
@observer
class RedPackCountPanel extends React.Component {
constructor(props) {
super(props);
}
close = () => {
ModalCtrl.closeModal()
}
/*
getRedCountDown(redRainConfig) {
const now = new Date().getTime();
const today = dateFormatter(new Date(), 'yyyy-MM-dd');
const timeArr = redRainConfig.map(el => {
return {
...el,
start: new Date(today + " " + el.startTime).getTime(),
end: new Date(today + " " + el.endTime).getTime(),
}
})
// 按照开始时间排序
timeArr.sort((a, b) => {
return a.start - b.start;
})
const el = timeArr.find(el => {
return now >= el.start && now <= el.end;
})
if (el && !el.joinStatus) {
return 0;
} else {
const next = timeArr.find(el => {
return now < el.start;
});
if (!next) {
return 0
} else {
return next.start - now
}
}
}
*/
render() {
const { redRainConfig } = store.indexData
/*
const redDownTime = this.getRedCountDown(redRainConfig || []);
*/
const redDownTime = redRainConfig?.haveNext ? redRainConfig?.nextRainBeginTime - new Date().getTime() : 0;
return (<>
<div className="redPackCountPanel modal_center">
<span className="bg"></span>
<div>
<Countdown
leftT={redDownTime}
renderText={data => {
let { day, hour, minute, second } = data
let hourNum = Number(day) * 24 + Number(hour);
hourNum = hourNum >= 10 ? hourNum + "" : '0' + hourNum;
minute = minute + "";
second = second + ""
return <div className="panel_time_box">
{hourNum.split('').map((el, index) => {
return <span className='panel_time_num' key={index}>{el}</span>
})}
<span>:</span>
{minute.split('').map((el, index) => {
return <span className='panel_time_num' key={index}>{el}</span>
})}
<span>:</span>
{second.split('').map((el, index) => {
return <span className='panel_time_num' key={index}>{el}</span>
})}
</div>
}}
countdownOver={() => {
ModalCtrl.closeModal();
store.updateIndex()
}}
/>
</div>
<Button className="iknow md25" onClick={this.close}></Button>
<Button className="close" onClick={this.close}></Button>
</div>
</>);
}
}
export default RedPackCountPanel;
@import "../../res.less";
.redPackCountPanel {
left: 82px;
top: 320px;
width: 585px;
height: 656px;
position: absolute;
.bg {
left: 0px;
top: 0px;
width: 585px;
height: 656px;
position: absolute;
.sparkBg("redPackCountPanel/redPackCountPanelBg.png");
// background-size: 585px 611px;
// background-color: #ffffff;
// border-radius: 36px;
}
.panel_time_box {
position: absolute;
width: 550px;
height: 87px;
left: 23px;
top: 251px;
text-align: center;
font-weight: bold;
font-size: 40px;
color: #d26654;
span {
margin: 0 2px;
}
.panel_time_num {
display: inline-block;
width: 60px;
height: 80px;
border-radius: 20px;
color: rgb(255, 255, 255);
font-weight: bold;
text-align: center;
font-size: 45px;
line-height: 80px;
.sparkBg("redPackCountPanel/numBg.png");
}
}
.close {
left: 264px;
top: 756px;
width: 58px;
height: 58px;
position: absolute;
.sparkBg("redPackCountPanel/closeBtn.png");
}
.iknow {
left: 38px;
top: 504px;
width: 510px;
height: 138px;
position: absolute;
.sparkBg("redPackCountPanel/iknowBtn.png");
}
}
\ No newline at end of file
@import '../../res.less';
.redPackRainModal {
width: 100%;
height: 100%;
position: absolute;
background-color: rgba(0, 0, 0, 0.5);
.gameCutDownBg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
// background-color: rgba(0, 0, 0, 0.7);
overflow: hidden;
.cutDownSvga {
width: 677px;
height: 947px;
position: absolute;
left: 36px;
top: 200px;
}
}
.redText {
width: 750px;
height: 1804px;
position: absolute;
top: -300px;
}
.redCount {
width: 649px;
height: 619px;
position: absolute;
left: calc(50% - 324px);
top: calc(50% - 309px);
}
.cd {
position: absolute;
left: 566px;
//top: 196px;
// top: 12.0%;
top: 45px;
width: 164px;
height: 135px;
.webpBg("common/clock.png");
.cd-text {
position: absolute;
// left: 50px;
top: 63px;
width: 170px;
height: 60px;
text-align: center;
font-size: 26px;
color: #ffffff;
font-weight: bold;
}
}
}
\ No newline at end of file
import React, { Component } from 'react';
import { Game, GAME_EVENT, GDispatcher } from "../../GameModule/GameModule";
import './redPackRainModal.less';
import store from '@/store/store';
import { _throttle } from '@/utils/utils';
import API from '@/api';
import { SvgaPlayer } from '@grace/svgaplayer';
import redText from '../../assets/svga/2红包雨来袭.svga';
import redCount from '../../assets/svga/3倒计时.svga';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { PrizePanel } from '../PrizePanel/PrizePanel';
import { NoPrizePanel } from '../NoPrizePanel/NoPrizePanel';
class RedPackRainModal extends Component<any, any> {
state = {
// 红包雨时间
gameDuration: store?.indexData?.redRainConfig?.redRainCountDownTime || 0,
// 是否准备
showReady: true,
showRed: true,
}
async componentDidMount() {
await this.initGame()
// await this.startGame();
}
onEnd = () => {
this.setState({ showReady: false}, () => {
// modalStore.pushPop("RedPackRainModal")
GDispatcher.dispatchEvent(GAME_EVENT.START_GAME);
this.startTimer();
});
}
currentRecordId = null;
startGame = async() => {
const { redRainId } = this.props;
const res = await API.redStartGame({
redRainId
})
if(!res || !res.data || !res.success) return
this.currentRecordId = res.data?.currentRecordId;
GDispatcher.dispatchEvent(GAME_EVENT.START_GAME);
this.startTimer();
}
playground = null;
game = null;
awaitInitGame = null;
/** 初始化游戏舞台 */
initGame() {
if (!this.awaitInitGame) {
this.awaitInitGame = new Promise((resolve: any) => {
const canvas:any = document.createElement("canvas");
canvas.style = "position:absolute;width:100%;height:100%";
this.playground.appendChild(canvas);
this.game = new Game(canvas, 750, 1624);
this.game.initWebEvent();
GDispatcher.once(GAME_EVENT.READY, () => {
resolve();
});
GDispatcher.addEventListener(GAME_EVENT.ADD_SCORE, this.clickRed, this);
});
}
return this.awaitInitGame;
}
score = 0;
clickRed = _throttle(() => {
this.score += 1;
}, 0);
timer = null;
startTimer = () => {
let { gameDuration } = this.state;
this.timer = setInterval(async () => {
if (gameDuration <= 0) {
this.gameStop();
} else {
this.setState({
gameDuration: (gameDuration -= 1)
});
}
}, 1000);
}
gameStop = async () => {
// this.gameIng = false;
GDispatcher.dispatchEvent(GAME_EVENT.END_GAME);
clearInterval(this.timer);
// return
const { success, data } = await API.redSubmitGame({
currentRecordId: this.currentRecordId
}) || {};
await store.updateIndex();
ModalCtrl.closeModal();
if (success && data && data?.prizeId != 'thanks') {
ModalCtrl.showModal(PrizePanel, {optionImg: data?.prizeImg, optionName: data?.prizeName, type: 'red'})
} else {
ModalCtrl.showModal(NoPrizePanel, {type: 'red'})
}
}
redTextEnd = () => {
this.setState({
showRed: false
})
}
redCountEnd = () => {
this.setState({
showReady: false
})
this.startGame();
}
componentWillUnmount() {
clearInterval(this.timer);
GDispatcher.removeEventListener(GAME_EVENT.ADD_SCORE, this.clickRed, this);
this.setState = () => 0;
}
render() {
const {gameDuration, showReady, showRed} = this.state;
return (
<div className='redPackRainModal'>
{showReady && <>
{showRed && <SvgaPlayer className='redText' src={redText} loop={1} onEnd={this.redTextEnd}/>}
{!showRed && <SvgaPlayer className='redCount' src={redCount} loop={1} onEnd={this.redCountEnd}/>}
</>}
<div className="game_canvas" ref={(playground) => (this.playground = playground)}></div>
<div className="cd">
<div className="cd-bg"/>
<div className="cd-text">{gameDuration}</div>
</div>
</div>
);
}
}
export default RedPackRainModal;
......@@ -30,7 +30,6 @@ class SetupSuccessPop extends React.Component {
onStop = async() => {
this.btnStarting = false;
store.updateIndex();
if (this.drawResultInfo.prizeId == "thanks") {
ModalCtrl.showModal(NoPrizePanel, {type: 'final_turntable', ...this.drawResultInfo});
} else {
......
......@@ -37,7 +37,7 @@
left: 0;
top: 0;
position: absolute;
.sparkBg("ResPage/转盘背景.png");
.sparkBg("setupSuccessPop/转盘背景.png");
}
.prize_item {
......@@ -75,7 +75,7 @@
top: 895px;
width: 169px;
height: 178px;
.webpBg("ResPage/点击抽奖.png");
.webpBg("setupSuccessPop/点击抽奖.png");
}
}
......
'use strict';
import React from 'react';
import { observer } from 'mobx-react';
import './sharepop.less';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import shareStore from '@/store/share';
import { _throttle } from '@/utils/utils';
import { Toast } from '@grace/ui';
import { copyToClipboard } from '@spark/utils';
@observer
class Sharepop extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
shareStore.getShareLink(true);
}
copyHandle = _throttle(() => {
copyToClipboard(shareStore.inviteUrl);
setTimeout(() => {
copyToClipboard(shareStore.inviteUrl);
}, 200)
Toast.show("邀请链接已复制,快去微信打开吧")
})
close = () => {
ModalCtrl.closeModal()
}
render() {
return (
<div className="sharepop modal_center">
<span className="close" onClick={this.close}></span>
<span className="bg"></span>
<div className="copy_btn" onClick={this.copyHandle}></div>
<span className="tips">将已复制链接发送好友,好友微信打开链接即可点赞助力</span>
</div>
);
}
}
export default Sharepop;
@import "../../res.less";
.sharepop {
width: 750px;
height: 1624px;
left: 0px;
top: 0px;
position: absolute;
.close {
left: 345px;
top: 1344px;
width: 58px;
height: 58px;
position: absolute;
.sparkBg("common/close.png");
}
.bg {
left: 70px;
top: 366px;
width: 607px;
height: 862px;
position: absolute;
.sparkBg("sharePop/bg.png");
}
.copy_btn {
left: 162px;
top: 1056px;
width: 425px;
height: 98px;
position: absolute;
.sparkBg("sharePop/copy_btn.png");
}
.tips {
position: absolute;
left: 70px;
top: 1173px;
width: 607px;
font-size: 20px;
color: rgba(63, 43, 43, 0.671);
text-align: center;
}
}
......@@ -5,7 +5,6 @@ import { CHANNEL } from '@/AppTools';
import { Toast } from '@grace/ui';
import { hxbankShare } from './bank';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import Sharepop from '@/panels/sharepop/sharepop';
const shareStore = makeAutoObservable({
......@@ -51,7 +50,7 @@ const shareStore = makeAutoObservable({
url: _url
})
} else {
ModalCtrl.showModal(Sharepop)
}
},
......
......@@ -7,16 +7,15 @@ import { PageCtrl } from '@/core/ctrls/PageCtrl';
import { ModalCtrl } from '@/core/ctrls/ModalCtrl';
import { getDomain } from '@spark/dbdomain';
import { showShareGuide } from '@spark/share';
import Loginpop from '@/panels/loginpop/loginpop';
import InvalidPop from '@/panels/invalidPop/invalidPop';
import FirstPop from '@/panels/firstPop/firstPop';
import Tipspop from '@/panels/tipspop/tipspop';
import { IS_OTHER_APP, isWeiXin, queryAppFundDetail } from '@/AppTools';
import { CHANNEL } from '@/AppTools';
import RedPackRainModal from '@/panels/redPackRainModal/redPackRainModal';
import { errMessageMap } from '@/utils/errorHandler';
import BlackPop from '@/panels/blackPop/index';
import SetupPop from '@/panels/setupPop/index';
import EndPop from '@/panels/endPop';
import { PrizePanel } from '@/panels/PrizePanel/PrizePanel';
class Store {
......@@ -101,6 +100,7 @@ class Store {
pop: boolean,
show: boolean
},
lcGradeIcon: boolean,
lastMonthRankPop: boolean,
overallRankPop: {
prizeId: string,
......@@ -117,30 +117,6 @@ class Store {
} = {} as any;
percent = 0;
async judgeIsWhiteUser() {
const { success, data, code, message } = await API.isWhiteUser({
"redirectUrl": CFG.domain + CFG.index
});
if (success) {
if (data) {
location.replace(data);
} else {
await this.updateIndex();
}
} else if (code == 60001) {
// 非白名单用户
ModalCtrl.showModal(InvalidPop);
} else if (code == 60002) {
// 请绑定手机号
ModalCtrl.showModal(Loginpop)
} else if ((CFG.channel == CHANNEL.KUNLUN) && (code == 100001 || code == 100007 || code == 100009)) {
// 只有昆仑银行 需要绑定手机号 其他渠道拦截登录直接出未登录toast,防止奖品被刷
ModalCtrl.showModal(Loginpop);
} else {
Toast.show(errMessageMap[code] || message || '网络异常,请稍后再试')
}
}
homeRoot = null;
async updateIndex() {
......@@ -152,7 +128,7 @@ class Store {
resData.currentTime = timeStamp;
this.indexData = resData;
const { isBlack, giftPop } = resData
const { isBlack, giftPop, lastMonthRankPop, overallRankPop } = resData
// 非白名单名单拦截弹窗
if (isBlack) {
......@@ -164,78 +140,18 @@ class Store {
ModalCtrl.showModal(SetupPop);
}
// 计算进度条百分比
// if (checkIn?.checkInConfig && checkIn?.totalCheckIn !== undefined) {
// this.percent = this.calculateProgressPercent(checkIn.checkInConfig, checkIn.totalCheckIn);
// console.log(`当前签到${checkIn.totalCheckIn}天,进度条百分比: ${this.percent.toFixed(1)}%`);
// } else {
// this.percent = 0;
// }
// // 防止奖品被刷 禁止微信端访问了 这个弹窗不会出了 配置项控制
// if (endPop) {
// ModalCtrl.showModal(Tipspop);
// }
// // 更新产品信息
// if (codeList?.length && CFG.channel == CHANNEL.HXLC) {
// this.updateFundInfo(codeList)
// }
// if (redRainConfig?.canJoin) {
// // 在时间段内,显示红包雨弹窗
// ModalCtrl.showModal(RedPackRainModal, { redRainId: redRainConfig?.redRainId });
// }
// if (firstMoneyPop) {
// ModalCtrl.showModal(FirstPop, firstMoneyPop);
// }
}
/*
judgeRedModal() {
const redRainConfig = this.indexData?.redRainConfig
// 红包雨时间段判断
const everyJoinStatus = redRainConfig?.some(item => !item?.joinStatus);
if (everyJoinStatus) {
const len = redRainConfig?.length;
for (let i = 0; i < len; i++) {
const redItem = redRainConfig?.[i];
const redStart = getTimeStamp(redItem?.startTime);
const redEnd = getTimeStamp(redItem?.endTime);
// 看看是不是在开始的场次之前 那就直接等最开始的倒计时就行了
if (this.indexData.currentTime < redStart) {
this.leftOpenTime = redStart - this.indexData.currentTime;
break;
}
if (this.indexData.currentTime >= redStart && this.indexData.currentTime <= redEnd && !redItem?.joinStatus) {
// 在时间段内,显示红包雨弹窗
ModalCtrl.showModal(RedPackRainModal, { redRainId: redItem?.rainId });
break;
}
// 看看是不是最后一场之后 那就直接等第二天的时间
if (this.indexData.currentTime > redEnd && i == len - 1) {
const firstStart = getTimeStamp(redRainConfig?.[0]?.startTime);
this.leftOpenTime = firstStart + 24 * 60 * 60 * 1000 - this.indexData.currentTime;
break;
}
}
// 上月理财成绩弹窗
if (lastMonthRankPop) {
ModalCtrl.showModal(EndPop);
}
if (this.leftOpenTime > 0) {
this.leftOpenId = setTimeout(async () => {
await this.updateIndex();
this.judgeRedModal();
clearTimeout(this.leftOpenId);
this.leftOpenId = null;
this.leftOpenTime = 0;
}, this.leftOpenTime)
}
if (overallRankPop) {
ModalCtrl.showModal(PrizePanel, {
optionImg: overallRankPop.prizeImg,
optionName: overallRankPop.prizeName,
});
}
}
*/
/**
* 更新某些基金信息
......
import { CHANNEL, IS_OTHER_APP, isWeiXin } from "@/AppTools";
import { ModalCtrl } from "@/core/ctrls/ModalCtrl";
import Loginpop from "@/panels/loginpop/loginpop";
import { Toast } from "@grace/ui";
// 需要过滤的错误码
......@@ -24,9 +23,6 @@ export const errMessageMap = {
*/
export function errorHandler(error) {
if ((error.code == 0 && error.message == "请稍后再试") || filterCode.indexOf(`${error.code}`) >= 0) return;
// 微信端/华夏理财/三方合作APP 未登录时 其他接口都走登录弹窗
// 20250903迭代:只有昆仑银行 需要绑定手机号 其他渠道拦截登录直接出未登录toast,防止奖品被刷
if ((CFG.channel == CHANNEL.KUNLUN) && (error.code == 100001 || error.code == 100007 || error.code == 100009)) return ModalCtrl.showModal(Loginpop);
switch (error.code) {
default: {
const msg = errMessageMap[error.code] || error.message || '网络异常,请稍后再试';
......
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