Commit 4fa39372 by 姜雷

完成首页和注册以及部分主页

parent aa361867
import createFetch from './index';
import { BASE_SERVER_URL } from '../constants/index';
const fetch = createFetch(BASE_SERVER_URL + '/dcxy/api');
export const fetchAllCampus = () =>
fetch({
url: '/campus/all',
});
import Taro, { request } from '@tarojs/taro';
import { BASE_SERVER_URL } from '../constants/index';
import store from '../store/index';
type ResponseDataEntity = {
export type ResponseDataEntity = {
code: number;
msg: string;
data: any;
......@@ -13,19 +13,28 @@ type ResponseEntity = {
[propName: string]: any;
};
const fetch = (entity: request.Param) => {
const createFetch = (basePath: string) => {
return (entity: request.Param): Promise<ResponseDataEntity> => {
const token = store.getState().userinfo.token;
return Taro.request({
...entity,
header: {
token: '',
},
url: BASE_SERVER_URL + entity.url,
header: token
? {
token: token,
}
: {},
url: basePath + entity.url,
}).then(({ data }: ResponseEntity) => {
if (data.code === 1000) {
return data;
}
Taro.showToast({
title: data.msg,
icon: 'none',
});
throw data;
});
};
};
export default fetch;
export default createFetch;
import fetch from './index';
export const login = data =>
fetch({
url: '/wx/api/user/login2',
data: data,
});
export const fetchAllCampus = () =>
fetch({
url: '/dcxy/api/campus/all',
});
import createFetch, { ResponseDataEntity } from './index';
import { BASE_SERVER_URL } from '../constants/index';
const fetch = createFetch(BASE_SERVER_URL + '/wx/api');
type LoginPramas = {
code: string;
};
type LoginReponseData = {
registed: boolean;
token: string;
};
export interface LoginReponse extends ResponseDataEntity {
data: LoginReponseData;
}
export const login = (data: LoginPramas): Promise<LoginReponse> =>
fetch({
url: '/user/login2',
data: data,
});
export const fetchValidateCode = () =>
fetch({
url: '/getValidateCode',
});
export const getImageVcode = () =>
fetch({
url: '/getImageValidateCode',
});
export const getVcode = entity =>
fetch({
url: '/getValidateCode',
method: 'POST',
data: entity,
});
type RegisiterPramas = {};
// type RegisiterReponseData = {};
export const fetchWxUserRegister = (entity: RegisiterPramas) =>
fetch({
url: '/user/regisiter2',
method: 'POST',
data: entity,
});
......@@ -30,3 +30,42 @@ button[disabled]:not([type]) {
width: 100%;
border-top: 1px solid #eee;
}
.registerBox-item {
display: flex;
justify-content: space-between;
align-items: center;
height: 80px;
line-height: 80px;
border-bottom: 1px solid #eee;
color: #333;
.loginBox-placeholder,
.noVlaue {
color: #999;
}
.loginBox-input {
width: 100%;
height: 100%;
font-size: 28px;
}
.registerBox-getVcode {
position: relative;
width: 268px;
text-align: center;
font-size: 28px;
color: #456beb;
}
.registerBox-getVcode::before {
content: '';
position: absolute;
left: 0px;
top: 26px;
height: 28px;
border-left: 1px solid #eee;
}
.registerBox-pwdIcon {
width: 44px;
height: 44px;
}
}
......@@ -4,7 +4,7 @@ import { Provider } from '@tarojs/redux';
import Index from './pages/index';
import configStore from './store';
import store from './store';
import './app.scss';
......@@ -14,8 +14,6 @@ if (process.env.NODE_ENV !== 'production' && process.env.TARO_ENV === 'h5') {
require('nerv-devtools');
}
const store = configStore();
class App extends Component {
/**
* 指定config的类型声明为: Taro.Config
......@@ -26,9 +24,11 @@ class App extends Component {
*/
config: Config = {
pages: [
'pages/Home/Home',
'pages/index/index',
'pages/ResetPwd/ResetPwd',
'pages/Register/Register',
// 'pages/Login/Login',
'pages/Login/Login',
// 'pages/CheckTelephone/CheckTelephone',
// 'pages/Feedback/Feedback',
// 'pages/Order/OrderDetail/OrderDetail',
......
.ToastBox {
position: absolute;
top: -100px;
left: 50%;
padding: 0 20px;
min-width: 200px;
height: 64px;
line-height: 64px;
text-align: center;
background-color: #ffd506;
border-radius: 48px;
transform: translate(-50%);
transition: all 400ms;
color: #fff;
opacity: 0;
}
.ToastBox.show {
top: 30px;
opacity: 1;
}
import { ComponentClass } from 'react';
import Taro, { Component } from '@tarojs/taro';
import { View } from '@tarojs/components';
import './ToastBox.scss';
type PageOwnProps = {};
type PageState = {
text: string;
visiable: boolean;
timer: number | undefined;
};
interface ToastBox {
props: PageOwnProps;
state: PageState;
}
class ToastBox extends Component {
constructor(props: PageOwnProps) {
super(props);
this.state = {
text: '提示',
visiable: false,
timer: undefined,
};
}
showToast(newText: string) {
const { timer } = this.state;
if (timer) {
clearTimeout(timer);
}
setTimeout(() => {
this.setState({
visiable: false,
});
}, 3000);
this.setState({
text: newText,
visiable: true,
});
}
render() {
const { text, visiable } = this.state;
return <View className={`ToastBox ${visiable ? 'show' : ''}`}>{text}</View>;
}
}
export default ToastBox as ComponentClass<PageOwnProps, PageState>;
......@@ -3,9 +3,11 @@ import Taro, { Component } from '@tarojs/taro';
import { View } from '@tarojs/components';
import './Vcode.scss';
import { getVcode } from '../../api/wx';
type PageOwnProps = {
text?: string;
cellphone: string;
};
type PageState = {
defaultText: string;
......@@ -24,6 +26,7 @@ class Vcode extends Component {
constructor(props: PageOwnProps) {
super(props);
this.state = {
defaultText: props.text ? props.text : '获取验证码',
counting: false,
......@@ -39,6 +42,29 @@ class Vcode extends Component {
}
}
clickHandle() {
const { cellphone } = this.props;
if (cellphone && cellphone.length == 11) {
getVcode({
tel: cellphone,
})
.then(res => {
this.countStart();
Taro.showToast({
title: res.msg,
mask: true,
});
})
.catch(console.error);
} else {
Taro.showToast({
title: '输入正确的手机号',
icon: 'none',
mask: true,
});
}
}
countStart() {
this.setState({
counting: true,
......@@ -66,9 +92,9 @@ class Vcode extends Component {
render() {
const { defaultText, counting, count } = this.state;
return counting ? (
<View className='vcode-classname Vcode Counting'>{`${count}S`}</View>
<View className='vcode-classname Vcode Counting'>{`${count}S后重发`}</View>
) : (
<View className='vcode-classname Vcode' onClick={this.countStart}>
<View className='vcode-classname Vcode' onClick={this.clickHandle}>
{defaultText}
</View>
);
......
.Home {
padding: 0 32px;
.Home-UserBox {
position: relative;
width: 100%;
height: 390px;
}
.Home-UserBox-bg {
position: absolute;
z-index: -1;
width: 100%;
height: 100%;
}
.Home-UserBox-info {
padding: 80px 88px 20px 76px;
display: flex;
justify-content: space-between;
color: #333;
}
.Home-UserBox-name {
font-size: 44px;
margin-bottom: 8px;
}
.Home-UserBox-tel {
font-size: 32px;
margin-bottom: 8px;
}
.Home-UserBox-addr {
font-size: 24px;
}
.Home-UserBox-headimg {
width: 100px;
height: 100px;
border-radius: 50%;
border: 10px solid #c8ccfc;
}
.Home-UserBox-line {
width: 620px;
border-top: 1px solid #d7daff;
margin: 0 auto;
}
.Home-UserBox-Bean {
padding: 32px 40px 0;
display: flex;
justify-content: space-around;
}
.Home-UserBox-Order {
position: absolute;
left: 50%;
bottom: -40px;
transform: translate(-50%);
width: 572px;
height: 80px;
line-height: 80px;
background-color: #6180f4;
border-radius: 50px;
display: flex;
overflow: hidden;
}
.Home-UserBox-Order-text {
flex: 1;
text-align: center;
color: #fff;
font-size: 24px;
}
.Home-UserBox-Order-right {
background-color: #375ef1;
width: 212px;
display: flex;
justify-content: center;
align-items: center;
}
.Home-UserBox-Order-icon {
width: 40px;
height: 20px;
}
}
import { ComponentClass } from 'react';
import Taro, { Component } from '@tarojs/taro';
import { View, Image, Text } from '@tarojs/components';
import UserBoxBg from '../../images/home/img_bg@2x.png';
import UserImg from '../../images/home/pc_minel_icon@2x.png';
import ArrowIcon from '../../images/home/icon_dingdan@2x.png';
class Home extends Component {
render() {
return (
<View className='Home'>
<View className='Home-UserBox'>
<Image className='Home-UserBox-bg' src={UserBoxBg} />
<View className='Home-UserBox-info'>
<View className='Home-UserBox-other'>
<View className='Home-UserBox-name'>中小</View>
<View className='Home-UserBox-tel'>16878964216</View>
<View className='Home-UserBox-addr'>成都师范学校-温江小区</View>
</View>
<Image className='Home-UserBox-headimg' src={UserImg} />
</View>
<View className='Home-UserBox-line' />
<View className='Home-UserBox-Bean'>
<View className='Home-UserBox-BeanItem'>吹风豆:2.35</View>
<View className='Home-UserBox-BeanItem'>通用豆:12.35</View>
</View>
<View className='Home-UserBox-Order'>
<Text className='Home-UserBox-Order-text'>我的订单</Text>
<View className='Home-UserBox-Order-right'>
<Image className='Home-UserBox-Order-icon' src={ArrowIcon} />
</View>
</View>
</View>
<View>吹风</View>
<View>公告</View>
</View>
);
}
}
export default Home as ComponentClass;
......@@ -7,20 +7,8 @@
margin-top: 168px;
color: #fff;
font-size: 48px;
}
.Login-loginWay-tab {
margin-top: 60px;
margin-bottom: 44px;
}
.Login-loginWay-item {
color: #c2cef9;
font-size: 32px;
margin-right: 28px;
}
.Login-loginWay-item.active {
color: #fff;
font-size: 40px;
}
.Login-vcodeBox,
.Login-input {
height: 96px;
......@@ -57,7 +45,8 @@
}
}
.Login-regist {
text-align: right;
display: flex;
justify-content: space-between;
color: #c2cef9;
margin-bottom: 52px;
}
......
......@@ -2,16 +2,11 @@ import { ComponentClass } from 'react';
import Taro, { Component, Config } from '@tarojs/taro';
import { View, Button, Text, Input, Navigator } from '@tarojs/components';
import Vcode from '../../components/Vcode/Vcode';
import './Login.scss';
type PageState = {
loginWay: string;
vcode: string;
account: string;
pwd: string;
tel: string;
code: string;
};
interface Login {
......@@ -26,42 +21,17 @@ class Login extends Component {
constructor(props) {
super(props);
this.state = {
loginWay: 'tel',
vcode: '',
account: '',
pwd: '',
tel: '',
code: '',
};
}
toggleLoginWay(state: string) {
this.setState({
loginWay: state,
});
}
loginHandle() {}
render() {
const { loginWay } = this.state;
return (
<View className='Login'>
<View className='Login-title'>欢迎来到多彩校园</View>
<View className='Login-loginWay-tab'>
<Text
className={`Login-loginWay-item ${
loginWay === 'account' ? 'active' : ''
}`}
onClick={() => this.toggleLoginWay('account')}>
账号登录
</Text>
<Text
className={`Login-loginWay-item ${
loginWay === 'tel' ? 'active' : ''
}`}
onClick={() => this.toggleLoginWay('tel')}>
手机号登录
</Text>
</View>
{loginWay === 'account' ? (
<View>
<Input
className='Login-input'
......@@ -75,29 +45,9 @@ class Login extends Component {
placeholder='请输入密码'
/>
</View>
) : (
<View>
<Input
className='Login-input'
type='number'
placeholder-class='Login-input-placeholder'
placeholder='请输入手机号'
maxLength={11}
/>
<View className='Login-vcodeBox'>
<Input
className='Login-input'
type='number'
placeholder-class='Login-input-placeholder'
placeholder='请输入验证码'
maxLength={6}
/>
<Vcode vcode-classname='Login-Vcode' text='获取验证码' />
</View>
</View>
)}
<View className='Login-regist'>
<View>
还没有账号?
<Navigator
className='Login-regist-btn'
......@@ -105,7 +55,15 @@ class Login extends Component {
注册
</Navigator>
</View>
<Button className='Login-btn'>登录</Button>
<Navigator
className='Login-regist-btn'
url='/pages/ResetPwd/ResetPwd'>
忘记密码
</Navigator>
</View>
<Button className='Login-btn' onClick={this.loginHandle}>
登录
</Button>
</View>
);
}
......
......@@ -15,24 +15,6 @@
margin-right: 10px;
}
}
.registerBox-item {
display: flex;
justify-content: space-between;
align-items: center;
height: 80px;
line-height: 80px;
border-bottom: 1px solid #eee;
color: #333;
.loginBox-placeholder,
.noVlaue {
color: #999;
}
.loginBox-input {
width: 100%;
height: 100%;
font-size: 28px;
}
}
.sexBox {
display: flex;
.sexBox-item {
......@@ -46,25 +28,7 @@
margin-right: 20px;
}
}
.registerBox-getVcode {
position: relative;
width: 268px;
text-align: center;
font-size: 28px;
color: #456beb;
}
.registerBox-getVcode::before {
content: '';
position: absolute;
left: 0px;
top: 26px;
height: 28px;
border-left: 1px solid #eee;
}
.registerBox-pwdIcon {
width: 44px;
height: 44px;
}
}
.registerBox-agreeBox {
height: 60px;
......
......@@ -15,10 +15,11 @@ import './Register.scss';
import agreeIcon from '../../images/login/icon_zhuce_sel@2x.png';
import agreeNotIcon from '../../images/login/icon_zhuce_nor@2x.png';
import { connect } from '@tarojs/redux';
import { StoreState } from 'src/store/rootReducers/userinfo';
import { UserState } from '../../store/rootReducers/userinfo';
import { getVcode, fetchWxUserRegister } from '../../api/wx';
type PageStateProps = {
userinfo: StoreState;
userinfo: UserState;
};
type PageDispatchProps = {
// updateUserInfo: (e: User) => void;
......@@ -27,6 +28,7 @@ type PageDispatchProps = {
type PageState = {
name: string;
cellphone: string;
vcode: string;
pwd: string;
checkPwd: string;
sex: string;
......@@ -52,10 +54,11 @@ class Register extends Component {
constructor(props: IProps) {
super(props);
this.state = {
name: '',
cellphone: '',
pwd: '',
checkPwd: '',
name: '姜雷',
cellphone: '18108096033',
vcode: '',
pwd: '123456',
checkPwd: '123456',
sex: 'Male',
agree: false,
showPwd: false,
......@@ -68,38 +71,75 @@ class Register extends Component {
sex: value,
});
}
updateName({ detail: { value } }) {
this.setState({
name: value,
getVcode() {
const { cellphone } = this.state;
if (cellphone.length == 11) {
// getVcode({
// tel: cellphone,
// })
// .then(res => {
// console.log(res);
// Taro.showToast({
// title: res.msg,
// mask: true,
// });
// })
// .catch(console.error);
this.refs.Vcode.countStart();
} else {
Taro.showToast({
title: '输入正确的手机号',
icon: 'none',
mask: true,
});
}
}
validateRegisterEntity(): boolean {
const { name, cellphone, pwd, checkPwd, agree } = this.state;
const { name, cellphone, pwd, checkPwd } = this.state;
const {
userinfo: { campusId },
} = this.props;
if (!name) {
console.log('请输入姓名');
Taro.showToast({
title: '请输入姓名',
icon: 'none',
});
return false;
}
if (!cellphone || cellphone.length !== 11) {
console.log('请输入手机号码');
Taro.showToast({
title: '请输入手机号码',
icon: 'none',
});
return false;
}
if (!pwd) {
console.log('请输入密码');
Taro.showToast({
title: '请输入密码',
icon: 'none',
});
return false;
}
if (!checkPwd) {
console.log('请输入确认密码');
Taro.showToast({
title: '请输入确认密码',
icon: 'none',
});
return false;
}
if (pwd != checkPwd) {
console.log('请输入确认密码');
Taro.showToast({
title: '请输入确认密码',
icon: 'none',
});
return false;
}
if (!agree) {
console.log('请勾选同意条款');
if (!campusId) {
Taro.showToast({
title: '请选择所属校区',
icon: 'none',
});
return false;
}
return true;
......@@ -107,9 +147,18 @@ class Register extends Component {
getRegister() {
if (this.validateRegisterEntity()) {
const { name, cellphone, pwd, checkPwd, sex } = this.state;
console.log(name, cellphone, pwd, checkPwd, sex);
console.log('跳转首页');
const { name, cellphone, pwd, sex } = this.state;
const {
userinfo: { campusId, schoolId },
} = this.props;
fetchWxUserRegister({
cellphone,
campusId,
name,
pwd,
schoolId,
sex,
});
}
}
......@@ -138,7 +187,17 @@ class Register extends Component {
}
render() {
const { sex, showPwd, showCheckPwd, agree } = this.state;
const {
name,
sex,
showPwd,
showCheckPwd,
agree,
cellphone,
vcode,
pwd,
checkPwd,
} = this.state;
const { userinfo } = this.props;
return (
<View className='Register topBr'>
......@@ -152,6 +211,7 @@ class Register extends Component {
className='loginBox-input'
placeholderClass='loginBox-placeholder'
placeholder='输入您的姓名'
value={name}
onInput={({ detail: { value } }) => {
this.setState({
name: value.trim(),
......@@ -187,6 +247,7 @@ class Register extends Component {
placeholderClass='loginBox-placeholder'
placeholder='请输入注册的手机号码'
type='number'
value={cellphone}
onInput={({ detail: { value } }) => {
this.setState({
cellphone: value,
......@@ -202,8 +263,13 @@ class Register extends Component {
placeholderClass='loginBox-placeholder'
placeholder='请输入验证码'
maxLength={6}
value={vcode}
/>
<Vcode
vcode-classname='registerBox-getVcode'
ref='Vcode'
onClickHandle={this.getVcode}
/>
<Vcode vcode-classname='registerBox-getVcode' />
</View>
<View className='registerBox-title'>
<Image className='registerBox-icon' src={pwdIcon} />
......@@ -216,6 +282,13 @@ class Register extends Component {
password={!showPwd}
placeholder='密码由6-20位组成'
maxLength={20}
value={pwd}
onInput={({ detail: { value } }) => {
this.setState({
pwd: value,
});
return value;
}}
/>
<Image
className='registerBox-pwdIcon'
......@@ -230,6 +303,13 @@ class Register extends Component {
password={!showCheckPwd}
placeholder='确认密码'
maxLength={20}
value={checkPwd}
onInput={({ detail: { value } }) => {
this.setState({
checkPwd: value,
});
return value;
}}
/>
<Image
className='registerBox-pwdIcon'
......
.ResetPwd {
.ResetPwd-form {
padding: 0 32px;
}
.ResetPwd-title {
margin-top: 52px;
margin-bottom: 32px;
font-size: 32px;
}
.ResetPwd-btn {
margin: 40px 16px 0;
border-radius: 24px;
}
}
import Taro, { Component, Config } from '@tarojs/taro';
import { ComponentClass } from 'react';
import { View, Input, Image, Button } from '@tarojs/components';
import Vcode from '../../components/Vcode/Vcode';
import pwdHideIcon from '../../images/login/setting_invisible_icon@2x.png';
import pwdShowIcon from '../../images/login/setting_see_icon@2x.png';
import './ResetPwd.scss';
type PageOwnProps = {};
type PageState = {
cellphone: string;
vcode: string;
pwd: string;
checkPwd: string;
showPwd: boolean;
showCheckPwd: boolean;
};
interface ResetPwd {
props: PageOwnProps;
state: PageState;
}
class ResetPwd extends Component {
config: Config = {
navigationBarTitleText: '找回APP登陆密码',
};
constructor(props: PageOwnProps) {
super(props);
this.state = {
cellphone: '',
vcode: '',
pwd: '',
checkPwd: '',
showPwd: false,
showCheckPwd: false,
};
}
togglePwdBox() {
this.setState(({ showPwd }: PageState) => ({
showPwd: !showPwd,
}));
}
togglePwdCheckBox() {
this.setState(({ showCheckPwd }: PageState) => ({
showCheckPwd: !showCheckPwd,
}));
}
validatePwdForm(): boolean {
const { pwd, checkPwd, cellphone, vcode } = this.state;
if (!cellphone || cellphone.length !== 11) {
Taro.showToast({
title: '请输入手机号码',
icon: 'none',
});
return false;
}
if (!vcode || vcode.length !== 6) {
Taro.showToast({
title: '请输入验证码',
icon: 'none',
});
return false;
}
if (!pwd || pwd.length < 6) {
Taro.showToast({
title: '请输入大于6位密码',
icon: 'none',
});
return false;
}
if (!checkPwd || checkPwd.length < 6) {
Taro.showToast({
title: '请输入大于6位密码',
icon: 'none',
});
return false;
}
if (pwd !== checkPwd) {
Taro.showToast({
title: '两次密码不一致',
icon: 'none',
});
return false;
}
return true;
}
resetPwd() {
if (this.validatePwdForm()) {
console.log('回到登陆');
Taro.redirectTo({
url: '/pages/Login/Login',
});
}
}
render() {
const { cellphone, vcode, showPwd, pwd, checkPwd } = this.state;
return (
<View className='ResetPwd'>
<View className='ResetPwd-form'>
<View className='ResetPwd-title'>请输入您的登陆手机号</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
placeholder='请输入注册的手机号码'
type='number'
value={cellphone}
onInput={({ detail: { value } }) => {
this.setState({
cellphone: value,
});
return value;
}}
maxLength={11}
/>
</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
placeholder='请输入验证码'
maxLength={6}
value={vcode}
/>
<Vcode
vcode-classname='registerBox-getVcode'
ref='Vcode'
cellphone={cellphone}
/>
</View>
<View className='ResetPwd-title'>设置新密码</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
password={!showPwd}
placeholder='输入6-20位新密码'
maxLength={20}
value={pwd}
onInput={({ detail: { value } }) => {
this.setState({
pwd: value,
});
return value;
}}
/>
<Image
className='registerBox-pwdIcon'
src={showPwd ? pwdShowIcon : pwdHideIcon}
onClick={this.togglePwdBox}
/>
</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
password={!showPwd}
placeholder='确认6-20位新密码'
maxLength={20}
value={checkPwd}
onInput={({ detail: { value } }) => {
this.setState({
checkPwd: value,
});
return value;
}}
/>
<Image
className='registerBox-pwdIcon'
src={showPwd ? pwdShowIcon : pwdHideIcon}
onClick={this.togglePwdCheckBox}
/>
</View>
</View>
<Button className='ResetPwd-btn' onClick={this.resetPwd}>
确定
</Button>
</View>
);
}
}
export default ResetPwd as ComponentClass<PageOwnProps, PageState>;
.Location {
background-color: #fff;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
height: 100%;
.searchBox {
display: flex;
height: 90px;
......@@ -36,6 +35,7 @@
}
.infoBar {
position: fixed;
z-index: 2;
top: 262px;
right: 30px;
width: 40px;
......@@ -49,10 +49,12 @@
}
.infoToast {
position: fixed;
z-index: 2;
width: 180px;
height: 180px;
line-height: 180px;
background-color: rgba(254, 148, 10, 0.4);
background-color: #a2b5f5;
border-radius: 8px;
left: 9999px;
top: 480px;
margin-left: -90px;
......@@ -67,9 +69,7 @@
left: 50%;
}
.locationList {
height: 100%;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
height: calc(100vh - 90rpx);
}
.locationTitle {
padding: 0 40px;
......
......@@ -2,67 +2,18 @@ import { ComponentClass } from 'react';
import Taro, { Component, Config } from '@tarojs/taro';
import { connect } from '@tarojs/redux';
import { View, Text, Input, Image } from '@tarojs/components';
import { View, Text, Input, Image, ScrollView } from '@tarojs/components';
import SearchIcon from '../../images/login/icon_search@2x.png';
import { Campus, CampusList } from '../../types/Campus/Campus';
import { fetchAllCampus } from '../../api/login';
import { StoreState, updateUserInfo } from '../../store/rootReducers/userinfo';
import { fetchAllCampus } from '../../api/campus';
import { UserState, updateUserInfo } from '../../store/rootReducers/userinfo';
import User from 'src/types/User/User';
const resData = [
{
id: 47,
schoolId: 36,
name: '保定职业技术学院1',
mobile: '15212121222',
address: '河北省保定市新市区朝阳南大街613号',
introduce: '',
fd_version: '1',
isDel: 0,
openLattice: 'N',
firstPin: 'B',
},
{
id: 126,
schoolId: 36,
name: '保定职业技术学院测试学院1',
mobile: '15232569878',
address: '敖德萨所大所多',
introduce: '奥术大师多',
fd_version: '2',
isDel: 0,
openLattice: 'N',
firstPin: 'B',
},
{
id: 12,
schoolId: 6,
name: '成师温江校区',
mobile: '13608207722',
address: '海科路东段99号',
introduce: '',
fd_version: '1',
isDel: 0,
openLattice: 'N',
firstPin: 'C',
},
{
id: 116,
schoolId: 200004,
name: '成都正阳1.0校区 ',
mobile: '15881097999',
address: '四川省成都市温江区',
introduce: '用于虚拟客户体验使用',
fd_version: '1',
isDel: 0,
openLattice: 'N',
firstPin: 'C',
},
];
import './SelectCampus.scss';
type PageStateProps = {
userinfo: StoreState;
userinfo: UserState;
};
type PageDispatchProps = {
updateUserInfo: (e: User) => void;
......@@ -72,6 +23,9 @@ type PageState = {
campusList: CampusList;
filterList: CampusList;
filterName: string;
showToast: boolean;
localText: string;
timer: number | undefined;
};
type IProps = PageStateProps & PageDispatchProps;
......@@ -101,10 +55,17 @@ class SelectCampus extends Component {
filterName: '',
campusList: [],
filterList: [],
showToast: false,
localText: '',
timer: undefined,
};
}
componentWillMount() {
this.getList();
}
getList() {
fetchAllCampus()
.then(res => {
console.log(res);
......@@ -132,32 +93,9 @@ class SelectCampus extends Component {
})
.catch(err => {
console.log(err);
let campusIndexArr: Array<string> = [];
let campusList: CampusList = [];
resData.map((campus: Campus) => {
let firstPin = campus.firstPin;
if (firstPin) {
let index = campusIndexArr.indexOf(firstPin);
if (index > -1) {
campusList[index].children.push(campus);
} else {
campusIndexArr.push(firstPin);
campusList.push({
firstPin: firstPin,
children: [campus],
});
}
}
});
this.setState({
campusList: campusList,
filterList: campusList,
});
});
this.setState(({ campusList }: PageState) => ({
filterList: campusList,
}));
}
searchList() {
let { filterName, campusList } = this.state;
if (filterName) {
......@@ -185,7 +123,31 @@ class SelectCampus extends Component {
});
}
}
bindCampus({ id, name, schoolId }: Campus) {
showToastHandle(text: string) {
console.log(text);
const { timer } = this.state;
if (timer) {
clearTimeout(timer);
}
const newTimer = setTimeout(() => {
this.setState({
showToast: false,
localText: '',
});
}, 1000);
this.setState({
showToast: true,
localText: text,
timer: newTimer,
});
}
bindCampus({ target: { dataset } }) {
const {
campus: { id, name, schoolId },
} = dataset;
this.props.updateUserInfo({
campusId: id,
campusName: name,
......@@ -195,7 +157,13 @@ class SelectCampus extends Component {
}
render() {
const { filterList, filterName } = this.state;
const {
campusList,
filterList,
filterName,
showToast,
localText,
} = this.state;
return (
<View className='Location topBr'>
<View className='searchBox'>
......@@ -215,23 +183,41 @@ class SelectCampus extends Component {
<Text>搜索</Text>
</View>
</View>
<View className='locationList'>
<View className='infoBar'>
{campusList.map(item => (
<View
key={item.firstPin}
className='infoItem'
onClick={() => this.showToastHandle(item.firstPin)}>
{item.firstPin}
</View>
))}
</View>
<View className={showToast ? 'show br8 infoToast' : 'br8 infoToast'}>
{localText}
</View>
<ScrollView
scroll-y
className='locationList'
scrollIntoView={localText}
scrollWithAnimation>
{filterList.map(campusItem => (
<View key={campusItem.firstPin} className='locationArea'>
<View id={campusItem.firstPin} className='locationTitle'>
{campusItem.firstPin}
</View>
{campusItem.children.map((campus, index) => (
{campusItem.children.map(campus => (
<View
key={index}
key={campus.id}
className='locationItem'
onClick={() => this.bindCampus(campus)}>
data-campus={campus}
onClick={this.bindCampus}>
{campus.name}
</View>
))}
</View>
))}
</View>
</ScrollView>
</View>
);
}
......
import { ComponentClass } from 'react';
import Taro, { Component, Config } from '@tarojs/taro';
import { View, Button } from '@tarojs/components';
import { View } from '@tarojs/components';
import './index.scss';
import { login } from '../../api/login';
import { login, LoginReponse } from '../../api/wx';
import { connect } from '@tarojs/redux';
type PageStateProps = {
counter: {
num: number;
};
};
import { updateUserInfo, UserState } from '../../store/rootReducers/userinfo';
type PageDispatchProps = {};
type PageDispatchProps = {
updateUserInfo: (e: UserState) => void;
};
type PageOwnProps = {};
type PageState = {
loadingText: string;
};
type PageState = {};
type IProps = PageStateProps & PageDispatchProps & PageOwnProps;
type IProps = PageDispatchProps & PageOwnProps;
interface Index {
props: IProps;
state: PageState;
}
@connect(
() => ({}),
dispatch => ({
updateUserInfo(entity: UserState) {
dispatch(updateUserInfo(entity));
},
}),
)
class Index extends Component {
config: Config = {};
constructor(props) {
constructor(props: IProps) {
super(props);
this.state = {
loadingText: 'Loading...',
};
}
componentWillMount() {
Taro.showLoading();
this.checkUser();
}
checkUser() {
Taro.getStorage({
key: 'token',
})
.then(res => {
console.log(res);
const data = res.data;
const userInfo = Taro.getStorageSync('userInfo');
console.log('token ' + data);
})
.catch(() => {
this.loginHandle();
......@@ -49,41 +58,43 @@ class Index extends Component {
}
loginHandle() {
Taro.login().then(res => {
const { updateUserInfo } = this.props;
Taro.login()
.then(res => {
console.log(res);
login({
code: res.code,
})
.then(res => {
const data = res.data;
.then((res: LoginReponse) => {
const { registed, token } = res.data;
if (registed) {
Taro.setStorage({ key: 'token', data: token });
Taro.setStorage({ key: 'userInfo', data: token });
Taro.redirectTo({
url: '/pages/Home/Home',
});
} else {
updateUserInfo({
token: token,
});
Taro.hideLoading();
Taro.redirectTo({
url: '/pages/Login/Login',
});
}
})
.catch(err => {
console.log(err);
this.setState({
loadingText: '',
});
});
// Taro.setStorage({ key: 'token', data: res.code });
})
.catch(err => {
console.log(err);
});
}
navToLogin() {
this.loginHandle();
// Taro.navigateTo({
// url: '/pages/Register/Register',
// });
}
render() {
const { loadingText } = this.state;
return (
<View className='Index'>
<View className='Index-loading-text'>{loadingText}</View>
<Button className='dec_btn' onClick={this.navToLogin}>
登录
</Button>
</View>
);
return <View className='Index' />;
}
}
export default Index as ComponentClass<IProps, PageState>;
export default Index as ComponentClass<PageOwnProps, PageState>;
import { createStore, applyMiddleware, compose } from 'redux'
import thunkMiddleware from 'redux-thunk'
import rootReducer from './reducers'
import { createStore, applyMiddleware, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
import rootReducer from './reducers';
const composeEnhancers =
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
}) : compose
})
: compose;
const middlewares = [
thunkMiddleware
]
const middlewares = [thunkMiddleware];
if (process.env.NODE_ENV === 'development') {
middlewares.push(require('redux-logger').createLogger())
middlewares.push(require('redux-logger').createLogger());
}
const enhancer = composeEnhancers(
applyMiddleware(...middlewares),
// other store enhancers if any
)
);
export default function configStore () {
const store = createStore(rootReducer, enhancer)
return store
}
const store = createStore(rootReducer, enhancer);
export default store;
import User from '../../types/User/User';
import Action from '../../types/Store/Actions';
export interface StoreState extends User {
login: boolean;
token: string;
export interface UserState extends User {
login?: boolean;
token?: string;
}
const INITIAL_STATE = {
......@@ -23,9 +23,9 @@ export const updateUserInfo = (entity: User): Action => ({
});
export default function userinfo(
state: StoreState = INITIAL_STATE,
state: UserState = INITIAL_STATE,
actions: Action,
): StoreState {
): UserState {
switch (actions.type) {
case 'UPDATE_USERINFO':
return {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment