Commit b15f188f by 姜雷

添加个人设置功能

parent d2ca5a94
......@@ -93,3 +93,77 @@ export const refreshCodeBar = (): Promise<ResponseDataEntity<string>> =>
customerFetch({
url: '/dcxy/wechat/applet/flush/idbar',
});
type ChangeAppPasswordParam = {
customerId: number;
oldPassword: string;
password: string;
};
export const changeAppPassword = (
entity: ChangeAppPasswordParam,
): Promise<ResponseDataEntity<null>> =>
customerFetch({
url: '/app/customer/old/pwd',
method: 'POST',
data: entity,
});
export const changeDevicePassword = (
entity: ChangeAppPasswordParam,
): Promise<ResponseDataEntity<null>> =>
customerFetch({
url: '/app/customer/hardware/pwd',
method: 'POST',
data: entity,
});
type ChangePhoneAccountParams = {
customerId: number;
password: string;
phoneAccount: string;
verification: string;
};
export const changePhoneAccount = (
entity: ChangePhoneAccountParams,
): Promise<ResponseDataEntity<null>> =>
customerFetch({
url: '/app/customer/phone/account/',
method: 'POST',
data: entity,
});
type SwitchAccountLoginStateParams = {
customerId: number;
state: string;
};
export const switchAccountLoginState = (
entity: SwitchAccountLoginStateParams,
): Promise<ResponseDataEntity<null>> =>
customerFetch({
url: `/app/customer/switch/${entity.customerId}/${entity.state}`,
method: 'PUT',
});
type FetchBalanceStateParams = {
customerId: number;
};
export enum BalanceState {
open = 1,
close = 0,
}
export const fetchBalanceState = (
entity: FetchBalanceStateParams,
): Promise<ResponseDataEntity<BalanceState>> =>
customerFetch({
url: '/app/customer/balance/state',
data: entity,
});
type SwitchBalanceStateParams = {
customerId: number;
isEnabled: BalanceState;
};
export const switchBalanceState = (
entity: SwitchBalanceStateParams,
): Promise<ResponseDataEntity<null>> =>
customerFetch({
url: `/app/customer/swich/balance/${entity.customerId}/${entity.isEnabled}`,
method: 'PUT',
});
......@@ -24,15 +24,15 @@ class App extends Component {
*/
config: Config = {
pages: [
// 'pages/Shower/ShowerAppointment',
'pages/index/index',
'pages/UserSetting/CustomerSetting',
'pages/Home/Home',
'pages/Order/OrderPay/OrderPay',
'pages/Order/OrderList/OrderList',
'pages/BarCode/BarCode',
'pages/Announcement/Announcement',
'pages/UserSetting/UserSetting',
'pages/ResetPwd/ResetPwd',
'pages/PassWord/ResetPwd',
'pages/Register/Register',
'pages/Login/Login',
'pages/Feedback/Feedback',
......@@ -44,6 +44,9 @@ class App extends Component {
'pages/Shower/ShowerAppointment',
'pages/WaterDispenser/WaterDispenser',
'pages/Account/Account',
'pages/PassWord/ChangePwd',
'pages/PassWord/ChangeHardwareAccount',
'pages/PassWord/ChangeTelAccount',
],
window: {
backgroundTextStyle: 'light',
......
......@@ -12,7 +12,7 @@
background-color: #fff;
border-radius: 24px;
margin-top: 4px;
height: 176px;
// height: 176px;
font-size: 28px;
text-align: center;
line-height: 88px;
......
......@@ -255,6 +255,13 @@ class Home extends Component {
});
}
goUserSetting() {
this.toggleBarMenu();
Taro.navigateTo({
url: '/pages/UserSetting/CustomerSetting',
});
}
render() {
const { userinfo, serviceList } = this.props;
const { annItem, barMenuVisiable } = this.state;
......@@ -266,6 +273,7 @@ class Home extends Component {
<View className='mask' onClick={this.toggleBarMenu} />
<View className='Home-BarMenu'>
<View className='Home-BarMenu-Content'>
<View onClick={this.goUserSetting}>个人设置</View>
<View onClick={this.goFeedback}>意见反馈</View>
<View onClick={this.logoutHandle}>切换账号</View>
</View>
......
......@@ -160,7 +160,7 @@ class Login extends Component {
</View>
<Navigator
className='Login-regist-btn'
url='/pages/ResetPwd/ResetPwd'>
url='/pages/PassWord/ResetPwd'>
忘记密码
</Navigator>
</View>
......
.ChangeHardwareAccount {
.ChangePwd-btn {
margin-top: 60px;
}
}
import './Common.scss';
import './ChangeHardwareAccount.scss';
import Taro from '@tarojs/taro';
import usePasswordInput from './usePasswordInput';
import { View, Button, Image, Input } from '@tarojs/components';
import pwdHideIcon from '../../images/login/setting_invisible_icon@2x.png';
import pwdShowIcon from '../../images/login/setting_see_icon@2x.png';
import { changeDevicePassword } from '@/api/customer';
import { useSelector } from '@tarojs/redux';
import { Customer } from '@/types/Customer/Customer';
const ChangeHardwareAccount = () => {
const customerId = useSelector(
(state: { userinfo: Customer }) => state.userinfo.customerId,
);
const { pwd, setPwd, showPwd, setShowPwd } = usePasswordInput();
const {
pwd: oldPwd,
setPwd: setOldPwd,
showPwd: showOldPwd,
setShowPwd: setShowOldPwd,
} = usePasswordInput();
const {
pwd: checkPwd,
setPwd: setCheckPwd,
showPwd: showCheckPwd,
setShowPwd: setShowCheckPwd,
} = usePasswordInput();
const changeAccountHandle = () => {
if (!oldPwd || oldPwd.length < 6) {
return Taro.showToast({
title: '请输入6-20位APP登录密码',
icon: 'none',
});
}
if (!pwd || pwd.length !== 4) {
return Taro.showToast({
title: '请输入4位新密码',
icon: 'none',
});
}
if (!checkPwd || checkPwd.length !== 4 || pwd !== checkPwd) {
return Taro.showToast({
title: '请确认输入密码和新密码完全一致',
icon: 'none',
});
}
Taro.showLoading();
changeDevicePassword({
password: pwd,
oldPassword: oldPwd,
customerId: customerId,
})
.then(res => {
Taro.hideLoading();
Taro.showToast({
title: '修改成功',
});
})
.catch(err => {
Taro.hideLoading();
Taro.showToast({
title: err.msg || '修改成功',
icon: 'none',
});
});
};
return (
<View className='ChangeHardwareAccount Password'>
<View className='Password-form'>
<View className='Password-title'>APP登录密码</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
password={!showOldPwd}
placeholder='请输入当前登录密码'
maxLength={20}
value={oldPwd}
onInput={({ detail: { value } }) => setOldPwd(value)}
/>
<Image
className='registerBox-pwdIcon'
src={showOldPwd ? pwdShowIcon : pwdHideIcon}
onClick={setShowOldPwd}
/>
</View>
<View className='Password-title'>新密码</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
type='number'
password={!showPwd}
placeholder='设备密码由4位数字组成'
maxLength={4}
value={pwd}
onInput={({ detail: { value } }) => setPwd(value)}
/>
<Image
className='registerBox-pwdIcon'
src={showPwd ? pwdShowIcon : pwdHideIcon}
onClick={setShowPwd}
/>
</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
type='number'
password={!showCheckPwd}
placeholder='确认密码'
maxLength={4}
value={checkPwd}
onInput={({ detail: { value } }) => setCheckPwd(value)}
/>
<Image
className='registerBox-pwdIcon'
src={showCheckPwd ? pwdShowIcon : pwdHideIcon}
onClick={setShowCheckPwd}
/>
</View>
<Button className='ChangePwd-btn' onClick={changeAccountHandle}>
确定
</Button>
</View>
</View>
);
};
ChangeHardwareAccount.config = {
navigationBarTitleText: '设备密码修改',
};
export default ChangeHardwareAccount;
.ChangePwd {
.ChangePwd-forget {
margin: 40px auto 60px;
color: #f93d3d;
font-size: 24px;
text-align: right;
}
.ChangePwd-btn {
border-radius: 24px;
}
}
import './Common.scss';
import './ChangePwd.scss';
import { View, Image, Input, Button } from '@tarojs/components';
import Taro from '@tarojs/taro';
import pwdHideIcon from '../../images/login/setting_invisible_icon@2x.png';
import pwdShowIcon from '../../images/login/setting_see_icon@2x.png';
import { changeAppPassword } from '@/api/customer';
import usePasswordInput from './usePasswordInput';
import { useSelector } from '@tarojs/redux';
import { Customer } from '@/types/Customer/Customer';
const ChangePwd = () => {
const customerId = useSelector(
(state: { userinfo: Customer }) => state.userinfo.customerId,
);
const { pwd, setPwd, showPwd, setShowPwd } = usePasswordInput();
const {
pwd: oldPwd,
setPwd: setOldPwd,
showPwd: showOldPwd,
setShowPwd: setShowOldPwd,
} = usePasswordInput();
const {
pwd: checkPwd,
setPwd: setCheckPwd,
showPwd: showCheckPwd,
setShowPwd: setShowCheckPwd,
} = usePasswordInput();
const changePasswordHandle = () => {
if (!oldPwd || oldPwd.length < 6) {
return Taro.showToast({
title: '请输入6-20位旧密码',
icon: 'none',
});
}
if (!pwd || pwd.length < 6) {
return Taro.showToast({
title: '请输入6-20位新密码',
icon: 'none',
});
}
if (!checkPwd || checkPwd.length < 6 || pwd !== checkPwd) {
return Taro.showToast({
title: '请确认输入密码和新密码完全一致',
icon: 'none',
});
}
Taro.showLoading();
changeAppPassword({
password: pwd,
oldPassword: oldPwd,
customerId: customerId,
})
.then(res => {
Taro.hideLoading();
Taro.showToast({
title: '修改成功',
});
})
.catch(err => {
Taro.hideLoading();
Taro.showToast({
title: err.msg || '修改成功',
icon: 'none',
});
});
};
const goResetpwd = () => {
Taro.navigateTo({
url: '/pages/PassWord/ResetPwd',
});
};
return (
<View className='ChangePwd Password'>
<View className='Password-form'>
<View className='Password-title'>旧密码</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
password={!showOldPwd}
placeholder='请输入当前登录密码'
maxLength={20}
value={oldPwd}
onInput={({ detail: { value } }) => setOldPwd(value)}
/>
<Image
className='registerBox-pwdIcon'
src={showOldPwd ? pwdShowIcon : pwdHideIcon}
onClick={setShowOldPwd}
/>
</View>
<View className='Password-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 } }) => setPwd(value)}
/>
<Image
className='registerBox-pwdIcon'
src={showPwd ? pwdShowIcon : pwdHideIcon}
onClick={setShowPwd}
/>
</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
password={!showCheckPwd}
placeholder='确认6-20位新密码'
maxLength={20}
value={checkPwd}
onInput={({ detail: { value } }) => setCheckPwd(value)}
/>
<Image
className='registerBox-pwdIcon'
src={showCheckPwd ? pwdShowIcon : pwdHideIcon}
onClick={setShowCheckPwd}
/>
</View>
<View className='ChangePwd-forget' onClick={goResetpwd}>
忘记密码?
</View>
<Button className='ChangePwd-btn' onClick={changePasswordHandle}>
确定
</Button>
</View>
</View>
);
};
ChangePwd.config = {
navigationBarTitleText: '登陆密码修改',
};
export default ChangePwd;
.ChangeTelAccount {
.ChangeTelAccount-forget {
margin: 40px auto 60px;
color: #f93d3d;
font-size: 24px;
text-align: right;
}
}
import './Common.scss';
import './ChangeTelAccount.scss';
import { View, Button, Image, Input } from '@tarojs/components';
import Taro, { useState } from '@tarojs/taro';
import { useSelector } from '@tarojs/redux';
import { Customer } from '@/types/Customer/Customer';
import usePasswordInput from './usePasswordInput';
import pwdHideIcon from '../../images/login/setting_invisible_icon@2x.png';
import pwdShowIcon from '../../images/login/setting_see_icon@2x.png';
import useInputValue from '@/hooks/useInputValue';
import Vcode from '@/components/Vcode/Vcode';
import { changePhoneAccount } from '@/api/customer';
const ChangeTelAccount = () => {
const customerId = useSelector(
(state: { userinfo: Customer }) => state.userinfo.customerId,
);
const [vcode, setVcode] = useState('');
const { pwd, setPwd, showPwd, setShowPwd } = usePasswordInput();
const { value: phone, onChange } = useInputValue('');
const goResetpwd = () => {
Taro.navigateTo({
url: '/pages/PassWord/ResetPwd',
});
};
const changeAccountHandle = () => {
if (!pwd || pwd.length < 6) {
return Taro.showToast({
title: '请输入6-20位新密码',
icon: 'none',
});
}
if (!phone || phone.length !== 11) {
return Taro.showToast({
title: '请输入手机号码',
icon: 'none',
});
}
if (!vcode || vcode.length !== 6) {
return Taro.showToast({
title: '请输入6位验证码',
icon: 'none',
});
}
Taro.showLoading();
changePhoneAccount({
customerId: customerId,
password: pwd,
phoneAccount: phone,
verification: vcode,
})
.then(res => {
Taro.hideLoading();
Taro.showToast({
title: '修改成功',
});
})
.catch(err => {
Taro.hideLoading();
Taro.showToast({
title: err.msg || '修改成功',
icon: 'none',
});
});
};
return (
<View className='ChangeTelAccount Password'>
<View className='Password-form'>
<View className='Password-title'>APP登录密码</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
password={!showPwd}
placeholder='请输入当前登录密码'
maxLength={20}
value={pwd}
onInput={({ detail: { value } }) => setPwd(value)}
/>
<Image
className='registerBox-pwdIcon'
src={showPwd ? pwdShowIcon : pwdHideIcon}
onClick={setShowPwd}
/>
</View>
<View className='Password-title'>更换所需手机号</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
placeholder='请输入手机号码'
maxLength={11}
value={phone}
onInput={onChange}
/>
</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
placeholderClass='loginBox-placeholder'
placeholder='请输入验证码'
maxLength={6}
value={vcode}
onInput={({ detail: { value } }) => setVcode(value)}
/>
<Vcode
vcode-classname='registerBox-getVcode'
positionNum='4'
ref='Vcode'
cellphone={phone}
/>
</View>
<View className='ChangeTelAccount-forget' onClick={goResetpwd}>
忘记密码?
</View>
<Button className='ChangePwd-btn' onClick={changeAccountHandle}>
确定
</Button>
</View>
</View>
);
};
ChangeTelAccount.config = {
navigationBarTitleText: '更换手机账户',
};
export default ChangeTelAccount;
.ResetPwd {
.ResetPwd-form {
.Password {
.Password-form {
padding: 0 32px;
}
.ResetPwd-title {
.Password-title {
margin-top: 52px;
margin-bottom: 32px;
font-size: 32px;
}
.ResetPwd-btn {
.Password-btn {
margin: 40px 16px 0;
border-radius: 24px;
}
......
.ResetPwd {
.ResetPwd-btn {
margin: 40px 16px 0;
border-radius: 24px;
}
}
......@@ -6,6 +6,7 @@ import pwdHideIcon from '../../images/login/setting_invisible_icon@2x.png';
import pwdShowIcon from '../../images/login/setting_see_icon@2x.png';
import ToastBox from '../../components/ToastBox/ToastBox';
import './Common.scss';
import './ResetPwd.scss';
import { changePwdByCellphone } from '../../api/customer';
import { replaceIllegalPwd } from '../../utils/pwd';
......@@ -131,10 +132,10 @@ class ResetPwd extends Component {
checkPwd,
} = this.state;
return (
<View className='ResetPwd'>
<View className='ResetPwd Password'>
<ToastBox ref='ToastBox' />
<View className='ResetPwd-form'>
<View className='ResetPwd-title'>请输入您的登陆手机号</View>
<View className='Password-form'>
<View className='Password-title'>请输入您的登陆手机号</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
......@@ -172,7 +173,7 @@ class ResetPwd extends Component {
cellphone={cellphone}
/>
</View>
<View className='ResetPwd-title'>设置新密码</View>
<View className='Password-title'>设置新密码</View>
<View className='registerBox-item'>
<Input
className='loginBox-input'
......
import Taro, { useState, useCallback } from '@tarojs/taro';
import { switchAccountLoginState } from '@/api/customer';
const useAccountLogin = (
customerId: number,
initState: string,
): [boolean, (state: boolean) => void] => {
const [state, setState] = useState(initState === '1' ? true : false);
const setStateHandle = useCallback(
(state: boolean) => {
setState(state);
Taro.showLoading();
switchAccountLoginState({
customerId,
state: state ? '1' : '0',
})
.then(res => {
Taro.hideLoading();
console.log(res);
Taro.showToast({
title: '修改成功',
});
})
.catch(err => {
Taro.hideLoading();
console.log(err);
setState(!state);
Taro.showToast({
title: err.msg || '修改失败',
icon: 'none',
});
});
},
[customerId],
);
return [state, setStateHandle];
};
export default useAccountLogin;
import Taro, { useEffect, useState, useCallback } from '@tarojs/taro';
import {
fetchBalanceState,
switchBalanceState,
BalanceState,
} from '@/api/customer';
const useBalanceState = (
customerId: number,
): [boolean, (state: boolean) => void] => {
const [state, setState] = useState(false);
const getBoolValue = (e: BalanceState): boolean =>
e === BalanceState.open ? true : false;
useEffect(() => {
fetchBalanceState({
customerId,
})
.then(res => {
setState(getBoolValue(res.data));
})
.catch(err => {
console.log(err);
});
}, []);
const switchBalanceStateHandle = (state: BalanceState) => {
Taro.showLoading();
return switchBalanceState({
customerId,
isEnabled: state,
})
.then(res => {
Taro.hideLoading();
console.log(res);
setState(getBoolValue(state));
Taro.showToast({
title: '修改成功',
});
})
.catch(err => {
Taro.hideLoading();
console.log(err);
Taro.showToast({
title: err.msg || '修改失败',
icon: 'none',
});
});
};
const setStateHandle = useCallback(
(state: boolean) => {
setState(state);
if (state) {
Taro.showModal({
title: '提示',
content: '您将切换使用预充值模式,消费时请保证账号又余额',
}).then(res => {
if (res.confirm) {
switchBalanceStateHandle(BalanceState.open).catch(() => {
setState(false);
});
} else {
setState(false);
}
});
} else {
Taro.showModal({
title: '提示',
content: '关闭后将切换至订单单笔支付模式',
}).then(res => {
if (res.confirm) {
switchBalanceStateHandle(BalanceState.close).catch(() => {
setState(true);
});
} else {
setState(true);
}
});
}
},
[customerId],
);
return [state, setStateHandle];
};
export default useBalanceState;
import { useState, useCallback } from '@tarojs/taro';
import { ITouchEvent } from '@tarojs/components/types/common';
type PasswordInput = {
pwd: string;
setPwd: (e: string) => void;
showPwd: boolean;
setShowPwd: (e: ITouchEvent) => void;
};
const usePasswordInput = (): PasswordInput => {
const [pwd, setPwd] = useState('');
const [showPwd, setShowPwd] = useState(false);
const setShowPwdHandle = useCallback(() => {
setShowPwd(showPwd ? false : true);
}, [showPwd]);
return { pwd, setPwd, showPwd, setShowPwd: setShowPwdHandle };
};
export default usePasswordInput;
.CustomerSetting {
padding: 10px 32px;
.CustomerSettingItem {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28px;
line-height: 80px;
color: #333;
.CustomerSetting-icon {
width: 15px;
color: #999;
font-family: serif;
font-weight: bolder;
}
}
.CustomerSettingItem-switch {
zoom: 0.7;
}
.CustomerSetting-buttom {
padding-top: 40px;
}
}
import './CustomerSetting.scss';
import Taro from '@tarojs/taro';
import { View, Text, Switch } from '@tarojs/components';
import { useSelector } from '@tarojs/redux';
import { Customer } from '@/types/Customer/Customer';
import useAccountLogin from '../PassWord/useAccountLogin';
import useBalanceState from '../PassWord/useBalanceState';
const CustomerSetting = () => {
const userinfo = useSelector(
(state: { userinfo: Customer }) => state.userinfo,
);
const goChangePwd = () => {
Taro.navigateTo({
url: '/pages/PassWord/ChangePwd',
});
};
const goChangeAccount = () => {
Taro.navigateTo({
url: '/pages/PassWord/ChangeHardwareAccount',
});
};
const goChangePhoneAccount = () => {
Taro.navigateTo({
url: '/pages/PassWord/ChangeTelAccount',
});
};
const [accountLoginState, setAccountLoginState] = useAccountLogin(
userinfo.customerId,
userinfo.hardwareState,
);
const [balanceState, setBalanceState] = useBalanceState(userinfo.customerId);
return (
<View className='CustomerSetting'>
<View className='CustomerSettingItem' onClick={goChangePwd}>
<Text className='CustomerSettingItem-label'>登录密码修改</Text>
<Text className='CustomerSetting-icon'>></Text>
</View>
<View className='CustomerSettingItem' onClick={goChangeAccount}>
<Text className='CustomerSettingItem-label'>设备密码修改</Text>
<Text className='CustomerSetting-icon'>></Text>
</View>
<View className='CustomerSettingItem' onClick={goChangePhoneAccount}>
<Text className='CustomerSettingItem-label'>更换手机账户</Text>
<Text className='CustomerSetting-icon'>></Text>
</View>
<View className='CustomerSetting-buttom'>
<View className='CustomerSettingItem'>
<Text className='CustomerSettingItem-label'>开启设备登录密码</Text>
<Switch
className='CustomerSettingItem-switch'
color='#6180f4'
checked={accountLoginState}
onChange={e => setAccountLoginState(e.detail.value)}
/>
</View>
<View className='CustomerSettingItem'>
<Text className='CustomerSettingItem-label'>开启系统自动扣费</Text>
<Switch
className='CustomerSettingItem-switch'
color='#6180f4'
checked={balanceState}
onChange={e => setBalanceState(e.detail.value)}
/>
</View>
</View>
</View>
);
};
CustomerSetting.config = {
navigationBarTitleText: '个人设置',
};
export default CustomerSetting;
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