@@ -20,6 +20,8 @@ async function saveSafeArea(dispatch) { | |||
export function logout() { | |||
return async (dispatch) => { | |||
storage.clear(); | |||
Taro.reLaunch({ url: '/pages/login/index' }); | |||
dispatch({ | |||
type: 'app/logout', | |||
}); | |||
@@ -3,6 +3,7 @@ export default { | |||
'pages/login/index', | |||
'pages/project/index', | |||
'pages/recycle/index', | |||
'pages/usercenter/index', | |||
], | |||
window: { | |||
backgroundTextStyle: 'light', | |||
@@ -11,7 +11,7 @@ export default function Avator(props) { | |||
return getFileUrl(propsSrc || accountAvator); | |||
}, [propsSrc, accountAvator]) | |||
return ( | |||
<View className={[styles.avator, className]}> | |||
<View className={[styles.avator, className]} {...restProps}> | |||
<Image src={src} /> | |||
</View> | |||
) |
@@ -5,7 +5,7 @@ import { AtNavBar } from 'taro-ui'; | |||
import styles from './page.module.scss'; | |||
export default function Page(props) { | |||
const { wrapperClassName, className, children, headerColor, title = '', leftText } = props; | |||
const { wrapperClassName, className, children, headerColor, title = '', leftText, onClickLeftIcon } = props; | |||
const statusBarHeight = useSelector(state => state.app.statusBarHeight); | |||
return ( | |||
<View className={[styles.page, wrapperClassName]}> | |||
@@ -15,11 +15,12 @@ export default function Page(props) { | |||
<View className={styles.headerCenter}>{title}</View> | |||
<View className={styles.headerRight} /> | |||
</View> */} | |||
<View className={styles.header} style={{ backgroundColor: headerColor }} onClickLeftIcon={() => {}}> | |||
<View className={styles.header} style={{ backgroundColor: headerColor }}> | |||
<AtNavBar | |||
className={styles.navBar} | |||
leftIconType={leftText ? "chevron-left" : undefined} | |||
leftText={leftText} | |||
onClickLeftIcon={onClickLeftIcon} | |||
> | |||
<View>{title}</View> | |||
</AtNavBar> | |||
@@ -24,5 +24,8 @@ | |||
:global(.at-nav-bar__text) { | |||
padding-left: 0; | |||
} | |||
:global(.at-nav-bar__title) { | |||
flex: 4; | |||
} | |||
} | |||
} |
@@ -10,13 +10,6 @@ import Page from '@root/components/Page'; | |||
export default function ProjectListView() { | |||
const [projectList, setProjectList] = useState([]); | |||
useLayoutEffect(() => { | |||
Taro.setNavigationBarColor({ | |||
backgroundColor: '#f6f6f6', // 窗口的背景色为白色 | |||
frontColor: '#ffffff', | |||
}); | |||
}, []); | |||
const fetchList = useCallback(async () => { | |||
const dataList = await fetchProjectList(); | |||
setProjectList(dataList); | |||
@@ -30,7 +23,7 @@ export default function ProjectListView() { | |||
<Page wrapperClassName={styles.page}> | |||
<ScrollView className={styles.project} scrollY> | |||
<View className={styles.wrapPadding}> | |||
<Avator className={styles.avator} /> | |||
<Avator className={styles.avator} onClick={() => Taro.navigateTo({ url: '/pages/usercenter/index' })} /> | |||
</View> | |||
<Welcome className={[styles.wrapPadding, styles.mt10]} /> | |||
<View className={[styles.listTitle, styles.wrapPadding]}> | |||
@@ -0,0 +1 @@ | |||
export { default } from './usercenter'; |
@@ -0,0 +1,80 @@ | |||
import Page from '@root/components/Page'; | |||
import { useRequest } from '@root/utils/hooks'; | |||
import getData from '@root/utils/request'; | |||
import { get } from '@root/utils/storage'; | |||
import Taro from '@tarojs/taro'; | |||
import { firstCharToLowerCase } from '@root/utils/tool'; | |||
import React, { useCallback } from 'react'; | |||
import styles from './usercenter.module.scss'; | |||
import { AtList, AtListItem } from 'taro-ui'; | |||
import { ScrollView, View } from '@tarojs/components'; | |||
import Avator from '@root/components/Avator'; | |||
import { useDispatch } from 'react-redux'; | |||
import { logout } from '@root/actions/app'; | |||
export default function UserCenter() { | |||
const dispatch = useDispatch(); | |||
const { data } = useRequest(async () => { | |||
const accountId = get('accountId'); | |||
const res = await getData('user/queryUserByUserId', { id: accountId }); | |||
return firstCharToLowerCase(res.data); | |||
}); | |||
return ( | |||
<Page | |||
leftText="我的项目" | |||
wrapperClassName={styles.page} | |||
onClickLeftIcon={() => Taro.navigateBack()} | |||
headerColor="#f0f0f0" | |||
> | |||
<View className={styles.banner}> | |||
<View className={styles.name}>{data?.cnName}</View> | |||
<Avator className={styles.avator} /> | |||
<View className={styles.gradient} /> | |||
</View> | |||
<ScrollView className={styles.scroll} scrollY> | |||
<AtList className={styles.itemList}> | |||
<AtListItem | |||
title="账号信息" | |||
className={styles.subtitle} | |||
/> | |||
<AtListItem | |||
className={styles.item} | |||
title="姓名" | |||
extraText={data?.cnName} | |||
/> | |||
<AtListItem | |||
className={styles.item} | |||
title="手机号" | |||
extraText={data?.phone} | |||
/> | |||
<AtListItem | |||
className={styles.item} | |||
title="邮箱" | |||
extraText={data?.email} | |||
// arrow="right" | |||
/> | |||
<AtListItem | |||
title="职务信息" | |||
className={styles.subtitle} | |||
/> | |||
<AtListItem | |||
className={styles.item} | |||
title="所在部门" | |||
extraText={data?.deptName} | |||
/> | |||
<AtListItem | |||
className={styles.item} | |||
title="职位" | |||
extraText={data?.position} | |||
/> | |||
</AtList> | |||
</ScrollView> | |||
<View className={styles.foot}> | |||
<View className={styles.logout} onClick={() => dispatch(logout())}> | |||
退出账户 | |||
</View> | |||
</View> | |||
</Page> | |||
) | |||
} |
@@ -0,0 +1,77 @@ | |||
.page { | |||
background-color: #f6f6f6; | |||
} | |||
.container { | |||
height: 100%; | |||
} | |||
.banner { | |||
position: relative; | |||
display: flex; | |||
align-items: center; | |||
flex-direction: row; | |||
justify-content: space-between; | |||
height: 132px *2; | |||
background-color: #f0f0f0; | |||
padding: 0 24px * 2; | |||
.avator { | |||
width: 84px * 2; | |||
height: 84px * 2; | |||
} | |||
.name { | |||
color: #32323c; | |||
font-size: 28px * 2; | |||
} | |||
.gradient { | |||
position: absolute; | |||
left: 0; | |||
right: 0; | |||
bottom: 0; | |||
height: 24px * 2; | |||
background: linear-gradient(to top, #d8d8d8, #f0f0f0); | |||
// background: linear-gradient(to top, #ff0000, #00ff00); | |||
} | |||
} | |||
.scroll { | |||
height: calc(100% - #{260px * 2}); | |||
} | |||
.subtitle { | |||
:global(.item-content__info-title) { | |||
font-size: 14px * 2; | |||
color: rgba(0, 0, 0, 0.56); | |||
} | |||
} | |||
.item { | |||
:global(.item-content__info-title) { | |||
color: #32323c; | |||
} | |||
:global(.item-extra__info) { | |||
font-size: 14px * 2; | |||
padding-right: 16px * 2; | |||
} | |||
:global(.at-list__item-extra) { | |||
max-width: none; | |||
} | |||
} | |||
.itemList { | |||
background-color: transparent; | |||
:global(.at-list__item) { | |||
padding-left: 24px * 2; | |||
} | |||
} | |||
.foot { | |||
height: (40 *2 + 44) * 2px; | |||
} | |||
.logout { | |||
position: absolute; | |||
bottom: 40px * 2; | |||
width: 327px * 2; | |||
height: 44px *2; | |||
left: 24px * 2; | |||
line-height: 44px * 2; | |||
color: #d20f00; | |||
background-color: #fff; | |||
text-align: center; | |||
border: 1px solid rgba(17, 17, 17, 0.15); | |||
border-radius: 8px * 2; | |||
} |
@@ -1,5 +1,5 @@ | |||
const initState = { | |||
isLogin:false, | |||
isLogin: false, | |||
safeArea: {}, | |||
statusBarHeight: 20, | |||
accountId: '', | |||
@@ -17,22 +17,19 @@ export default (state = initState, { type, payload }) => { | |||
...payload, | |||
}; | |||
case 'app/login': | |||
return { | |||
...state, | |||
isLogin: true, | |||
...payload, | |||
} | |||
return { | |||
...state, | |||
isLogin: true, | |||
...payload, | |||
} | |||
case 'app/logout': | |||
return { | |||
...state, | |||
isLogin: false, | |||
accountId: '', | |||
accountName: '', | |||
customerType: '', // 'provider' | 'ent' ent: 企业用户 | provider: 华能用户 | |||
customerId: '', | |||
customerName: '', | |||
customerShortName: '', | |||
orgId: '', | |||
companyId: '', | |||
avatorUrl: '', | |||
} | |||
default: | |||
return state; | |||
@@ -1,6 +1,6 @@ | |||
import { useEffect, useRef } from 'react'; | |||
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; | |||
export function useInterval(fn,delay,options) { | |||
export function useInterval(fn, delay, options) { | |||
const immediate = options?.immediate; | |||
const fnRef = useRef(); | |||
@@ -18,4 +18,29 @@ export function useInterval(fn,delay,options) { | |||
clearInterval(timer); | |||
}; | |||
}, [delay]); | |||
} | |||
export function useRequest(service) { | |||
const [loading, setLoading] = useState(false); | |||
const [data, setData] = useState(null); | |||
const ref = useRef(); | |||
ref.current = service; | |||
const wrapperFn = useCallback(async () => { | |||
setLoading(true); | |||
const res = await ref.current(); | |||
setLoading(false); | |||
setData(res); | |||
}, [ref]) | |||
useLayoutEffect(() => { | |||
wrapperFn(); | |||
}, [wrapperFn]) | |||
return { | |||
loading, | |||
data, | |||
trigger: wrapperFn | |||
} | |||
} |
@@ -10,4 +10,8 @@ export function set(key, value) { | |||
export function remove(key) { | |||
Taro.removeStorageSync(key); | |||
} | |||
export function clear() { | |||
Taro.clearStorage(); | |||
} |
@@ -1983,14 +1983,6 @@ | |||
react-reconciler "0.25.1" | |||
scheduler "^0.17.0" | |||
"@tarojs/redux@^2.2.10": | |||
version "2.2.10" | |||
resolved "https://registry.yarnpkg.com/@tarojs/redux/-/redux-2.2.10.tgz#63b1ee7cd123c17aa67d71d6d5ae8ce6ef6eacea" | |||
integrity sha512-t2dkhUi5W7iVO5GBPIqxNQEfSHm5UBtdIssQFn69Hd4vhuEWLATUBCLa4Ki8fYz1s+peqLfNuObz2svVKOiRDg== | |||
dependencies: | |||
"@tarojs/taro" "^2.2.10" | |||
"@tarojs/utils" "^2.2.10" | |||
"@tarojs/rn-runner@^3.2.10": | |||
version "3.2.10" | |||
resolved "https://registry.yarnpkg.com/@tarojs/rn-runner/-/rn-runner-3.2.10.tgz#18f2862b82442eae1d7f3eaf74d0955fe078555e" | |||
@@ -2184,13 +2176,6 @@ | |||
"@tarojs/runtime" "3.2.10" | |||
"@tarojs/taro-h5" "3.2.10" | |||
"@tarojs/taro@^2.2.10": | |||
version "2.2.17" | |||
resolved "https://registry.yarnpkg.com/@tarojs/taro/-/taro-2.2.17.tgz#78a95dc4e91ab4e4580205464ae684f32b612fa4" | |||
integrity sha512-Mw41xfoPFwFcePkGXAxkH7J+2yWEViLUeM5Y3MvEjmPi+MWLQK5eMf+YLXKEf2GJ8pxf7H9GYr0FLG7s8qowJw== | |||
dependencies: | |||
"@tarojs/utils" "2.2.17" | |||
"@tarojs/taroize@3.2.10": | |||
version "3.2.10" | |||
resolved "https://registry.yarnpkg.com/@tarojs/taroize/-/taroize-3.2.10.tgz#32130be822b623c14aa40f6552bbb6848d5934af" | |||
@@ -2240,16 +2225,6 @@ | |||
prettier "^1.14.2" | |||
typescript "^3.2.2" | |||
"@tarojs/utils@2.2.17": | |||
version "2.2.17" | |||
resolved "https://registry.yarnpkg.com/@tarojs/utils/-/utils-2.2.17.tgz#d6e4b808e3d7f984e8e5671a33e6f02ad2042651" | |||
integrity sha512-QMCcvicXKwEiF6+K5lwdF98dISRMrc/0pA3hQOPnnBrHSUSV19pD3tYC5kMcUxc7FqsQO7bS7WgWVXs+QECW2Q== | |||
"@tarojs/utils@^2.2.10": | |||
version "2.2.10" | |||
resolved "https://registry.yarnpkg.com/@tarojs/utils/-/utils-2.2.10.tgz#ddf82a77aeccfc315c2fb78b3d1c079860aed350" | |||
integrity sha512-5Y96pcSqqOYS/C1OlqtjzmTpD44n2AxobyKHpvVapqKdhnHbxkUVm+biqbHhfNqwr056KPviPQ4WMDjU33X7PA== | |||
"@tarojs/webpack-runner@3.2.10": | |||
version "3.2.10" | |||
resolved "https://registry.yarnpkg.com/@tarojs/webpack-runner/-/webpack-runner-3.2.10.tgz#e3271b2e68651452ffc2ce7ad6e915002affcba4" | |||