From 254cc52585fcf18b465babb62f118f8be2841388 Mon Sep 17 00:00:00 2001 From: saplf Date: Wed, 4 Sep 2019 15:15:40 +0800 Subject: [PATCH] Community list --- src/global.less | 2 + src/locales/en-US.ts | 7 ++ src/locales/zh-CN.ts | 7 ++ src/pages/home/market/index.tsx | 118 +++++++++++++++++++++-- src/pages/home/market/model.ts | 154 ++++++++++++++++--------------- src/pages/home/market/service.ts | 29 +++--- src/pages/home/market/style.less | 150 +++++++++++++++++++++++++++++- src/types/common.ts | 29 ++++++ 8 files changed, 400 insertions(+), 96 deletions(-) diff --git a/src/global.less b/src/global.less index 17fc28f..f39d550 100644 --- a/src/global.less +++ b/src/global.less @@ -17,6 +17,8 @@ body { @purple-two: #7483f6; @blue-one: #21b4fc; @blue-two: #7483f6; +@orange-one: #f5b92e; +@orange-two: #eaa900; @header-height: 54px; diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index 38b9d5a..92286fc 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -70,6 +70,13 @@ export default { 'home.fund.type2': '社区奖励', 'home.fund.type3': '提币', + 'home.community.total': '累计社区奖励', + 'home.community.totalInvited': '成功邀请:{num}人', + 'home.community.totalAll': '社区总数:{num}人', + 'home.community.invite': '邀请新人加入我的社区', + 'home.community.title': '成功直推名单', + 'home.community.time': '注册时间:', + 'estate.tab1': '买卖记录', 'estate.tab2': '地块介绍', 'estate.title1': '买入信息', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index e05391b..e5c89a1 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -70,6 +70,13 @@ export default { 'home.fund.type2': '社区奖励', 'home.fund.type3': '提币', + 'home.community.total': '累计社区奖励', + 'home.community.totalInvited': '成功邀请:{num}人', + 'home.community.totalAll': '社区总数:{num}人', + 'home.community.invite': '邀请新人加入我的社区', + 'home.community.title': '成功直推名单', + 'home.community.time': '注册时间:', + 'estate.tab1': '买卖记录', 'estate.tab2': '地块介绍', 'estate.title1': '买入信息', diff --git a/src/pages/home/market/index.tsx b/src/pages/home/market/index.tsx index fc705cc..cd15b22 100644 --- a/src/pages/home/market/index.tsx +++ b/src/pages/home/market/index.tsx @@ -1,17 +1,117 @@ -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 FittedImage from 'react-fitted-image'; -import banner from '@/assets/m_banner.jpg'; +import { HomeCommunityModelState } from './model'; +import { Inviter } from '@/types/common'; +import Label from '@/components/Label'; +import List from '@/components/List'; +import { dispatch } from '@/utils/utils'; import styles from './style.less'; -const MarketPage: React.FC = () => { - return ( -
-
- +const CommunityPage: React.FC = ({ + dispatch, + refreshingList, + loadingList, + loadingFinished, + errorList, + data, + refreshingBasic, + errorBasic, + info, +}) => { + + useEffect(() => { + if (!data || errorList) { + dispatch({ type: 'homeCommunity/loadList', payload: true }); + } + if (!info || errorBasic) { + dispatch({ type: 'homeCommunity/loadBasic' }); + } + }, []); + + const onRefresh = () => { + if (refreshingBasic || refreshingList) return; + dispatch({ type: 'homeCommunity/loadList', payload: true }); + dispatch({ type: 'homeCommunity/loadBasic' }); + }; + + const renderBanner = ( +
+
+ {formatMessage({ id: 'home.community.total' })} + + +{info ? info.rewardAll : 0} USDT + +
+
+ + {formatMessage({ + id: 'home.community.totalInvited', + }, { + num: info ? info.followerNumber : 0, + })} + + + {formatMessage({ + id: 'home.community.totalAll', + }, { + num: info ? info.communeNumber : 0, + })} + +
+ +
+ {formatMessage({ id: 'home.community.invite' })} +
); -} -export default MarketPage; + const renderItem = (it: Inviter) => ( +
+
+ {it.avatar ? :
{(it.nickname && it.nickname[0]) || 'F'}
} +
+
+ {it.nickname} + {formatMessage({ id: 'home.community.time' })}{it.registryTime} +
+
+ ); + + return ( +
+ {renderBanner} + +
+ ); +}; + +export default connect( + ({ homeCommunity } : any) => ({ ...homeCommunity }), +)(CommunityPage); diff --git a/src/pages/home/market/model.ts b/src/pages/home/market/model.ts index eab35f1..4ceb9c8 100644 --- a/src/pages/home/market/model.ts +++ b/src/pages/home/market/model.ts @@ -1,104 +1,108 @@ import { Model, routerRedux } from 'dva'; import { message } from 'antd'; -import { EstateType, Estates } from '@/types/common'; -import { getEstateList, EstateList } from './service'; +import { Journal, CommunityBasic } from '@/types/common'; +import { getCommunityList, getCommunityBasic } from './service'; -export interface HomeMarketModelState { - refreshing: boolean; - loading: boolean; +export interface HomeCommunityModelState { + refreshingList: boolean; + loadingList: boolean; loadingFinished: boolean; - data: Estates; - num: number; - pageIndex: number; + errorList: boolean; + data: Journal[] | null; - tab: EstateType; + refreshingBasic: boolean; + errorBasic: boolean; + info: CommunityBasic | null; + + pageIndex: number; } -const MarketModel: Model = { - namespace: 'homeMarket', +const CommunityModel: Model = { + namespace: 'homeCommunity', state: { - refreshing: false, - loading: false, - enableLoad: true, + refreshingList: false, + loadingList: false, loadingFinished: false, - data: [], - num: 0, + errorList: false, + data: null, + + refreshingBasic: false, + errorBasic: false, + info: null, + pageIndex: 1, - pageSize: 10, - tab: EstateType.Hold, - } as HomeMarketModelState, + } as HomeCommunityModelState, effects: { - *refresh(_, { put, call, select }) { - const { - pageSize, - tab, - } = yield select((state: any) => state.homeEstate); - yield put({ type: 'onUpdateState', payload: { refreshing: true, loading: false } }); - try { - const { total, list }: EstateList = yield call(getEstateList, 1, pageSize, tab); - const { tab: newTab } = yield select((state: any) => state.homeEstate); - if (tab === newTab) { - yield put({ - type: 'onUpdateState', - payload: { - refreshing: false, - pageIndex: 2, - data: list, - num: total, - }, - }); - } - } catch (e) { - message.error(e.message); - yield put({ type: 'onUpdateState', payload: { refreshing: false, pageIndex: 1 } }); - } - }, - - *loadMore(_, { put, call, select }) { + *loadList({ payload: refresh }, { put, call, select }) { const { + refreshingList, + loadingList, pageIndex, - pageSize, - tab, data, - } = yield select((state: any) => state.homeEstate); - yield put({ type: 'onUpdateState', payload: { loading: true, refreshing: false } }); + } = yield select((state: any) => state.homeCommunity); + if (refreshingList || loadingList) return; + + yield put({ + type: 'onUpdateState', + refreshingList: refresh, + loadingList: !refresh, + errorList: false, + }); try { - const { total, list }: EstateList = yield call(getEstateList, pageIndex, pageSize, tab); - const { tab: newTab } = yield select((state: any) => state.homeEstate); - if (tab === newTab) { - yield put({ - type: 'onUpdateState', - payload: { - loading: false, - pageIndex: pageIndex + 1, - data: [...data, ...list], - num: total, - enableLoad: list.length === pageSize, - }, - }); - } + const pageSize = 10; + const page = refresh ? 1 : pageIndex + 1; + const list = yield call(getCommunityList, 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', payload: { loading: false } }); + yield put({ + type: 'onUpdateState', + refreshingList: false, + loadingList: false, + errorList: true, + }); } }, - *changeTab({ payload: tab }, { put }) { - yield put({ type: 'onUpdateState', payload: { tab, pageIndex: 1, data: [], num: 0 } }); - yield put({ type: 'refresh' }); - }, + *loadBasic(_, { put, call, select }) { + const { refreshingBasic } = yield select((state: any) => state.homeCommunity); + if (refreshingBasic) return; - *gotoDetail({ payload }, { put }) { - if (!payload) return; - yield put(routerRedux.push('/estate')); - yield put({ type: 'ext/onUpdateState', payload: { estateExt: payload } }); + yield put({ + type: 'onUpdateState', + refreshingBasic: true, + errorBasic: false, + }); + try { + const info = yield call(getCommunityBasic); + yield put({ + type: 'onUpdateState', + info, + refreshingBasic: false, + errorBasic: false, + }); + } catch (e) { + yield put({ + type: 'onUpdateState', + refreshingBasic: false, + errorBasic: true, + }); + } }, }, reducers: { - onUpdateState(state, { payload } : any) { + onUpdateState(state, payload) { return { ...state, ...payload, @@ -107,4 +111,4 @@ const MarketModel: Model = { }, }; -export default MarketModel; +export default CommunityModel; diff --git a/src/pages/home/market/service.ts b/src/pages/home/market/service.ts index e6b045e..dc73f33 100644 --- a/src/pages/home/market/service.ts +++ b/src/pages/home/market/service.ts @@ -1,21 +1,28 @@ import http from '@/utils/http'; -import { Estates, EstateType } from '@/types/common'; -import { calcEstate } from '@/utils/transform'; +import { Inviters, CommunityBasic } from '@/types/common'; -export interface EstateList { - total: number; - list: Estates; -} - -export async function getEstateList(pageIndex: number, pageSize: number, type: EstateType) { +export async function getCommunityBasic(): Promise { const { ok, data, msg, - } = await http.get('/estateorder/list', { type, pageIndex, pageSize }); + } = await http.get('/commune/basic'); + if (ok && data) { + return data; + } + throw Error(msg); +} + +export async function getCommunityList(pageIndex: number, pageSize: number): Promise { + const { + ok, + data, + msg, + } = await http.get('/commune/list', { + pageIndex, + pageSize, + }); if (ok && data) { - data.list.forEach(it => it.type = type); - data.list.forEach(calcEstate); return data; } throw Error(msg); diff --git a/src/pages/home/market/style.less b/src/pages/home/market/style.less index 81b2460..7177c11 100644 --- a/src/pages/home/market/style.less +++ b/src/pages/home/market/style.less @@ -1,8 +1,156 @@ +@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%; - height: 240px; + 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, @orange-one, @orange-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; + flex-direction: column; + align-items: stretch; + + :global { + .left { + flex-grow: 1; + display: flex; + align-items: center; + justify-content: space-between; + } + + .right { + flex-shrink: 0; + margin-top: 8px; + } + + .line { + margin: 4px 0; + font-weight: lighter; + } + + .app-btn { + user-select: none; + white-space: nowrap; + text-align: center; + background-color: @orange-one; + @btn-height: 32px; + height: @btn-height; + line-height: @btn-height; + padding: 0; + border-radius: 6px; + color: white; + font-size: 0.8rem; + box-shadow: 1px 1px 8px rgba(0,0,0,.2); + transition: background-color .18s; + + &:active { + background-color: lighten(@orange-one, 10%); + } + } + } + } +} + +.controller { + flex-shrink: 0; + margin: 10px; +} + +.list { + flex-grow: 1; +} + +.item { + height: 98%; + margin: 0 10px; + display: flex; + align-items: center; + border: 1px solid @bg-color; + padding: 8px 10px; + font-size: 0.9rem; + + :global { + + @size: 38px; + .avatar { + height: @size; + width: @size; + } + + .fake { + width: 100%; + height: 100%; + line-height: @size; + background-color: @bg-color; + font-size: 1.2rem; + border-radius: @size / 2; + text-align: center; + } + + .line { + margin: 0 8px; + display: flex; + flex-direction: column; + justify-content: space-around; + } + + .time { + font-weight: lighter; + font-size: 0.8rem; + } + } } diff --git a/src/types/common.ts b/src/types/common.ts index e806b8f..600b0e0 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -210,6 +210,35 @@ export interface Journal { timestamp: string; } +export interface CommunityBasic { + /** + * 累计奖励总额的数字 + */ + rewardAll: string; + + /** + * 直接邀请人数 + */ + followerNumber: string; + + /** + * 社区总人数 + */ + communeNumber: string; +} + +export interface Inviter { + id: string; + + avatar: string; + + nickname: string; + + registryTime: string; +} + +export type Inviters = Inviter[]; + export enum MarketEstateAvailable { No = 0, Yes = 1,