Fund list

This commit is contained in:
saplf
2019-09-04 14:16:13 +08:00
parent 8e62f9bab9
commit ff5a431f43
11 changed files with 493 additions and 15 deletions

View File

@@ -1,5 +1,4 @@
import { Model, routerRedux } from 'dva';
import { message } from 'antd';
import { Model } from 'dva';
import { Mines, MineBasic } from '@/types/common';
import { getMineList, getMineBasic } from './service';

View File

@@ -1,7 +1,114 @@
import React from 'react';
import React, { useEffect } from 'react';
import { connect, DispatchProp, routerRedux } from 'dva';
import { Spin, Icon } from 'antd';
import { formatMessage } from 'umi-plugin-locale';
import { HomeFundModelState } from './model';
import { Journal, JournalOp } from '@/types/common';
import Label from '@/components/Label';
import List from '@/components/List';
import { dispatch } from '@/utils/utils';
const FundPage: React.FC = () => {
return <div>Fund</div>
}
import styles from './style.less';
export default FundPage;
const FundPage: React.FC<HomeFundModelState & DispatchProp> = ({
dispatch,
refreshingList,
loadingList,
loadingFinished,
errorList,
data,
refreshingBasic,
errorBasic,
info,
}) => {
useEffect(() => {
if (!data || errorList) {
dispatch({ type: 'homeFund/loadList', payload: true });
}
if (!info || errorBasic) {
dispatch({ type: 'homeFund/loadBasic' });
}
}, []);
const onRefresh = () => {
if (refreshingBasic || refreshingList) return;
dispatch({ type: 'homeFund/loadList', payload: true });
dispatch({ type: 'homeFund/loadBasic' });
};
const renderBanner = (
<div className={styles.banner}>
<div className="bg" />
<span className="title">{formatMessage({ id: 'home.fund.total' })}</span>
<span className="content">
<span className="large">{info ? info.balanceSum : 0}</span>
VIC
</span>
<div className={styles.card}>
<div className="left">
<span className="line">
<span className="title2">{formatMessage({ id: 'home.fund.totalVIC' })}</span>
<span className="value">+{info ? info.balanceVIC : 0} VIC</span>
</span>
<span className="line">
<span className="title2">{formatMessage({ id: 'home.fund.totalUSDT' })}</span>
<span className="value">+{info ? info.balanceUSDT : 0} USDT</span>
</span>
</div>
<div
className="right app-btn"
>
{formatMessage({ id: 'home.fund.draw' })}
</div>
</div>
</div>
);
const renderItem = (it: Journal) => (
<div className={styles.item} key={it.id}>
<div className="line">
<div>{formatMessage({ id: `home.fund.type${it.type}` })}</div>
<div className={`amount ${it.op === JournalOp.Income ? 'active' : ''}`}>
{it.op === JournalOp.Income ? '+' : '-'}{it.amount}&nbsp;
{it.coinType.toUpperCase()}
</div>
</div>
<div className="line">
<div className="detail">
{it.detail}
</div>
<div className="small">{it.timestamp}</div>
</div>
</div>
);
return (
<div className={styles.container}>
{renderBanner}
<Label
className={styles.controller}
name={formatMessage({ id: 'home.fund.journal' })}
/>
<List
className={styles.list}
data={data || []}
renderItem={renderItem}
refreshing={refreshingList}
onRefresh={onRefresh}
loading={loadingList}
enableLoading={!loadingFinished}
onLoadMore={() => dispatch({ type: 'homeFund/loadList' })}
itemKey={data => data.id}
itemSize={80}
/>
</div>
);
};
export default connect(
({ homeFund } : any) => ({ ...homeFund }),
)(FundPage);

View File

@@ -0,0 +1,114 @@
import { Model, routerRedux } from 'dva';
import { message } from 'antd';
import { Journal, FundBasic } from '@/types/common';
import { getFundList, getFundBasic } from './service';
export interface HomeFundModelState {
refreshingList: boolean;
loadingList: boolean;
loadingFinished: boolean;
errorList: boolean;
data: Journal[] | null;
refreshingBasic: boolean;
errorBasic: boolean;
info: FundBasic | null;
pageIndex: number;
}
const FundModel: Model = {
namespace: 'homeFund',
state: {
refreshingList: false,
loadingList: false,
loadingFinished: false,
errorList: false,
data: null,
refreshingBasic: false,
errorBasic: false,
info: null,
pageIndex: 1,
} as HomeFundModelState,
effects: {
*loadList({ payload: refresh }, { put, call, select }) {
const {
refreshingList,
loadingList,
pageIndex,
data,
} = yield select((state: any) => state.homeFund);
if (refreshingList || loadingList) return;
yield put({
type: 'onUpdateState',
refreshingList: refresh,
loadingList: !refresh,
errorList: false,
});
try {
const pageSize = 10;
const page = refresh ? 1 : pageIndex + 1;
const list = yield call(getFundList, page, pageSize);
yield put({
type: 'onUpdateState',
data: refresh ? list : [...data, ...list],
refreshingList: false,
loadingList: false,
pageIndex: page,
errorList: false,
loadingFinished: list.length !== pageSize,
});
} catch (e) {
message.error(e.message);
yield put({
type: 'onUpdateState',
refreshingList: false,
loadingList: false,
errorList: true,
});
}
},
*loadBasic(_, { put, call, select }) {
const { refreshingBasic } = yield select((state: any) => state.homeFund);
if (refreshingBasic) return;
yield put({
type: 'onUpdateState',
refreshingBasic: true,
errorBasic: false,
});
try {
const info = yield call(getFundBasic);
yield put({
type: 'onUpdateState',
info,
refreshingBasic: false,
errorBasic: false,
});
} catch (e) {
yield put({
type: 'onUpdateState',
refreshingBasic: false,
errorBasic: true,
});
}
},
},
reducers: {
onUpdateState(state, payload) {
return {
...state,
...payload,
};
},
},
};
export default FundModel;

View File

@@ -0,0 +1,29 @@
import http from '@/utils/http';
import { Journal, FundBasic } from '@/types/common';
export async function getFundBasic(): Promise<FundBasic> {
const {
ok,
data,
msg,
} = await http.get<FundBasic>('/fund/detail');
if (ok && data) {
return data;
}
throw Error(msg);
}
export async function getFundList(pageIndex: number, pageSize: number): Promise<Journal[]> {
const {
ok,
data,
msg,
} = await http.get<Journal[]>('/fund/journals', {
pageIndex,
pageSize,
});
if (ok && data) {
return data;
}
throw Error(msg);
}

View File

@@ -0,0 +1,154 @@
@import '../../../global.less';
.container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
}
.message {
text-align: center;
margin-top: 20px;
}
.banner {
flex-shrink: 0;
position: relative;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
:global {
.bg {
z-index: -1;
position: absolute;
left: 0;
right: 0;
width: 100%;
height: 90%;
background: linear-gradient(to bottom, @blue-one, @blue-two);
}
.title, .content {
color: white;
font-weight: lighter;
}
.title {
margin-top: 40px;
}
.content {
margin: 10px 0 24px;
}
.content .large {
font-size: 1.6rem;
margin-right: 6px;
font-weight: normal;
}
}
.card {
flex-shrink: 0;
align-self: stretch;
background-color: white;
padding: 20px;
margin: 0 10px;
box-shadow: 1px 1px 8px rgba(0,0,0,.1);
display: flex;
align-items: center;
:global {
.left {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.right {
flex-shrink: 0;
margin-left: 8px;
}
.line {
margin: 4px 0;
}
.title2 {
font-weight: lighter;
}
.app-btn {
user-select: none;
white-space: nowrap;
background-color: @blue-one;
@btn-height: 28px;
height: @btn-height;
line-height: @btn-height;
padding: 0 24px;
border-radius: @btn-height / 2;
color: white;
font-size: 0.8rem;
box-shadow: 1px 1px 8px rgba(0,0,0,.2);
transition: background-color .18s;
&:active {
background-color: lighten(@blue-one, 10%);
}
}
}
}
}
.controller {
flex-shrink: 0;
margin: 10px;
}
.list {
flex-grow: 1;
}
.item {
height: 98%;
margin: 0 10px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
border: 1px solid @bg-color;
padding: 8px 10px;
font-size: 0.9rem;
line-height: 1.8;
:global {
.line {
display: flex;
justify-content: space-between;
align-items: center;
}
.amount {
font-size: 1rem;
}
.amount.active {
color: @blue-one;
}
.small {
flex-shrink: 0;
font-weight: lighter;
font-size: 0.8rem;
}
.detail {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}

View File

@@ -30,18 +30,18 @@ const tabItems: TabItemModels = [
icon: estateIcon,
iconSelected: estateIconS,
},
{
key: '/home/market',
name: 'home.tabMarket',
icon: marketIcon,
iconSelected: marketIconS,
},
{
key: '/home/fund',
name: 'home.tabFund',
icon: fundIcon,
iconSelected: fundIconS,
},
{
key: '/home/market',
name: 'home.tabMarket',
icon: marketIcon,
iconSelected: marketIconS,
},
{
key: '/home/profile',
name: 'home.tabProfile',