Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
TianGongKaiWu-20251203
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
SparkProjects
TianGongKaiWu-20251203
Commits
94333785
Commit
94333785
authored
Dec 04, 2025
by
王勇霞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 调整
parent
c7524f25
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
14553 additions
and
89 deletions
+14553
-89
package.json
package.json
+9
-7
pnpm-lock.yaml
pnpm-lock.yaml
+13859
-0
index.html
public/index.html
+28
-35
AppTool.js
src/AppTool.js
+61
-21
app.jsx
src/app.jsx
+2
-1
app.less
src/app.less
+1
-2
assetList.json
src/assetList.json
+1
-1
tab1_bg.png
src/assets/ActualHome/tab1_bg.png
+0
-0
tab2_bg.png
src/assets/ActualHome/tab2_bg.png
+0
-0
index.jsx
src/pages/ActualHome/index.jsx
+25
-17
index.less
src/pages/ActualHome/index.less
+1
-0
index.jsx
src/pages/DetailPage/index.jsx
+300
-0
index.less
src/pages/DetailPage/index.less
+0
-0
index.jsx
src/pages/components/ProductListModule/index.jsx
+74
-0
index.less
src/pages/components/ProductListModule/index.less
+185
-0
index.less
src/pages/components/SignModule/index.less
+4
-4
index.js
src/store/index.js
+1
-1
constants.js
src/utils/constants.js
+2
-0
No files found.
package.json
View file @
94333785
...
@@ -18,25 +18,27 @@
...
@@ -18,25 +18,27 @@
},
},
"dependencies"
:
{
"dependencies"
:
{
"
@spark/api-base
"
:
"
^2.0.36
"
,
"
@spark/api-base
"
:
"
^2.0.36
"
,
"
@spark/api-common
"
:
"
^2.0.22
"
,
"
@spark/disk-turntable
"
:
"
^1.0.27
"
,
"
@spark/projectx
"
:
"
^2.0.13
"
,
"
@spark/share
"
:
"
^2.0.242
"
,
"
@spark/svgaplayer
"
:
"
^2.0.5
"
,
"
@spark/svgaplayer
"
:
"
^2.0.5
"
,
"
@spark/ui
"
:
"
^2.0.8
"
,
"
@spark/ui
"
:
"
^2.0.8
"
,
"
@spark/utils
"
:
"
^2.0.17
"
,
"
@spark/utils
"
:
"
^2.0.17
"
,
"
classnames
"
:
"
^2.5.1
"
,
"
classnames
"
:
"
^2.5.1
"
,
"
crypto-js
"
:
"
^4.2.0
"
,
"
crypto-js
"
:
"
^4.2.0
"
,
"
duiba-utils
"
:
"
^1.0.2
"
,
"
duiba-utils
"
:
"
^1.0.2
"
,
"
framer-motion
"
:
"
6.5.1
"
,
"
history
"
:
"
^4.10.1
"
,
"
history
"
:
"
^4.10.1
"
,
"
hx-product_detail-link
"
:
"
^1.0.6
"
,
"
javascript-obfuscator
"
:
"
^4.1.0
"
,
"
javascript-obfuscator
"
:
"
^4.1.0
"
,
"
mobx
"
:
"
^6.2.0
"
,
"
mobx
"
:
"
^6.2.0
"
,
"
mobx-react
"
:
"
^7.1.0
"
,
"
mobx-react
"
:
"
^7.1.0
"
,
"
qs
"
:
"
^6.9.4
"
,
"
qs
"
:
"
^6.9.4
"
,
"
react
"
:
"
^16.
4.1
"
,
"
react
"
:
"
^16.
14.0
"
,
"
react-dom
"
:
"
^16.
4.1
"
,
"
react-dom
"
:
"
^16.
14.0
"
,
"
spark-utils
"
:
"
^0.0.12
"
,
"
spark-utils
"
:
"
^0.0.12
"
,
"
terser-webpack-plugin
"
:
"
4.2.3
"
,
"
terser-webpack-plugin
"
:
"
4.2.3
"
"
@spark/api-common
"
:
"
^2.0.22
"
,
"
@spark/projectx
"
:
"
^2.0.13
"
,
"
@spark/share
"
:
"
^2.0.242
"
,
"
@spark/disk-turntable
"
:
"
^1.0.27
"
},
},
"devDependencies"
:
{
"devDependencies"
:
{
"
@babel/core
"
:
"
^7.12.10
"
,
"
@babel/core
"
:
"
^7.12.10
"
,
...
...
pnpm-lock.yaml
0 → 100644
View file @
94333785
This diff is collapsed.
Click to expand it.
public/index.html
View file @
94333785
<!DOCTYPE html>
<!DOCTYPE html>
<html
lang=
"zh"
>
<html
lang=
"zh"
>
<head>
<head>
<meta
charset=
"utf-8"
/>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, shrink-to-fit=no"
>
<meta
name=
"theme-color"
content=
"#000000"
/>
<meta
name=
"theme-color"
content=
"#000000"
>
<link
rel=
"dns-prefetch"
href=
"//yun.duiba.com.cn"
/>
<link
rel=
"dns-prefetch"
href=
"//yun.duiba.com.cn"
/>
<link
rel=
"preconnect"
href=
"//embedlog.duiba.com.cn"
>
<link
rel=
"preconnect"
href=
"//embedlog.duiba.com.cn"
/
>
<title>
活动标题
</title>
<title>
活动标题
</title>
<script
type=
"text/javascript"
>
<script
type=
"text/javascript"
>
if
(
localStorage
&&
localStorage
.
isWebp
)
{
if
(
localStorage
&&
localStorage
.
isWebp
)
{
document
document
.
getElementsByTagName
(
"html"
)[
0
].
setAttribute
(
"duiba-webp"
,
"true"
);
.
getElementsByTagName
(
'html'
)[
0
]
}
.
setAttribute
(
'duiba-webp'
,
'true'
);
}
</script>
</script>
<script
src=
"//yun.duiba.com.cn/spark/v2/spark.base.fz.wxpollyfill.js"
></script>
<script
src=
"//yun.duiba.com.cn/spark/v2/spark.base.fz.wxpollyfill.js"
></script>
<script
src=
"//yun.duiba.com.cn/js-libs/rem/1.1.3/rem.min.js"
></script>
<script
src=
"//yun.duiba.com.cn/js-libs/rem/1.1.3/rem.min.js"
></script>
<script
src=
"//yun.duiba.com.cn/h5/lib/zepto.min.js"
></script>
<script
src=
"//yun.duiba.com.cn/h5/lib/zepto.min.js"
></script>
<!-- 华夏银行app文件 -->
<script
src=
"//yun.duiba.com.cn/polaris/hxbExtLib.min.f2e3022c5ce5dd92689bff0a5b6c5cb0e9193cd1.js"
></script>
<script>
<script>
var
CFG
=
CFG
||
{};
var
CFG
=
CFG
||
{};
CFG
.
projectId
=
location
.
pathname
.
split
(
'/'
)[
2
]
||
'1'
;
CFG
.
projectId
=
location
.
pathname
.
split
(
"/"
)[
2
]
||
"1"
;
function
getUrlParam
(
name
)
{
function
getUrlParam
(
name
)
{
var
search
=
window
.
location
.
search
;
var
search
=
window
.
location
.
search
;
var
matched
=
search
var
matched
=
search
.
slice
(
1
).
match
(
new
RegExp
(
"(^|&)"
+
name
+
"=([^&]*)(&|$)"
,
"i"
));
.
slice
(
1
)
return
search
.
length
?
matched
&&
matched
[
2
]
:
null
;
.
match
(
new
RegExp
(
'(^|&)'
+
name
+
'=([^&]*)(&|$)'
,
'i'
));
}
return
search
.
length
?
matched
&&
matched
[
2
]
:
null
;
}
CFG
.
appID
=
"${APPID}"
;
if
(
!
getUrlParam
(
"appID"
))
{
CFG
.
appID
=
'${APPID}'
;
// alert("【警告】检测到活动url中没有appID参数\n缺少该参数会导致埋点、分享、app信息获取错误。")
if
(
!
getUrlParam
(
"appID"
))
{
}
// alert("【警告】检测到活动url中没有appID参数\n缺少该参数会导致埋点、分享、app信息获取错误。")
}
</script>
</script>
</head>
</head>
<body>
<body>
<noscript>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
You need to enable JavaScript to run this app.
</noscript>
<div
id=
"root"
></div>
<div
id=
"root"
></div>
<!--
<!--
This HTML file is a template.
This HTML file is a template.
...
@@ -52,7 +47,5 @@
...
@@ -52,7 +47,5 @@
To begin the development, run `npm start` or `yarn start`.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
-->
</body>
</body>
</html>
</html>
\ No newline at end of file
src/AppTool.js
View file @
94333785
import
API
from
"@src/api"
;
/** 渠道 */
import
{
export
const
CHANNEL
=
{
setCookieId
/** 华夏理财 */
}
from
"@src/api/utils"
;
HXLC
:
"1"
,
/** 母行-华夏银行 */
HXBANK
:
"2"
,
/** 渠道5-昆仑银行 */
KUNLUN
:
"5"
,
};
/**
/**
* 普通跳转客服
* 普通跳转客服
* 注意:小程序需要额外增加业务域名 https://duiba.qiyukf.com/
* 注意:小程序需要额外增加业务域名 https://duiba.qiyukf.com/
*/
*/
export
function
jumpService
()
{
export
function
jumpService
()
{
location
.
href
=
location
.
origin
+
'/faq/index'
location
.
href
=
location
.
origin
+
"/faq/index"
;
}
}
/** 跳转行方页面-华夏理财 */
export
function
hxlcAppJump
(
fundcode
)
{
const
navBarStyle
=
{
backgroundColor
:
"#d20a10"
};
const
target
=
// eslint-disable-next-line @spark/best-practices/no-url-in-js
"gmu://web?startPage="
+
encodeURIComponent
(
`index.html#/fund-detail?fundcode=
${
fundcode
}
&from=third`
)
+
`&navBarType=2&navBarStyle=
${
encodeURIComponent
(
JSON
.
stringify
(
navBarStyle
))}
`
;
console
.
info
(
"目标地址=================>:"
,
target
);
window
.
location
.
href
=
target
;
}
export
function
appJump
(
url
,
hideNavbar
=
false
,
data
=
{})
{
// 判断jsbridge加载完成
API
.
tempSaveCookie
().
then
((
res
)
=>
{
function
ready
(
callback
)
{
if
(
res
?.
data
)
{
if
(
window
.
AlipayJSBridge
)
{
localStorage
.
setItem
(
"db_temp_cookie"
,
res
.
data
);
callback
&&
callback
();
// setCookieId(res.data);
}
else
{
}
document
.
addEventListener
(
"AlipayJSBridgeReady"
,
callback
,
false
);
}).
finally
(()
=>
{
}
}
// app对应跳转方法
function
bfSearchMenu
(
param
,
callback
)
{
window
.
MarsJSBridge
.
invoke
(
"pushPage"
,
{
window
.
AlipayJSBridge
.
call
(
uri
:
url
,
"BFSearchMenuHandler"
,
data
,
{
pageParams
:
{
param
:
param
,
hideNavbar
,
},
}
callback
});
);
}
/** 行方跳转方法-华夏银行 */
export
function
appJump
(
url
)
{
console
.
info
(
"bfSearchMenu url"
,
url
);
// 判断端内,若在端内走回调
ready
(()
=>
{
// 跳转的路径,视具体修改
bfSearchMenu
({
url
,
});
});
});
}
}
/** 跳转方法 区分app */
export
function
diffJump
(
url
)
{
if
(
CFG
.
channel
==
CHANNEL
.
HXLC
)
{
// 华夏理财
hxlcAppJump
(
url
);
}
else
if
(
CFG
.
channel
==
CHANNEL
.
HXBANK
)
{
// 华夏银行
appJump
(
url
);
}
else
{
// 其他三方app
location
.
href
=
url
;
}
}
src/app.jsx
View file @
94333785
...
@@ -15,15 +15,16 @@ MD();
...
@@ -15,15 +15,16 @@ MD();
import
LoadingDemo
from
"@src/pages/LoadingDemo/LoadingDemo"
;
import
LoadingDemo
from
"@src/pages/LoadingDemo/LoadingDemo"
;
import
ActualHome
from
"@src/pages/ActualHome/index"
;
import
ActualHome
from
"@src/pages/ActualHome/index"
;
import
PrizePage
from
"@src/pages/PrizePage"
;
import
PrizePage
from
"@src/pages/PrizePage"
;
import
DetailPage
from
"@src/pages/DetailPage"
;
import
{
PAGE_MAP
}
from
"./utils/constants"
;
import
{
PAGE_MAP
}
from
"./utils/constants"
;
/**
/**
* 所有页面场景
*/
*/
const
pageMap
=
{
const
pageMap
=
{
[
PAGE_MAP
.
LOADING_PAGE
]:
<
LoadingDemo
/>
,
[
PAGE_MAP
.
LOADING_PAGE
]:
<
LoadingDemo
/>
,
[
PAGE_MAP
.
ACTUAL_HOME_PAGE
]:
<
ActualHome
/>
,
[
PAGE_MAP
.
ACTUAL_HOME_PAGE
]:
<
ActualHome
/>
,
[
PAGE_MAP
.
PRIZE_PAGE
]:
<
PrizePage
/>
,
[
PAGE_MAP
.
PRIZE_PAGE
]:
<
PrizePage
/>
,
[
PAGE_MAP
.
PRODUCT_DETAIL
]:
<
DetailPage
/>
,
};
};
@
observer
@
observer
...
...
src/app.less
View file @
94333785
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
-webkit-user-select: text;
-webkit-user-select: text;
}
}
*:not(input,textarea) {
*:not(input,
textarea) {
-webkit-touch-callout: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
-webkit-user-select: none;
}
}
...
@@ -42,7 +42,6 @@ body {
...
@@ -42,7 +42,6 @@ body {
overflow: hidden;
overflow: hidden;
}
}
.com_Container {
.com_Container {
width: 100%;
width: 100%;
height: 100%;
height: 100%;
...
...
src/assetList.json
View file @
94333785
{
"preLoadImg"
:[],
"asyncLoadImg"
:[
"ActualHome/bg.png"
,
"ActualHome/financeAchievement.png"
,
"ActualHome/newUserGift.png"
,
"ActualHome/prize.png"
,
"ActualHome/rule.png"
,
"ActualHome/sign_bg.png"
,
"ActualHome/sign_btn.png"
,
"ActualHome/sign_ok.png"
,
"ActualHome/sign_task.png"
,
"ActualHome/sign_task_title.png"
,
"ActualHome/sign_wait.png"
,
"Common/close.png"
,
"LoadingPage/loadingBg.jpg"
,
"LoadingPage/loadingFill.png"
,
"LoadingPage/loadingIp.png"
,
"Pop/BlackListPop/bg.png"
,
"Pop/BlackListPop/btn_actual.png"
,
"Pop/BlackListPop/title_actual.png"
,
"Pop/RulePop/bg.png"
]}
{
"preLoadImg"
:[],
"asyncLoadImg"
:[
"ActualHome/bg.png"
,
"ActualHome/financeAchievement.png"
,
"ActualHome/newUserGift.png"
,
"ActualHome/prize.png"
,
"ActualHome/rule.png"
,
"ActualHome/sign_bg.png"
,
"ActualHome/sign_btn.png"
,
"ActualHome/sign_ok.png"
,
"ActualHome/sign_task.png"
,
"ActualHome/sign_task_title.png"
,
"ActualHome/sign_wait.png"
,
"ActualHome/tab1_bg.png"
,
"ActualHome/tab2_bg.png"
,
"Common/close.png"
,
"LoadingPage/loadingBg.jpg"
,
"LoadingPage/loadingFill.png"
,
"LoadingPage/loadingIp.png"
,
"Pop/BlackListPop/bg.png"
,
"Pop/BlackListPop/btn_actual.png"
,
"Pop/BlackListPop/title_actual.png"
,
"Pop/RulePop/bg.png"
,
"PrizePage/back.png"
,
"PrizePage/bg.png"
,
"PrizePage/empty_img.png"
,
"PrizePage/item_btn_bg.png"
,
"PrizePage/item_btn_bg2.png"
]}
\ No newline at end of file
\ No newline at end of file
src/assets/ActualHome/tab1_bg.png
0 → 100644
View file @
94333785
13.1 KB
src/assets/ActualHome/tab2_bg.png
0 → 100644
View file @
94333785
11.9 KB
src/pages/ActualHome/index.jsx
View file @
94333785
import
React
from
"react"
;
import
React
from
"react"
;
import
{
observer
}
from
"mobx-react"
;
import
{
observer
}
from
"mobx-react"
;
import
{
Button
}
from
"@src/components/Button"
;
import
{
Button
}
from
"@src/components/Button"
;
import
SignModule
from
"@src/pages/components/SignModule/index"
;
import
SignModule
from
"@src/pages/components/SignModule"
;
import
RankModule
from
"@src/pages/components/RankModule/index"
;
import
RankModule
from
"@src/pages/components/RankModule"
;
import
BannerModule
from
"@src/pages/components/BannerModule/index"
;
import
BannerModule
from
"@src/pages/components/BannerModule"
;
import
ProductListModule
from
"@src/pages/components/ProductListModule"
;
import
"./index.less"
;
import
"./index.less"
;
import
modalStore
from
"@src/store/modal"
;
import
modalStore
from
"@src/store/modal"
;
import
{
_throttle
}
from
"@src/utils/utils"
;
import
{
_throttle
}
from
"@src/utils/utils"
;
...
@@ -28,25 +29,32 @@ class ActualHome extends React.Component {
...
@@ -28,25 +29,32 @@ class ActualHome extends React.Component {
render
()
{
render
()
{
return
(
return
(
<
div
className=
"actual-home-page"
>
<
div
className=
"com_Container"
>
{
/* 规格&奖品 */
}
<
div
className=
"actual-home-page"
>
<
Button
className=
"rule-icon"
onClick=
{
this
.
openRule
}
></
Button
>
{
/* 规格&奖品 */
}
<
Button
className=
"prize-icon"
onClick=
{
this
.
goPrize
}
></
Button
>
<
Button
className=
"rule-icon"
onClick=
{
this
.
openRule
}
></
Button
>
<
Button
className=
"prize-icon"
onClick=
{
this
.
goPrize
}
></
Button
>
{
/* 其他icon */
}
{
/* 其他icon */
}
<
Button
className=
"new-user-gift-icon"
></
Button
>
<
Button
className=
"new-user-gift-icon"
></
Button
>
<
Button
className=
"finance-achievement-icon"
></
Button
>
<
Button
className=
"finance-achievement-icon"
></
Button
>
{
/* 排行榜 */
}
{
/* 排行榜 */
}
<
RankModule
/>
<
RankModule
/>
{
/* 真实持仓 */
}
{
/* 真实持仓 */
}
{
/* banner区 */
}
{
/* banner区 */
}
<
BannerModule
/>
<
BannerModule
/>
{
/* 签到 */
}
{
/* 签到 */
}
<
SignModule
/>
<
SignModule
/>
{
/* 产品列表 */
}
<
ProductListModule
/>
<
div
style=
{
{
height
:
"90px"
}
}
></
div
>
</
div
>
</
div
>
</
div
>
);
);
}
}
...
...
src/pages/ActualHome/index.less
View file @
94333785
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
background-size: 750px 779px;
background-size: 750px 779px;
background-color: #e86a3c;
background-color: #e86a3c;
box-sizing: border-box;
box-sizing: border-box;
overflow-y: scroll;
}
}
.rule-icon {
.rule-icon {
...
...
src/pages/DetailPage/index.jsx
0 → 100644
View file @
94333785
import
React
from
"react"
;
import
{
observer
}
from
"mobx-react"
;
import
"./index.less"
;
// import { Button, Toast } from "@grace/ui";
import
{
motion
}
from
"framer-motion"
;
import
classNames
from
"classnames"
;
import
API
from
"@src/api"
;
import
{
_throttle
}
from
"@src/utils/utils"
;
import
{
PAGE_MAP
}
from
"@src/utils/constants"
;
import
{
Button
}
from
"@src/components/Button"
;
import
modalStore
from
"@src/store/modal"
;
import
modal
from
"@src/store"
;
import
hxLink
from
"hx-product_detail-link"
;
// import { diffJump } from "@src/AppTool";
const
EOpType
=
{
Buy
:
"buy"
,
Sell
:
"sell"
,
};
@
observer
class
DetailPage
extends
React
.
Component
{
state
=
{
tabType
:
EOpType
.
Buy
,
productName
:
""
,
totalProfit
:
0
,
tranche
:
0
,
marketValue
:
0
,
yesterdayProfit
:
0
,
availableFunds
:
0
,
minBuyLimit
:
0
,
sellInput
:
""
,
buyInput
:
""
,
iframeUrl
:
""
,
};
async
componentDidMount
()
{
this
.
getFrameUrl
();
this
.
updateInfo
();
}
getFrameUrl
=
()
=>
{
// 1912121000101
hxLink
({
fundcode
:
this
.
props
.
code
}).
then
((
res
)
=>
{
this
.
setState
({
iframeUrl
:
res
.
path
,
});
});
};
async
updateInfo
()
{
const
{
success
,
data
}
=
await
API
.
mncpIndex
({
code
:
this
.
props
.
code
});
if
(
!
success
)
return
;
this
.
setState
({
productName
:
data
.
productName
,
totalProfit
:
data
.
totalProfit
,
tranche
:
data
.
tranche
,
marketValue
:
data
.
marketValue
,
yesterdayProfit
:
data
.
yesterdayProfit
,
availableFunds
:
data
.
availableFunds
,
minBuyLimit
:
data
.
minBuyLimit
,
buyInput
:
data
.
availableFunds
/
100
,
});
}
clickTab
=
(
type
)
=>
{
this
.
setState
({
tabType
:
type
,
});
};
clickSimulateBuy
=
_throttle
(
async
()
=>
{
const
{
buyInput
}
=
this
.
state
;
console
.
log
(
buyInput
);
if
(
!+
buyInput
||
buyInput
.
toString
().
trim
()
===
""
)
{
// Toast.show("请输入买入金额");
return
;
}
// +(+xxx * 100).toFixed(0) 解决精度问题 比如76.9*100=7690.000000000001 而不是7690
if
(
+
(
+
buyInput
*
100
).
toFixed
(
0
)
<
this
.
state
.
minBuyLimit
)
{
// Toast.show("低于起购价");
return
;
}
const
div
=
+
(
+
buyInput
*
100
).
toFixed
(
0
)
/
this
.
state
.
minBuyLimit
;
if
(
div
!==
Math
.
floor
(
div
))
{
// Toast.show("按起购倍数递增哦~");
return
;
}
if
(
+
(
+
buyInput
*
100
).
toFixed
(
0
)
>
this
.
state
.
availableFunds
)
{
// Toast.show("超出买入上限啦");
return
;
}
modalStore
.
pushPop
(
"BuyPanel"
);
// ModalCtrl.showModal(BuyPanel, {
// name: this.state.productName,
// amount: buyInput,
// call: async () => {
// const { success } = await API.buy({ code: this.props.code, amount: +(+buyInput * 100).toFixed(0) });
// this.updateInfo();
// if (!success) return;
// Toast.show("购买成功");
// },
// });
});
clickReallyBuy
=
_throttle
(
async
()
=>
{
// ModalCtrl.showModal(JumpConfirmPop, {
// confirmCb: () => {
// diffJump(this.props.realBuyJumpUrl);
// },
// });
});
clickSimulateSell
=
_throttle
(
async
()
=>
{
const
{
sellInput
}
=
this
.
state
;
console
.
log
(
sellInput
);
if
(
!+
sellInput
||
sellInput
.
toString
().
trim
()
===
""
)
{
// Toast.show("请输入赎回份额");
return
;
}
if
(
+
(
+
sellInput
*
100
).
toFixed
(
0
)
>
this
.
state
.
tranche
)
{
// Toast.show("超出赎回上限啦");
}
// ModalCtrl.showModal(SellPanel, {
// name: this.state.productName,
// amount: sellInput,
// call: async () => {
// const { success } = await API.redeem({ code: this.props.code, amount: +(+sellInput * 100).toFixed(0) });
// this.updateInfo();
// if (!success) return;
// Toast.show("赎回成功");
// },
// });
});
// 新增:输入校验,只允许数字和最多两位小数
handleInputChange
=
(
e
,
key
)
=>
{
const
value
=
e
.
target
.
value
;
// 只允许输入数字和最多两位小数
if
(
value
===
""
||
/^
\d
*
(\.\d{0,2})?
$/
.
test
(
value
))
{
this
.
setState
({
[
key
]:
value
,
});
}
};
clickBack
=
()
=>
{
modal
.
changePage
(
PAGE_MAP
.
ACTUAL_HOME_PAGE
);
};
render
()
{
const
{
tabType
,
iframeUrl
,
productName
,
totalProfit
,
tranche
,
minBuyLimit
,
marketValue
,
yesterdayProfit
,
availableFunds
,
sellInput
,
buyInput
,
}
=
this
.
state
;
const
isBuy
=
tabType
==
EOpType
.
Buy
;
const
isBuyed
=
totalProfit
||
tranche
||
marketValue
||
yesterdayProfit
;
// const isBuyed = false;
return
(
<
div
className=
"DetailPage"
>
{
isBuyed
?
(
<
div
className=
"topArea"
>
<
div
className=
"productName"
>
{
productName
}
</
div
>
<
div
className=
"label1"
>
累计收益(元)
</
div
>
<
div
className=
"totalProfit"
>
{
totalProfit
/
100
}
</
div
>
<
div
className=
"label2"
>
持有份额
</
div
>
<
div
className=
"tranche"
>
{
tranche
/
100
}
</
div
>
<
div
className=
"label3"
>
持有市值(元)
</
div
>
<
div
className=
"marketValue"
>
{
marketValue
/
100
}
</
div
>
<
div
className=
"label4"
>
昨日收益(元)
</
div
>
<
div
className=
"yesterdayProfit"
>
{
yesterdayProfit
/
100
}
</
div
>
</
div
>
)
:
(
<
div
className=
"topArea2"
>
<
div
className=
"productName"
>
{
productName
}
</
div
>
</
div
>
)
}
<
iframe
className=
"prodIframe"
src=
{
iframeUrl
}
/>
<
motion
.
div
className=
"options"
>
<
div
className=
"tab"
>
<
div
className=
"tabItem"
style=
{
{
color
:
tabType
==
EOpType
.
Buy
?
"#EA1211"
:
"#333333"
,
}
}
onClick=
{
()
=>
this
.
clickTab
(
EOpType
.
Buy
)
}
>
购买
</
div
>
<
div
className=
"tabItem"
style=
{
{
color
:
tabType
==
EOpType
.
Sell
?
"#EA1211"
:
"#333333"
,
}
}
onClick=
{
()
=>
this
.
clickTab
(
EOpType
.
Sell
)
}
>
赎回
</
div
>
<
motion
.
div
className=
"actBar"
animate=
{
{
left
:
(
isBuy
?
80
:
455
)
*
remScale
}
}
/>
</
div
>
<
motion
.
div
className=
"buy"
style=
{
{
opacity
:
isBuy
?
1
:
0
,
}
}
transition=
{
{
type
:
"tween"
}
}
initial=
{
{
x
:
0
}
}
animate=
{
{
x
:
isBuy
?
0
:
750
*
remScale
}
}
>
<
div
className=
"buyInfo"
>
<
div
>
买入金额
</
div
>
<
span
>
可用资金:
{
availableFunds
/
100
}
元
</
span
>
</
div
>
<
input
className=
"bugInput"
placeholder=
{
`¥最低买入${minBuyLimit / 100}元`
}
type=
"text"
inputMode=
"decimal"
value=
{
buyInput
}
onChange=
{
(
e
)
=>
this
.
handleInputChange
(
e
,
"buyInput"
)
}
/>
<
div
className=
"tip"
>
首次购买
{
minBuyLimit
/
100
}
元起 再次购买
{
minBuyLimit
/
100
}
元起
{
minBuyLimit
/
100
}
元递增
</
div
>
<
div
className=
"btnArea"
>
<
Button
className=
"btn simulate"
onClick=
{
this
.
clickSimulateBuy
}
>
模拟买入
</
Button
>
<
Button
className=
"btn really"
onClick=
{
this
.
clickReallyBuy
}
>
真实买入
</
Button
>
</
div
>
</
motion
.
div
>
<
motion
.
div
className=
"sell"
transition=
{
{
type
:
"tween"
}
}
initial=
{
{
x
:
750
*
remScale
}
}
animate=
{
{
x
:
isBuy
?
750
*
remScale
:
0
}
}
>
<
div
className=
"sellInfo"
>
<
div
>
赎回份额
</
div
>
<
span
>
持有份额:
{
tranche
/
100
}
份
</
span
>
</
div
>
<
div
className=
"sellInput"
>
<
input
value=
{
sellInput
}
type=
"text"
inputMode=
"decimal"
placeholder=
{
`最多可赎回${tranche / 100}份`
}
onChange=
{
(
e
)
=>
this
.
handleInputChange
(
e
,
"sellInput"
)
}
/>
<
Button
className=
"sellAll"
onClick=
{
()
=>
{
this
.
setState
({
sellInput
:
tranche
/
100
,
});
}
}
>
全部
</
Button
>
</
div
>
<
div
className=
"tip"
>
{
" "
}
</
div
>
<
div
className=
"btnArea"
>
<
Button
className=
{
classNames
(
"btn"
,
"simulate"
)
}
style=
{
{
width
:
"100%"
}
}
onClick=
{
this
.
clickSimulateSell
}
>
模拟赎回
</
Button
>
</
div
>
</
motion
.
div
>
</
motion
.
div
>
<
Button
className=
{
classNames
(
"backBtn"
,
isBuyed
?
"backBtn2"
:
""
)
}
onClick=
{
this
.
clickBack
}
/>
</
div
>
);
}
}
export
default
DetailPage
;
src/pages/DetailPage/index.less
0 → 100644
View file @
94333785
src/pages/components/ProductListModule/index.jsx
0 → 100644
View file @
94333785
import
React
,
{
useState
}
from
"react"
;
import
{
Button
}
from
"@src/components/Button"
;
import
"./index.less"
;
// 转换为函数组件以正确使用Hooks
const
ProductListModule
=
(
props
)
=>
{
const
[
curTab
,
setCurTab
]
=
useState
(
1
);
const
{
curTabProductList
=
[],
RATE_NAME
=
{}
}
=
props
;
// 切换标签页
const
toggleTab
=
(
tab
)
=>
{
setCurTab
(
tab
);
};
// 处理金额格式化
const
settleMoney
=
(
money
)
=>
{
// 这里应该实现金额格式化逻辑
return
money
.
toFixed
(
2
);
};
// 跳转到详情页
const
jumpVirtualDetailHandle
=
(
item
)
=>
{
// 这里应该实现跳转逻辑
console
.
log
(
"跳转到产品详情:"
,
item
);
};
return
(
<
div
className=
"bottom_products"
>
{
curTab
===
1
&&
<
span
className=
"tab1_bg"
></
span
>
}
{
curTab
===
2
&&
<
span
className=
"tab2_bg"
></
span
>
}
<
span
className=
"tab1_btn"
onClick=
{
()
=>
toggleTab
(
1
)
}
></
span
>
<
span
className=
"tab2_btn"
onClick=
{
()
=>
toggleTab
(
2
)
}
></
span
>
<
div
className=
"products_list"
>
{
curTabProductList
.
map
((
item
,
index
)
=>
(
<
div
className=
"b_product_item"
key=
{
`r_prdct_${index}`
}
>
<
span
className=
"b_product_name"
>
{
item
.
name
}
</
span
>
{
curTab
===
2
?
(
<>
<
div
className=
"b_product_rate"
>
<
span
className=
"b_product_rate_value"
>
{
settleMoney
(
item
.
totalProfit
||
0
)
}
</
span
>
<
span
className=
"b_product_rate_label"
>
累计收益
</
span
>
</
div
>
<
div
className=
"b_product_shu"
>
<
span
className=
"b_product_shu_value"
>
{
settleMoney
(
item
.
positionMoney
||
0
)
}
</
span
>
<
span
className=
"b_product_shu_label"
>
持仓金额
</
span
>
</
div
>
</>
)
:
(
<>
<
div
className=
"b_product_rate"
>
{
item
.
rate
!==
undefined
&&
item
.
rate
!==
null
&&
(
<
span
className=
"b_product_rate_value"
>
{
(
item
.
rate
/
100
).
toFixed
(
2
)
}
%
</
span
>
)
}
<
span
className=
"b_product_rate_label"
>
{
RATE_NAME
[
item
.
type
]
||
"年化收益率"
}
</
span
>
</
div
>
<
div
className=
"b_product_shu"
>
<
span
className=
"b_product_shu_value"
>
{
item
.
shenShuGuiZei
}
</
span
>
<
span
className=
"b_product_shu_label"
>
{
item
.
fengXian
}
|
{
item
.
qigouText
}
</
span
>
</
div
>
</>
)
}
<
Button
className=
"detail_btn_1"
onClick=
{
()
=>
jumpVirtualDetailHandle
(
item
)
}
></
Button
>
<
span
className=
"b_product_line"
></
span
>
</
div
>
))
}
</
div
>
{
!
curTabProductList
.
length
&&
curTab
===
2
&&
<
div
className=
"empty"
>
暂无持仓产品哦
</
div
>
}
</
div
>
);
};
export
default
ProductListModule
;
src/pages/components/ProductListModule/index.less
0 → 100644
View file @
94333785
@import "../../../res.less";
.bottom_products {
width: 700px;
height: auto;
min-height: 1017px;
background-color: #ffffff;
position: relative;
padding-top: 152px;
padding-bottom: 19px;
box-sizing: border-box;
border-radius: 24px;
margin-left: 24px;
// &::before {
// content: "";
// position: absolute;
// top: 800px;
// left: 15px;
// width: 685px;
// height: calc(100% - 800px - 19px);
// background-color: #fff;
// border-radius: 0 0 20px 20px;
// }
.tab1_bg {
width: 701px;
height: 1017px;
left: 0;
top: 0px;
position: absolute;
.sparkBg("ActualHome/tab1_bg.png");
}
.tab2_bg {
width: 701px;
height: 1017px;
left: 0;
top: 0px;
position: absolute;
.sparkBg("ActualHome/tab2_bg.png");
}
.tab1_btn {
width: 50%;
height: 80px;
position: absolute;
left: 0;
top: 0;
}
.tab2_btn {
width: 50%;
height: 80px;
position: absolute;
right: 0;
top: 0;
// background-color: rgba(0, 0, 0, 0.6);
}
.empty {
width: 653px;
left: 30px;
top: 252px;
position: absolute;
color: #000;
text-align: center;
}
.products_list {
width: 653px;
// height: 696px;
left: 30px;
// top: 152px;
position: relative;
.b_product_item {
width: 653px;
height: 173px;
position: relative;
&:not(:last-child) {
margin-bottom: 50px;
}
.b_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;
}
.b_product_rate {
width: 200px;
height: 63px;
left: 0px;
top: 57px;
position: absolute;
.b_product_rate_label {
width: 100%;
height: 22px;
left: 0px;
top: 46px;
position: absolute;
opacity: 0.6;
font-size: 20px;
line-height: 22px;
color: rgba(1, 1, 1, 1);
.lineClamp1();
}
.b_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();
}
}
.b_product_shu {
width: 280px;
height: 63px;
left: 222px;
top: 57px;
position: absolute;
.b_product_shu_label {
width: 100%;
height: 22px;
left: 1px;
top: 45px;
position: absolute;
opacity: 0.6;
font-size: 20px;
line-height: 22px;
color: rgba(1, 1, 1, 1);
.lineClamp1();
}
.b_product_shu_value {
width: 100%;
height: 32px;
left: 0px;
top: -2px;
position: absolute;
font-size: 28px;
line-height: 32px;
color: rgba(0, 0, 0, 1);
font-weight: bold;
.lineClamp1();
}
}
.detail_btn_1 {
width: 140px;
height: 49px;
left: 513px;
top: 65px;
position: absolute;
.sparkBg("ActualHome/detail_btn.png");
}
.b_product_line {
width: 652px;
height: 2px;
left: 1px;
top: 171px;
position: absolute;
opacity: 0.1;
.sparkBg("ActualHome/b_product_line.png");
}
}
}
}
src/pages/components/SignModule/index.less
View file @
94333785
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
width: 732px;
width: 732px;
height: 407px;
height: 407px;
.webpBg("ActualHome/sign_bg.png");
.webpBg("ActualHome/sign_bg.png");
margin: 0 auto;
margin: 0 auto
10px
;
}
}
.week-list-box {
.week-list-box {
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
position: relative;
position: relative;
width: 82px;
width: 82px;
height: 107px;
height: 107px;
.webpBg("ActualHome/sign_task.png")
.webpBg("ActualHome/sign_task.png")
;
}
}
.week-item-text {
.week-item-text {
...
@@ -46,7 +46,7 @@
...
@@ -46,7 +46,7 @@
position: absolute;
position: absolute;
top: -26px;
top: -26px;
left: -1px;
left: -1px;
.webpBg("ActualHome/sign_task_title.png")
.webpBg("ActualHome/sign_task_title.png")
;
}
}
}
}
...
@@ -56,5 +56,5 @@
...
@@ -56,5 +56,5 @@
position: absolute;
position: absolute;
left: 149px;
left: 149px;
top: 280px;
top: 280px;
.webpBg("ActualHome/sign_btn.png")
.webpBg("ActualHome/sign_btn.png")
;
}
}
src/store/index.js
View file @
94333785
...
@@ -17,7 +17,7 @@ const store = makeAutoObservable({
...
@@ -17,7 +17,7 @@ const store = makeAutoObservable({
myPrize
:
"myPrize"
,
myPrize
:
"myPrize"
,
// TODO 举例子 新宿台奖品页
// TODO 举例子 新宿台奖品页
index
:
PAGE_MAP
.
ACTUAL_HOME_PAGE
,
index
:
PAGE_MAP
.
ACTUAL_HOME_PAGE
,
}[
skinId
]
||
PAGE_MAP
.
PRIZ
E_PAGE
,
}[
skinId
]
||
PAGE_MAP
.
ACTUAL_HOM
E_PAGE
,
pageData
:
{},
pageData
:
{},
/** 场景切换 */
/** 场景切换 */
changePage
(
page
,
data
=
{})
{
changePage
(
page
,
data
=
{})
{
...
...
src/utils/constants.js
View file @
94333785
...
@@ -20,4 +20,6 @@ export const PAGE_MAP = {
...
@@ -20,4 +20,6 @@ export const PAGE_MAP = {
LOADING_PAGE
:
"loadingPage"
,
LOADING_PAGE
:
"loadingPage"
,
/** 奖品页 */
/** 奖品页 */
PRIZE_PAGE
:
"prizePage"
,
PRIZE_PAGE
:
"prizePage"
,
/** 产品详情 */
PRODUCT_DETAIL
:
"productDetail"
,
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment