1.实现手机号码校验提示 和登录返回错误提示

This commit is contained in:
amass 2023-06-21 16:19:29 +08:00
parent 16bc07d970
commit f30bf34432
6 changed files with 104 additions and 44 deletions

View File

@ -5,7 +5,7 @@ import styles from './LoginPage.module.css';
import { useSelector, useDispatch } from 'react-redux'
import { setFlushToken, setAccessToken, setUserInfo, setAgreeAgreement } from "./business/userSlice.js"
import logo from './assets/logo.png';
import { Container, Tab, Box, Snackbar, Button } from '@mui/material';
import { Container, Tab, Box, Snackbar, Alert, Button } from '@mui/material';
import TabPanel from '@mui/lab/TabPanel';
import { TabList } from '@mui/lab';
import TabContext from '@mui/lab/TabContext';
@ -35,6 +35,8 @@ export default function () {
const dispatch = useDispatch();
const [cookies, setCookie] = useCookies(['accessToken']);
const [value, setValue] = useState("1");
const [message, setMessage] = useState("");
const [openTooltip, setOpenTooltip] = useState(false);
const account = useSelector(state => state.user.account)
const password = useSelector(state => state.user.password)
const verificationCode = useSelector(state => state.user.verificationCode)
@ -44,6 +46,10 @@ export default function () {
setValue(newValue);
};
const handleTooltipClose = () => {
setOpenTooltip(false);
};
const onAgreeChange = (event) => {
dispatch(setAgreeAgreement(!agreeAgreement));
}
@ -78,6 +84,8 @@ export default function () {
})
}).catch(error => {
console.log(error)
setMessage(error);
setOpenTooltip(true);
});
};
@ -123,12 +131,13 @@ export default function () {
</ThemeProvider >
{/* <Button variant="contained" onClick={debug_test}>测试</Button> */}
</div>
{/* <Snackbar
anchorOrigin={{ vertical, horizontal }}
open={open}
onClose={handleClose}
message="I love snacks"
key={vertical + horizontal}
/> */}
<Snackbar
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
open={openTooltip}
autoHideDuration={3500}
onClose={handleTooltipClose}
>
<Alert severity="error">{message}</Alert>
</Snackbar>
</div>
}

View File

@ -206,10 +206,11 @@ const yzs = {
"Access-Control-Allow-Origin": "*",
},
}).then(response => response.json()).then((json) => {
console.log("flushToken: ", json.result.flushToken);
if (json.returnCode != "uc_0000") {
throw json.message;
}
// console.log("flushToken: ", json.result.flushToken);
return json.result.flushToken;
}).catch(error => {
console.log(error);
});
},
send_phone_code: function (udid, userCell) {

View File

@ -33,4 +33,18 @@ function audioWaveData(url, interval) {
});
}
export { sampleInterval, audioWaveData };
function validatePhoneNumber(phoneNumber) {
if (phoneNumber.length !== 11) {
return false;
}
let reg = /^1\d{10}$/;
return reg.test(phoneNumber);
}
function textHintOfValidatePhoneNumber(phoneNumber) {
if (validatePhoneNumber(phoneNumber)) return "";
if (phoneNumber.length === 0) return "请输入手机号码"
return "请输入正确的手机号码";
}
export { sampleInterval, audioWaveData, validatePhoneNumber, textHintOfValidatePhoneNumber };

View File

