矿场列表

This commit is contained in:
saplf
2019-09-03 17:24:52 +08:00
parent 47d7819f2d
commit 8742eedac8
13 changed files with 492 additions and 263 deletions

View File

@@ -13,6 +13,9 @@ body {
@bg-primary-color: #ffded8; @bg-primary-color: #ffded8;
@hint-color: gray; @hint-color: gray;
@purple-one: #c17ffe;
@purple-two: #7483f6;
@header-height: 54px; @header-height: 54px;
.ant-btn { .ant-btn {

View File

@@ -14,9 +14,11 @@ export default {
'common.releaseToRefresh': 'Release to refresh', 'common.releaseToRefresh': 'Release to refresh',
'common.refreshing': 'Refreshing', 'common.refreshing': 'Refreshing',
'common.loading': 'Loading', 'common.loading': 'Loading',
'common.loadError': 'Load Failed',
'common.loadFinished': 'Finished', 'common.loadFinished': 'Finished',
'common.cancel': 'Cancel', 'common.cancel': 'Cancel',
'common.ok': 'Ok', 'common.ok': 'Ok',
'common.modify': 'Modify',
'check.login': 'Sign In', 'check.login': 'Sign In',
'check.register': 'Sign Up', 'check.register': 'Sign Up',
@@ -46,15 +48,17 @@ export default {
'home.home.statistic': 'Total', 'home.home.statistic': 'Total',
'home.home.header': '精选市场', 'home.home.header': '精选市场',
'home.estate.hold': 'Hold', 'home.mine.lastday': '昨日挖矿收益',
'home.estate.sold': 'Sold', 'home.mine.acc': '累计挖矿收益:',
'home.estate.holdTitle': 'Hold amount: {num}', 'home.mine.valid': '当前有效矿晶:',
'home.estate.soldTitle': 'Sold amount: {num}', 'home.mine.retrieve': '获取矿晶',
'home.estate.timeDue': 'Due {time}', 'home.mine.refresh': 'refresh',
'home.estate.timeSold': 'Sold {time}', 'home.mine.validTime': '获赠日期:',
'home.estate.cost': 'Cost', 'home.mine.invalidTime': '有效期至:',
'home.estate.profit': 'Profit', 'home.mine.status': 'status: ',
'home.estate.profit2': 'Profit: ', 'home.mine.status0': 'Pending',
'home.mine.status1': '正在挖矿',
'home.mine.status2': '已耗尽能源',
'estate.tab1': '买卖记录', 'estate.tab1': '买卖记录',
'estate.tab2': '地块介绍', 'estate.tab2': '地块介绍',

View File

@@ -14,9 +14,11 @@ export default {
'common.releaseToRefresh': '释放以刷新', 'common.releaseToRefresh': '释放以刷新',
'common.refreshing': '刷新中', 'common.refreshing': '刷新中',
'common.loading': '加载中', 'common.loading': '加载中',
'common.loadError': '加载失败',
'common.loadFinished': '已经到底了~', 'common.loadFinished': '已经到底了~',
'common.cancel': '取消', 'common.cancel': '取消',
'common.ok': '确定', 'common.ok': '确定',
'common.modify': '修改',
'check.login': '登录', 'check.login': '登录',
'check.register': '注册', 'check.register': '注册',
@@ -46,15 +48,17 @@ export default {
'home.home.statistic': '累计收益', 'home.home.statistic': '累计收益',
'home.home.header': '精选市场', 'home.home.header': '精选市场',
'home.estate.hold': '当前持有', 'home.mine.lastday': '昨日挖矿收益',
'home.estate.sold': '已经卖出', 'home.mine.acc': '累计挖矿收益:',
'home.estate.holdTitle': '当前持有地产数:{num}', 'home.mine.valid': '当前有效矿晶:',
'home.estate.soldTitle': '已经卖出地产数:{num}', 'home.mine.retrieve': '获取矿晶',
'home.estate.timeDue': '{time} 将到期', 'home.mine.refresh': '刷新',
'home.estate.timeSold': '{time} 已卖出', 'home.mine.validTime': '获赠日期:',
'home.estate.cost': '成本', 'home.mine.invalidTime': '有效期至:',
'home.estate.profit': '收益', 'home.mine.status': '状态:',
'home.estate.profit2': '预期收益:', 'home.mine.status0': '等待确认',
'home.mine.status1': '正在挖矿',
'home.mine.status2': '已耗尽能源',
'estate.tab1': '买卖记录', 'estate.tab1': '买卖记录',
'estate.tab2': '地块介绍', 'estate.tab2': '地块介绍',

View File

@@ -6,16 +6,20 @@
import React from 'react'; import React from 'react';
import { connect, DispatchProp } from 'dva'; import { connect, DispatchProp } from 'dva';
import { formatMessage } from 'umi-plugin-locale'; import { formatMessage } from 'umi-plugin-locale';
import { Button, Modal } from 'antd'; import { Button, Modal, Input } from 'antd';
import Header from '@/components/Header'; import Header from '@/components/Header';
import AccountItem from '@/components/AccountItem'; import AccountItem from '@/components/AccountItem';
import { UserModelState } from '@/models/user'; import { UserModelState } from '@/models/user';
import styles from './style.less'; import styles from './style.less';
import { AccountModelState } from './model';
const AccountPage: React.FC<DispatchProp & UserModelState> = ({ const AccountPage: React.FC<DispatchProp & UserModelState & AccountModelState> = ({
dispatch, dispatch,
user, user,
nameEditable,
nameInput,
nameSubmitting,
}) => { }) => {
const onLogout = () => { const onLogout = () => {
@@ -28,6 +32,25 @@ const AccountPage: React.FC<DispatchProp & UserModelState> = ({
}); });
}; };
const editNameModal = (
<Modal
title={formatMessage({ id: 'common.modify' })}
visible={nameEditable}
onCancel={() => dispatch({ type: 'account/onUpdateState', nameEditable: false })}
onOk={() => dispatch({ type: 'account/changeName' })}
okText={formatMessage({ id: 'common.ok' })}
cancelText={formatMessage({ id: 'common.cancel' })}
confirmLoading={nameSubmitting}
>
<Input
size="large"
placeholder={formatMessage({ id: 'account.nickname' })}
value={nameInput}
onChange={e => dispatch({ type: 'account/onUpdateState', nameInput: e.target.value })}
/>
</Modal>
);
return ( return (
<div className={styles.container}> <div className={styles.container}>
<Header <Header
@@ -40,6 +63,7 @@ const AccountPage: React.FC<DispatchProp & UserModelState> = ({
title="account.nickname" title="account.nickname"
message={user.nickname} message={user.nickname}
showGo={false} showGo={false}
onClick={() => dispatch({ type: 'account/onUpdateState', nameEditable: true })}
/> />
<AccountItem <AccountItem
className="group" className="group"
@@ -71,10 +95,11 @@ const AccountPage: React.FC<DispatchProp & UserModelState> = ({
{formatMessage({ id: 'account.logout' })} {formatMessage({ id: 'account.logout' })}
</Button> </Button>
</div>} </div>}
{editNameModal}
</div> </div>
); );
}; };
export default connect( export default connect(
({ user }: any) => ({ ...user }), ({ user, account }: any) => ({ ...user, ...account }),
)(AccountPage); )(AccountPage);

View File

@@ -0,0 +1,50 @@
import { Model } from 'dva';
import { changeName } from './service';
import { message } from 'antd';
export interface AccountModelState {
nameEditable: boolean;
nameInput: string;
nameSubmitting: boolean;
}
const model: Model = {
namespace: 'account',
state: {
nameEditable: false,
nameInput: '',
nameSubmitting: false,
} as AccountModelState,
effects: {
*changeName(_, { put, all, call, select }) {
const { nameInput } = yield select((state: any) => state.account);
if (!nameInput) return;
yield put({ type: 'onUpdateState', nameSubmitting: true });
try {
yield call(changeName, nameInput);
yield all([
put({ type: 'onUpdateState', nameInput: '', nameEditable: false }),
put({ type: 'user/updateUser', payload: { nickname: nameInput } }),
]);
} catch (e) {
message.error(e.message);
} finally {
yield put({ type: 'onUpdateState', nameSubmitting: false });
}
},
},
reducers: {
onUpdateState(state, payload) {
return {
...state,
...payload,
};
},
},
};
export default model;

View File

@@ -0,0 +1,9 @@
import http from '@/utils/http';
export async function changeName(nickname: string) {
const { ok, msg } = await http.post('/user/chnickname', { nickname });
if (ok) {
return true;
}
throw Error(msg);
}

View File

@@ -1,103 +1,103 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { Radio } from 'antd';
import FittedImage from 'react-fitted-image';
import { connect, DispatchProp } from 'dva'; import { connect, DispatchProp } from 'dva';
import { Spin, Icon } from 'antd';
import { formatMessage } from 'umi-plugin-locale'; import { formatMessage } from 'umi-plugin-locale';
import List from '@/components/List'; import { HomeMineModelState } from './model';
import Label from '@/components/Label'; import { MineStatus, Mine } from '@/types/common';
import { HomeEstateModelState } from './model';
import { EstateType, Estate } from '@/types/common';
import { dispatch } from '@/utils/utils'; import { dispatch } from '@/utils/utils';
import styles from './style.less'; import styles from './style.less';
const RadioGroup = Radio.Group; const MinePage: React.FC<HomeMineModelState & DispatchProp> = ({
const RadioButton = Radio.Button;
const renderItem = (data: Estate) => {
const holdTab = data.type === EstateType.Hold;
return (
<div
className={styles.item}
onClick={() => dispatch({ type: 'homeEstate/gotoDetail', payload: data })}
>
<div className="avatar">
<FittedImage src={data.image || ''} fit="cover" />
</div>
<div className="content">
<span className="name">{data.name}</span>
<span className="desc">
{
holdTab ?
formatMessage({ id: 'home.estate.timeDue' }, { time: data.lockTime }) :
formatMessage({ id: 'home.estate.timeSold' }, { time: data.outTime })
}
</span>
</div>
<div className="postfix">
<span className={`cost-msg ${holdTab ? 'primary' : ''}`}>
{formatMessage({ id: 'home.estate.cost' })} <span>{data.inPrice}</span> LOG
</span>
{!holdTab && <span className="sold-msg">
{formatMessage({ id: 'home.estate.profit' })} {data.profitPrice} LOG
</span>}
{holdTab && <span className="hold-msg">
{formatMessage({ id: 'home.estate.profit2' })}{data.profitShow}
</span>}
</div>
</div>
);
};
const EstatePage: React.FC<HomeEstateModelState & DispatchProp> = ({
dispatch, dispatch,
loading, refreshingList,
refreshing, errorList,
tab,
data, data,
num, refreshingBasic,
errorBasic,
info,
}) => { }) => {
useEffect(() => { useEffect(() => {
if (!data.length) { if (!data || errorList) {
dispatch({ type: 'homeEstate/refresh' }); dispatch({ type: 'homeMine/loadList' });
}
if (!info || errorBasic) {
dispatch({ type: 'homeMine/loadBasic' });
} }
}, []); }, []);
return ( const onRefresh = () => {
<div className={styles.container}> if (refreshingBasic || refreshingList) return;
<div className={styles.header}> dispatch({ type: 'homeMine/loadList', payload: true });
<RadioGroup dispatch({ type: 'homeMine/loadBasic' });
buttonStyle="solid" };
value={tab}
onChange={e => dispatch({ type: 'homeEstate/changeTab', payload: e.target.value })} const renderBanner = (
> <div className={styles.banner}>
<RadioButton value={EstateType.Hold}>{formatMessage({ id: 'home.estate.hold' })}</RadioButton> <div className="bg" />
<RadioButton value={EstateType.Sold}>{formatMessage({ id: 'home.estate.sold' })}</RadioButton> <span className="title">{formatMessage({ id: 'home.mine.lastday' })}</span>
</RadioGroup> <span className="content">
<span className="large">+{info ? info.revenueLastday : 0}</span>
VIC
</span>
<div className={styles.card}>
<div className="left">
<span className="line">
<span className="title2">{formatMessage({ id: 'home.mine.acc' })}</span>
<span className="value">{info ? info.revenueAll : 0} VIC</span>
</span>
<span className="line">
<span className="title2">{formatMessage({ id: 'home.mine.valid' })}</span>
<span className="value">{info ? info.stoneAll : 0} KG</span>
</span>
</div> </div>
<Label <div className="right app-btn">
name={formatMessage({ {formatMessage({ id: 'home.mine.retrieve' })}
id: tab === EstateType.Hold ? 'home.estate.holdTitle' : 'home.estate.soldTitle', </div>
}, { num })} </div>
className={styles.label} </div>
/> );
<List const renderItem = (it: Mine) => (
className={styles.list} <div className={styles.item} key={it.id}>
data={data} <div className="line">
renderItem={renderItem} <div>{formatMessage({ id: 'home.mine.validTime' })}{it.validTime}</div>
refreshing={refreshing} <div className="amount">+{it.amount} KG</div>
onRefresh={() => dispatch({ type: 'homeEstate/refresh' })} </div>
loading={loading} <div className="line">
onLoadMore={() => dispatch({ type: 'homeEstate/loadMore' })} <div>
itemKey={data => data.id} {formatMessage({ id: 'home.mine.status' })}
itemSize={80} {formatMessage({ id: `home.mine.status${it.status}` })}
/> </div>
<div className="small">{formatMessage({ id: 'home.mine.invalidTime' })}{it.invalidTime}</div>
</div>
</div>
);
return (
<div className={styles.container}>
{renderBanner}
<div className={styles.controller}>
<div className="content" onClick={onRefresh}>
<Icon type="sync" spin={refreshingBasic || refreshingList} />
<span className="desc">{formatMessage({ id: 'home.mine.refresh' })}</span>
</div>
</div>
<Spin className={styles.list} spinning={refreshingList}>
{!data ? (
<div className={styles.message}>
{formatMessage({ id: errorList ? 'common.loadError' : 'common.loading' })}
</div>
) : data.map(renderItem)}
</Spin>
</div> </div>
); );
}; };
export default connect( export default connect(
({ homeEstate } : any) => ({ ...homeEstate }), ({ homeMine } : any) => ({ ...homeMine }),
)(EstatePage); )(MinePage);

View File

@@ -1,104 +1,88 @@
import { Model, routerRedux } from 'dva'; import { Model, routerRedux } from 'dva';
import { message } from 'antd'; import { message } from 'antd';
import { EstateType, Estates } from '@/types/common'; import { Mines, MineBasic } from '@/types/common';
import { getEstateList, EstateList } from './service'; import { getMineList, getMineBasic } from './service';
export interface HomeEstateModelState { export interface HomeMineModelState {
refreshing: boolean; refreshingList: boolean;
loading: boolean; errorList: boolean;
loadingFinished: boolean; data: Mines | null;
data: Estates;
num: number;
pageIndex: number;
tab: EstateType; refreshingBasic: boolean;
errorBasic: boolean;
info: MineBasic | null;
} }
const EstateModel: Model = { const MineModel: Model = {
namespace: 'homeEstate', namespace: 'homeMine',
state: { state: {
refreshing: false, refreshingList: false,
loading: false, errorList: false,
enableLoad: true, data: null,
loadingFinished: false,
data: [], refreshingBasic: false,
num: 0, errorBasic: false,
pageIndex: 1, info: null,
pageSize: 10, } as HomeMineModelState,
tab: EstateType.Hold,
} as HomeEstateModelState,
effects: { effects: {
*refresh(_, { put, call, select }) { *loadList({ payload: refresh }, { put, call, select }) {
const { const { refreshingList } = yield select((state: any) => state.homeMine);
pageSize, if (refreshingList) return;
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({ yield put({
type: 'onUpdateState', type: 'onUpdateState',
payload: { refreshingList: true,
refreshing: false, errorList: false,
pageIndex: 2,
data: list,
num: total,
},
}); });
} try {
} catch (e) { const data = yield call(getMineList, refresh);
message.error(e.message); yield put({
yield put({ type: 'onUpdateState', payload: { refreshing: false, pageIndex: 1 } }); type: 'onUpdateState',
}
},
*loadMore(_, { put, call, select }) {
const {
pageIndex,
pageSize,
tab,
data, data,
} = yield select((state: any) => state.homeEstate); refreshingList: false,
yield put({ type: 'onUpdateState', payload: { loading: true, refreshing: false } }); errorList: false,
try { });
const { total, list }: EstateList = yield call(getEstateList, pageIndex, pageSize, tab); } catch (e) {
const { tab: newTab } = yield select((state: any) => state.homeEstate);
if (tab === newTab) {
yield put({ yield put({
type: 'onUpdateState', type: 'onUpdateState',
payload: { refreshingList: false,
loading: false, errorList: true,
pageIndex: pageIndex + 1, data: null,
data: [...data, ...list],
num: total,
enableLoad: list.length === pageSize,
},
}); });
} }
},
*loadBasic(_, { put, call, select }) {
const { refreshingBasic } = yield select((state: any) => state.homeMine);
if (refreshingBasic) return;
yield put({
type: 'onUpdateState',
refreshingBasic: true,
errorBasic: false,
});
try {
const info = yield call(getMineBasic);
yield put({
type: 'onUpdateState',
info,
refreshingBasic: false,
errorBasic: false,
});
} catch (e) { } catch (e) {
message.error(e.message); yield put({
yield put({ type: 'onUpdateState', payload: { loading: false } }); type: 'onUpdateState',
refreshingBasic: false,
errorBasic: true,
});
} }
}, },
*changeTab({ payload: tab }, { put }) {
yield put({ type: 'onUpdateState', payload: { tab, pageIndex: 1, data: [], num: 0 } });
yield put({ type: 'refresh' });
},
*gotoDetail({ payload }, { put }) {
if (!payload) return;
yield put(routerRedux.push('/estate'));
yield put({ type: 'ext/onUpdateState', payload: { estateExt: payload } });
},
}, },
reducers: { reducers: {
onUpdateState(state, { payload } : any) { onUpdateState(state, payload) {
return { return {
...state, ...state,
...payload, ...payload,
@@ -107,4 +91,4 @@ const EstateModel: Model = {
}, },
}; };
export default EstateModel; export default MineModel;

View File

@@ -1,21 +1,34 @@
import http from '@/utils/http'; import http from '@/utils/http';
import { Estates, EstateType } from '@/types/common'; import { Mines, MineBasic } from '@/types/common';
import { calcEstate } from '@/utils/transform'; import { loadMineList, storeMineList } from '@/utils/storage';
export interface EstateList { export async function getMineBasic(): Promise<MineBasic> {
total: number;
list: Estates;
}
export async function getEstateList(pageIndex: number, pageSize: number, type: EstateType) {
const { const {
ok, ok,
data, data,
msg, msg,
} = await http.get<EstateList>('/estateorder/list', { type, pageIndex, pageSize }); } = await http.get<MineBasic>('/mine/basic');
if (ok && data) { if (ok && data) {
data.list.forEach(it => it.type = type); return data;
data.list.forEach(calcEstate); }
throw Error(msg);
}
export async function getMineList(refresh = false): Promise<Mines> {
if (!refresh) {
const dataCached = loadMineList();
if (dataCached && dataCached.length) {
return dataCached;
}
}
const {
ok,
data,
msg,
} = await http.get<Mines>('/mine/list');
if (ok && data) {
storeMineList(data);
return data; return data;
} }
throw Error(msg); throw Error(msg);

View File

@@ -7,90 +7,157 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
}
.header {
height: @header-height;
line-height: @header-height;
text-align: center;
}
.label {
margin: 0;
padding: 10px;
background-color: @bg-color;
}
.list {
flex-grow: 1;
}
.item {
height: 100%;
display: flex;
align-items: stretch;
padding: 0 10px;
transition: background-color .2s;
&:active {
background-color: @bg-color;
}
:global { :global {
.avatar { .ant-spin-nested-loading {
flex-shrink: 0; flex-grow: 1;
align-self: center;
@size: 56px;
width: @size;
height: @size;
overflow: hidden; overflow: hidden;
border-radius: 4px; }
.ant-spin-container {
height: 100%;
overflow: auto;
}
}
}
.message {
text-align: center;
margin-top: 20px;
}
.banner {
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, @purple-one, @purple-two);
}
.title, .content {
color: white;
font-weight: lighter;
}
.title {
margin-top: 40px;
} }
.content { .content {
margin: 10px 0 24px;
}
.content .large {
font-size: 1.6rem;
margin-right: 6px;
font-weight: normal;
}
}
.card {
align-self: stretch;
background-color: white;
padding: 20px;
margin: 0 10px; margin: 0 10px;
flex: 1; box-shadow: 1px 1px 8px rgba(0,0,0,.1);
display: flex;
align-items: center;
:global {
.left {
flex-grow: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center;
.desc {
font-weight: lighter;
font-size: 0.8rem;
margin-top: 6px;
}
} }
.postfix { .right {
flex-shrink: 0; flex-shrink: 0;
display: flex; margin-left: 8px;
flex-direction: column; }
justify-content: center;
align-items: flex-end; .line {
font-size: 0.8rem; margin: 4px 0;
}
.title2 {
font-weight: lighter; font-weight: lighter;
.cost-msg {
margin-bottom: 6px;
&.primary {
color: @primary-color;
} }
> span { .app-btn {
font-size: 1.2rem; user-select: none;
} white-space: nowrap;
} background-color: @purple-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;
.hold-msg { &:active {
background-color: @bg-primary-color; background-color: lighten(@purple-one, 10%);
color: @primary-color;
} }
.sold-msg {
color: @primary-color;
} }
} }
} }
} }
.controller {
background-color: @bg-color;
margin: 10px;
text-align: right;
:global {
.desc {
display: inline-block;
font-weight: lighter;
font-size: 0.8rem;
margin-left: 4px;
}
.content {
padding: 4px 10px;
}
}
}
.item {
margin: 4px 10px;
display: flex;
flex-direction: column;
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 {
color: @purple-one;
font-size: 1rem;
}
.small {
font-weight: lighter;
font-size: 0.8rem;
}
}
}

View File

@@ -92,6 +92,55 @@ export interface Estate {
export type Estates = Estate[]; export type Estates = Estate[];
export interface MineBasic {
/**
* 昨日收益
*/
revenueLastday: string;
/**
* 总收益
*/
revenueAll: string;
/**
* 当前有效矿晶
*/
stoneAll: string;
}
export enum MineStatus {
Pending = 0, // 等待确认
Working = 1, // 正在挖矿
RunOut = 2, // 耗尽能源
}
/**
* 矿
*/
export interface Mine {
id: string;
amount: string;
/**
* 获赠日期
*/
validTime: string;
/**
* 到期日期
*/
invalidTime: string;
/**
* 矿晶状态
*/
status: MineStatus;
}
export type Mines = Mine[];
export enum MarketEstateAvailable { export enum MarketEstateAvailable {
No = 0, No = 0,
Yes = 1, Yes = 1,

View File

@@ -15,8 +15,8 @@ const successLabel = 'color:white;background-color:green;padding: 1px 2px';
const failureLabel = 'color:white;background-color:red;padding: 1px 2px'; const failureLabel = 'color:white;background-color:red;padding: 1px 2px';
const originLabel = 'color:unset;background-color:unset;padding:unset'; const originLabel = 'color:unset;background-color:unset;padding:unset';
const baseURL = 'https://server.fiv.tacever.org/v1'; // const baseURL = 'https://server.fiv.tacever.org/v1';
// const baseURL = '//yapi.faronear.org/mock/20/v1'; const baseURL = '//yapi.faronear.org/mock/20/v1';
const instance = axios.create({ const instance = axios.create({
baseURL, baseURL,
}); });

View File

@@ -1,7 +1,9 @@
const userKey = 'user-key'; const userKey = 'user-key';
const areaCodeKey = 'area-code-key'; const areaCodeKey = 'area-code-key';
const mineListKey = 'mine-list-key';
// user info from now on
function storeUser(user: any = undefined) { function storeUser(user: any = undefined) {
if (user === undefined) { if (user === undefined) {
localStorage.removeItem(userKey); localStorage.removeItem(userKey);
@@ -20,6 +22,8 @@ function loadUser() {
const clearUser = storeUser; const clearUser = storeUser;
// area code info from now on
function storeAreaCode(codes: any) { function storeAreaCode(codes: any) {
localStorage.setItem(areaCodeKey, JSON.stringify(codes)); localStorage.setItem(areaCodeKey, JSON.stringify(codes));
} }
@@ -32,6 +36,20 @@ function loadAreaCode() {
} }
} }
// mine list info from now on
function storeMineList(list: any) {
localStorage.setItem(mineListKey, JSON.stringify(list));
}
function loadMineList() {
try {
return JSON.parse(localStorage.getItem(mineListKey) || 'null');
} catch (e) {
return null;
}
}
export { export {
storeUser, storeUser,
loadUser, loadUser,
@@ -39,4 +57,7 @@ export {
storeAreaCode, storeAreaCode,
loadAreaCode, loadAreaCode,
storeMineList,
loadMineList,
} }