@ -6,10 +6,12 @@ import { useSelector, useDispatch } from 'react-redux'
import { setAccount, setVerificationCode } from "../business/userSlice.js"
import yzs from "../business/request.js";
import Agreement from "./Agreement.js";
import { validatePhoneNumber, textHintOfValidatePhoneNumber } from "../business/utilities.js"
export default function ({ udid, agreeAgreement, onAgreeChange }) {
const dispatch = useDispatch();
const code = useRef(null);
const [firstEnter, setFirstEnter] = useState(true);
const [seconds, setSeconds] = useState(0); // 倒计时
const account = useSelector(state => state.user.account)
@ -17,7 +19,10 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
const handleInputChange = (event) => {
const { name, value } = event.target;
if (name === 'username') dispatch(setAccount(value));
if (name === 'username') {
dispatch(setAccount(value));
if (firstEnter) setFirstEnter(false);
}
if (name === 'password') dispatch(setVerificationCode(value));
};
@ -50,11 +55,15 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
<TextField
name="username"
autoComplete="username"
label="请输入手机号码"
hiddenLabel
placeholder="请输入手机号码"
variant="outlined"
value={account}
color="primary"
size="small"
fullWidth
error={firstEnter ? false : !validatePhoneNumber(account)}
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
onChange={handleInputChange}
InputProps={{
startAdornment: (
@ -63,16 +72,22 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
</InputAdornment>
),
}}
sx={{
minHeight: 64,
}}
/>
<TextField
// sx={{ paddingTop: 4 }}
sx={{
minHeight: 50,
}}
hiddenLabel
fullWidth
margin="normal"
name="password"
label="请输入验证码"
type="password"
placeholder="请输入验证码"
type="text"
autoComplete="current-password"
variant="outlined"
size="small"
value={verificationCode}
onChange={handleInputChange}
InputProps={{
@ -96,6 +111,7 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
fullWidth
disabled={!agreeAgreement}
sx={{
marginTop: 1.5,
backgroundColor: "#FF595A",
'&:hover': {
backgroundColor: '#FF595A',

View File

@ -1,18 +1,23 @@
import React from 'react';
import React, { useState } from 'react';
import { Container, TextField, Button, InputAdornment } from "@mui/material";
import PhoneIphoneIcon from '@mui/icons-material/PhoneIphone';
import LockIcon from '@mui/icons-material/Lock';
import { useSelector, useDispatch } from 'react-redux'
import { setAccount, setPassword } from "../business/userSlice.js"
import Agreement from './Agreement.js';
import { validatePhoneNumber, textHintOfValidatePhoneNumber } from "../business/utilities.js"
export default function ({ agreeAgreement, onAgreeChange }) {
const dispatch = useDispatch();
const account = useSelector(state => state.user.account)
const password = useSelector(state => state.user.password)
const [firstEnter, setFirstEnter] = useState(true);
const handleInputChange = (event) => {
const { name, value } = event.target;
if (name === 'username') dispatch(setAccount(value));
if (name === 'username') {
dispatch(setAccount(value));
if (firstEnter) setFirstEnter(false);
}
if (name === 'password') dispatch(setPassword(value));
};
@ -25,8 +30,12 @@ export default function ({ agreeAgreement, onAgreeChange }) {
<TextField
name="username"
autoComplete="username"
label="请输入手机号码"
hiddenLabel
placeholder="请输入手机号码"
variant="outlined"
size="small"
error={firstEnter ? false : !validatePhoneNumber(account)}
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
value={account}
fullWidth
onChange={handleInputChange}
@ -37,16 +46,22 @@ export default function ({ agreeAgreement, onAgreeChange }) {
</InputAdornment>
),
}}
sx={{
minHeight: 64,
}}
/>
<TextField
// sx={{ paddingTop: 4 }}
sx={{
minHeight: 50,
}}
fullWidth
margin="normal"
name="password"
label="请输入密码"
hiddenLabel
placeholder="请输入密码"
type="password"
autoComplete="current-password"
variant="outlined"
size="small"
value={password}
onChange={handleInputChange}
InputProps={{
@ -64,6 +79,7 @@ export default function ({ agreeAgreement, onAgreeChange }) {
fullWidth
disabled={!agreeAgreement}
sx={{
marginTop: 1.5,
backgroundColor: "#FF595A",
'&:hover': {
backgroundColor: '#FF595A',

View File

@ -58,28 +58,32 @@ const paintCanvas = ({
canvas, waveformData, duration, scrollLeft, leftPadding, canvasHeight, pointWidth, pointMargin, interval
}) => {
// console.log("paintCanvas", duration, canvasHeight, canvas.width, scrollLeft);
const context = canvas.getContext('2d');
context.save();
context.clearRect(0, 0, canvas.width, canvas.height);
context.translate(leftPadding, 0);;
try {
const context = canvas.getContext('2d');
context.save();
context.clearRect(0, 0, canvas.width, canvas.height);
context.translate(leftPadding, 0);;
drawText(context, duration, interval); // 画刻度尺
drawText(context, duration, interval); // 画刻度尺
waveformData.forEach((p, i) => {
context.beginPath()
const coordinates = pointCoordinates({
index: i,
pointWidth,
pointMargin,
canvasHeight,
maxAmplitude: canvasHeight - 30, // 留出空间画时间轴
amplitude: p,
})
context.rect(...coordinates)
context.fillStyle = (coordinates[0] <= scrollLeft) ? '#FF595A' : '#ABB5BC'
context.fill()
});
context.restore();
waveformData.forEach((p, i) => {
context.beginPath()
const coordinates = pointCoordinates({
index: i,
pointWidth,
pointMargin,
canvasHeight,
maxAmplitude: canvasHeight - 30, // 留出空间画时间轴
amplitude: p,
})
context.rect(...coordinates)
context.fillStyle = (coordinates[0] <= scrollLeft) ? '#FF595A' : '#ABB5BC'
context.fill()
});
context.restore();
} catch (error) {
console.log(error);
}
}
// duration ms