1.对转写文本显示进行重写
This commit is contained in:
parent
561ce68b70
commit
807df7f747
@ -3,7 +3,11 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import yzs from "./business/request.js";
|
import yzs from "./business/request.js";
|
||||||
import styles from './LoginPage.module.css';
|
import styles from './LoginPage.module.css';
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
import { setFlushToken, setAccessToken, setUserInfo, setAgreeAgreement } from "./business/userSlice.js"
|
import {
|
||||||
|
setAccount, setPassword, setVerificationCode,
|
||||||
|
setFlushToken, setAccessToken, setUserInfo, setAgreeAgreement,
|
||||||
|
setSelectInfo,
|
||||||
|
} from "./business/userSlice.js"
|
||||||
import logo from './assets/logo.png';
|
import logo from './assets/logo.png';
|
||||||
import { Container, Tab, Box, Snackbar, Alert, Button } from '@mui/material';
|
import { Container, Tab, Box, Snackbar, Alert, Button } from '@mui/material';
|
||||||
import TabPanel from '@mui/lab/TabPanel';
|
import TabPanel from '@mui/lab/TabPanel';
|
||||||
@ -34,6 +38,7 @@ export default function () {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [cookies, setCookie] = useCookies(['accessToken']);
|
const [cookies, setCookie] = useCookies(['accessToken']);
|
||||||
|
const [firstEnter, setFirstEnter] = useState(true);
|
||||||
const [value, setValue] = useState("1");
|
const [value, setValue] = useState("1");
|
||||||
const [message, setMessage] = useState("");
|
const [message, setMessage] = useState("");
|
||||||
const [openTooltip, setOpenTooltip] = useState(false);
|
const [openTooltip, setOpenTooltip] = useState(false);
|
||||||
@ -59,7 +64,24 @@ export default function () {
|
|||||||
|
|
||||||
// const debug_test = () => {
|
// const debug_test = () => {
|
||||||
// console.log("accessToken", accessToken, yzs.uniqueDeviceIdentifier());
|
// console.log("accessToken", accessToken, yzs.uniqueDeviceIdentifier());
|
||||||
|
// console.log("userExists", yzs.userExists(yzs.uniqueDeviceIdentifier(), account));
|
||||||
|
// testPromiseLoading(2000, "你好").then(v => {
|
||||||
|
// console.log(v);
|
||||||
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
const handleInputChange = (event) => {
|
||||||
|
const { name, value } = event.target;
|
||||||
|
if (name === 'username') {
|
||||||
|
dispatch(setAccount(value));
|
||||||
|
if (firstEnter) setFirstEnter(false);
|
||||||
|
} else if (name === 'password') {
|
||||||
|
dispatch(setPassword(value));
|
||||||
|
} else if (name === 'verification_code') {
|
||||||
|
dispatch(setVerificationCode(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmit = (event) => {
|
const handleSubmit = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let result = null;
|
let result = null;
|
||||||
@ -77,9 +99,9 @@ export default function () {
|
|||||||
yzs.get_user_info(yzs.uniqueDeviceIdentifier(), token).then(info => {
|
yzs.get_user_info(yzs.uniqueDeviceIdentifier(), token).then(info => {
|
||||||
dispatch(setUserInfo(info));
|
dispatch(setUserInfo(info));
|
||||||
yzs.user_select(yzs.uniqueDeviceIdentifier(), token).then(info => {
|
yzs.user_select(yzs.uniqueDeviceIdentifier(), token).then(info => {
|
||||||
|
dispatch(setSelectInfo(info));
|
||||||
navigate("/");
|
navigate("/");
|
||||||
})
|
})
|
||||||
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -121,10 +143,17 @@ export default function () {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<TabPanel value="1" >
|
<TabPanel value="1" >
|
||||||
<DynamicCodeForm udid={yzs.uniqueDeviceIdentifier()} agreeAgreement={agreeAgreement} onAgreeChange={onAgreeChange} />
|
<DynamicCodeForm udid={yzs.uniqueDeviceIdentifier()}
|
||||||
|
firstEnter={firstEnter}
|
||||||
|
agreeAgreement={agreeAgreement} onAgreeChange={onAgreeChange}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value="2" >
|
<TabPanel value="2" >
|
||||||
<PasswordForm agreeAgreement={agreeAgreement} onAgreeChange={onAgreeChange} />
|
<PasswordForm firstEnter={firstEnter}
|
||||||
|
agreeAgreement={agreeAgreement} onAgreeChange={onAgreeChange}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabContext>
|
</TabContext>
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { React, useEffect, useState } from 'react';
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
import AppBar from './AppBar';
|
import AppBar from './AppBar';
|
||||||
import RecordList from './components/RecordList';
|
import RecordList from './components/RecordList';
|
||||||
@ -7,6 +7,7 @@ import store from './business/store';
|
|||||||
import yzs from "./business/request.js";
|
import yzs from "./business/request.js";
|
||||||
import { setList, setCurrentLyric, setCurrentBlob, setCurrentWaveData } from "./business/recorderSlice.js"
|
import { setList, setCurrentLyric, setCurrentBlob, setCurrentWaveData } from "./business/recorderSlice.js"
|
||||||
import { CssBaseline, Box } from '@mui/material';
|
import { CssBaseline, Box } from '@mui/material';
|
||||||
|
import MainSkeleton from './MainSkeleton';
|
||||||
import RecordLyrics from './RecordLyrics';
|
import RecordLyrics from './RecordLyrics';
|
||||||
import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
|
import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
|
||||||
import expand from './assets/expand.png';
|
import expand from './assets/expand.png';
|
||||||
@ -104,6 +105,19 @@ const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const RecordPlayer = ({ loading, playerBarWidth, currentTime, hasLyric, currentLyric }) => {
|
||||||
|
if (loading) {
|
||||||
|
return <MainSkeleton />
|
||||||
|
} else {
|
||||||
|
return <div>
|
||||||
|
<PlayerBar width={playerBarWidth} currentTime={currentTime} />
|
||||||
|
{hasLyric ? <RecordLyrics style={lyricsBrowserStyle} currentLyric={currentLyric} currentTime={currentTime} /> :
|
||||||
|
<div style={lyricsBrowserStyle}
|
||||||
|
/>}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const accessToken = useSelector(state => state.user.accessToken);
|
const accessToken = useSelector(state => state.user.accessToken);
|
||||||
@ -112,15 +126,16 @@ export default function () {
|
|||||||
const currentLyric = useSelector(state => state.recorder.currentLyric);
|
const currentLyric = useSelector(state => state.recorder.currentLyric);
|
||||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||||
const recordList = useSelector(state => state.recorder.list);
|
const recordList = useSelector(state => state.recorder.list);
|
||||||
|
const loading = useSelector(state => state.recorder.loading);
|
||||||
const [playerBarWidth, setPlayerBarWidth] = useState(0);
|
const [playerBarWidth, setPlayerBarWidth] = useState(0);
|
||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
const [hasLyric, setHasLyric] = useState(true);
|
const [hasLyric, setHasLyric] = useState(true);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (passportId <= 0) return;
|
if (passportId <= 0) return;
|
||||||
yzs.get_record_list(accessToken, passportId).then(list => {
|
yzs.get_record_list(accessToken, passportId).then(list => {
|
||||||
dispatch(setList(list.result));
|
dispatch(setList(list));
|
||||||
if (list.result.length > 0) {
|
if (list.length > 0) {
|
||||||
fetchRecord(accessToken, list.result.at(0));
|
fetchRecord(accessToken, list.at(0));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.log("get list failed", error);
|
console.log("get list failed", error);
|
||||||
@ -168,10 +183,8 @@ export default function () {
|
|||||||
<Main open={open}
|
<Main open={open}
|
||||||
onTransitionEnd={onTransitionEnd}
|
onTransitionEnd={onTransitionEnd}
|
||||||
>
|
>
|
||||||
<PlayerBar width={playerBarWidth} currentTime={currentTime} />
|
<RecordPlayer loading={loading}
|
||||||
{hasLyric ? <RecordLyrics style={lyricsBrowserStyle} currentLyric={currentLyric} currentTime={currentTime} /> :
|
playerBarWidth={playerBarWidth} currentTime={currentTime} hasLyric={hasLyric} currentLyric={currentLyric} />
|
||||||
<div style={lyricsBrowserStyle}
|
|
||||||
/>}
|
|
||||||
</Main>
|
</Main>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</Box >
|
</Box >
|
||||||
|
34
src/MainSkeleton.js
Normal file
34
src/MainSkeleton.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import Stack from '@mui/material/Stack';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Skeleton from '@mui/material/Skeleton';
|
||||||
|
import { Container } from '@mui/material';
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return (
|
||||||
|
<Box spacing={1} sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
// justifyContent: "space-between",
|
||||||
|
height: `calc(100vh - 48px)`,
|
||||||
|
}}>
|
||||||
|
<Skeleton variant="text" sx={{ fontSize: '1rem' }} />
|
||||||
|
<Container disableGutters maxWidth={false} sx={{
|
||||||
|
height: 60,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginTop: 2,
|
||||||
|
marginBottom: 0.5,
|
||||||
|
}}>
|
||||||
|
<Skeleton variant="rounded" width={"30%"} height={60} />
|
||||||
|
<Skeleton variant="circular" width={30} height={30} />
|
||||||
|
</Container>
|
||||||
|
{/* For variant="text", adjust the height via font-size */}
|
||||||
|
|
||||||
|
{/* For other variants, adjust the size with `width` and `height` */}
|
||||||
|
<Skeleton variant="rounded" animation="wave" width="100%" height={70} sx={{ marginBottom: 0.5 }} />
|
||||||
|
<Skeleton variant="rounded" animation="wave" width="100%" height={32} sx={{ marginBottom: 2 }} />
|
||||||
|
<Skeleton variant="rounded" width="100%" sx={{ marginBottom: 2, flexGrow: 1 }} />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
@ -20,6 +20,7 @@ const durationFormat = (time) => {
|
|||||||
export default function ({ width, currentTime }) {
|
export default function ({ width, currentTime }) {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [duration, setDuration] = useState(0); // 秒,有小数点
|
const [duration, setDuration] = useState(0); // 秒,有小数点
|
||||||
|
const [playbackRate, setPlaybackRate] = useState(1.0);
|
||||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||||
const recordList = useSelector(state => state.recorder.list);
|
const recordList = useSelector(state => state.recorder.list);
|
||||||
const currentBlob = useSelector(state => state.recorder.currentBlob);
|
const currentBlob = useSelector(state => state.recorder.currentBlob);
|
||||||
@ -28,6 +29,7 @@ export default function ({ width, currentTime }) {
|
|||||||
const player = useRef(null);
|
const player = useRef(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
player.current.url = currentBlob
|
player.current.url = currentBlob
|
||||||
|
setPlaybackRate(1.0); // 恢复默认
|
||||||
console.log(player.current.url);
|
console.log(player.current.url);
|
||||||
}, [currentBlob]);
|
}, [currentBlob]);
|
||||||
|
|
||||||
@ -66,6 +68,7 @@ export default function ({ width, currentTime }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onChange = (event) => {
|
const onChange = (event) => {
|
||||||
|
setPlaybackRate(event.target.value);
|
||||||
player.current.playbackRate = event.target.value;
|
player.current.playbackRate = event.target.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -107,7 +110,7 @@ export default function ({ width, currentTime }) {
|
|||||||
waveData={currentWaveData}
|
waveData={currentWaveData}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={1.0}
|
value={playbackRate}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
sx={{ width: 90, height: 70 }}
|
sx={{ width: 90, height: 70 }}
|
||||||
>
|
>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useMemo } from "react";
|
||||||
import { Typography, Paper } from "@mui/material";
|
import { Typography, Paper } from "@mui/material";
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
|
|
||||||
@ -7,17 +7,56 @@ function isHighlight(currentTime, { start, end }) {
|
|||||||
return (currentTime > start) && (currentTime <= end);
|
return (currentTime > start) && (currentTime <= end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// type: 0 --> 声文速记 纯文本,已适配
|
||||||
|
// type: 1 --> 导入音频
|
||||||
|
// type: 2 --> 同传翻译 纯文本,已适配
|
||||||
|
// type: 3 --> 双语对话
|
||||||
|
|
||||||
|
const PlainText = ({ lyrics }) => {
|
||||||
|
return <div style={{ whiteSpace: "pre-wrap" }}>{lyrics}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImportAudio = ({ lyrics, currentTime }) => { // 导入音频
|
||||||
|
const onClick = (index) => {
|
||||||
|
console.log("onClick", index);
|
||||||
|
}
|
||||||
|
return <div>{lyrics.map((lyric, index) => {
|
||||||
|
return <div style={{ paddingBottom: 10, display: "inline-block" }} onDoubleClick={() => onClick(index)}>
|
||||||
|
<Typography align="left" color={isHighlight(currentTime, lyric) ? "red" : "black"}>{lyric.text}</Typography>
|
||||||
|
</div>
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
};
|
||||||
|
|
||||||
|
const BilingualDialogue = ({ lyrics }) => { // 双语对话
|
||||||
|
return <div> {lyrics.map((lyric, index) => {
|
||||||
|
return <div index={index} style={{ paddingBottom: 40 }}>
|
||||||
|
<Typography align="left" >{lyric.asr}</Typography>
|
||||||
|
<Typography align="left" >{lyric.translate}</Typography>
|
||||||
|
</div>
|
||||||
|
})}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const LyricsContent = ({ type, lyrics, currentTime }) => {
|
||||||
|
if (type === 0 || type === 2) {
|
||||||
|
return <PlainText lyrics={lyrics} />
|
||||||
|
} else if (type === 1) {
|
||||||
|
return <ImportAudio lyrics={lyrics} currentTime={currentTime} />
|
||||||
|
} else if (type === 3) {
|
||||||
|
return <BilingualDialogue lyrics={lyrics} />
|
||||||
|
} else {
|
||||||
|
return <React.Fragment />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function ({ style, currentLyric, currentTime }) {
|
export default function ({ style, currentLyric, currentTime }) {
|
||||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||||
const recordList = useSelector(state => state.recorder.list);
|
const recordList = useSelector(state => state.recorder.list);
|
||||||
|
const currentType = useMemo(() => {
|
||||||
if (recordList.length === 0) return <React.Fragment />;
|
if (recordList.length <= 0) return -1;
|
||||||
|
return recordList.at(currentIndex).type;
|
||||||
|
}, [currentLyric]);
|
||||||
return <Paper style={style}>
|
return <Paper style={style}>
|
||||||
{recordList.at(currentIndex).type === 1 ? (typeof currentLyric === "object" ? currentLyric.map((lyric, index) => {
|
<LyricsContent type={currentType} lyrics={currentLyric} currentTime={currentTime} />
|
||||||
return <div style={{ paddingBottom: 40 }}>
|
|
||||||
<Typography align="left" color={isHighlight(currentTime, lyric) ? "red" : "black"}>{lyric.text}</Typography>
|
|
||||||
</div>
|
|
||||||
}) : <React.Fragment />) : <div style={{ whiteSpace: "pre-wrap" }}>{typeof currentLyric === "string" ? currentLyric : ""}</div>}
|
|
||||||
</Paper>
|
</Paper>
|
||||||
}
|
}
|
@ -15,6 +15,7 @@ export const recorderSlice = createSlice({
|
|||||||
currentWaveData: [],
|
currentWaveData: [],
|
||||||
currentTime: 0, // 当前音频播放时间
|
currentTime: 0, // 当前音频播放时间
|
||||||
pause: true,
|
pause: true,
|
||||||
|
loading: false,
|
||||||
},
|
},
|
||||||
reducers: {
|
reducers: {
|
||||||
setList: (state, action) => {
|
setList: (state, action) => {
|
||||||
@ -41,11 +42,35 @@ export const recorderSlice = createSlice({
|
|||||||
},
|
},
|
||||||
setPauseState: (state, action) => {
|
setPauseState: (state, action) => {
|
||||||
state.pause = action.payload;
|
state.pause = action.payload;
|
||||||
}
|
},
|
||||||
|
setLoading: (state, action) => {
|
||||||
|
state.loading = true;
|
||||||
|
},
|
||||||
|
setLoadFinished: (state, action) => {
|
||||||
|
state.loading = false;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Action creators are generated for each case reducer function
|
// Action creators are generated for each case reducer function
|
||||||
export const { setCurrentIndex, setList, setCurrentLyric, setCurrentBlob, togglePauseState, setPauseState, setCurrentTime, setCurrentWaveData } = recorderSlice.actions
|
export const {
|
||||||
|
setCurrentIndex, setList, setCurrentLyric, setCurrentBlob, togglePauseState, setPauseState, setCurrentTime,
|
||||||
|
setCurrentWaveData,
|
||||||
|
setLoading,
|
||||||
|
setLoadFinished,
|
||||||
|
} = recorderSlice.actions
|
||||||
|
|
||||||
export default recorderSlice.reducer
|
export default recorderSlice.reducer
|
||||||
|
|
||||||
|
const fecthRecord = (index) => {
|
||||||
|
console.log("begin fetch record item", index);
|
||||||
|
return (dispatch) => {
|
||||||
|
dispatch(setLoading());
|
||||||
|
// testPromiseLoading(2000, true).then(e => {
|
||||||
|
// console.log("end fetch record item", index);
|
||||||
|
// dispatch(setLoadFinished());
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { fecthRecord };
|
@ -139,8 +139,11 @@ const yzs = {
|
|||||||
if (json.errorCode !== "0") {
|
if (json.errorCode !== "0") {
|
||||||
throw json;
|
throw json;
|
||||||
}
|
}
|
||||||
console.log(json)
|
let list = json.result;
|
||||||
return json;
|
list.sort((lfs, rhs) => { // 要求倒序排序
|
||||||
|
return rhs.modifyTime - lfs.modifyTime;
|
||||||
|
})
|
||||||
|
return list;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
download: function (accessToken, url) {
|
download: function (accessToken, url) {
|
||||||
@ -234,6 +237,31 @@ const yzs = {
|
|||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
userExists: function (udid, account) {
|
||||||
|
let body = {};
|
||||||
|
body.subsystemId = 16;
|
||||||
|
body.clientId = udid;
|
||||||
|
body.timestamp = Math.round(new Date().getTime() / 1000);
|
||||||
|
body.account = account;
|
||||||
|
return fetch("/rest/v2/user/is_user_exist", {
|
||||||
|
method: "POST",
|
||||||
|
body: constructParameter(body),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||||
|
},
|
||||||
|
}).then(response => response.json()).then((json) => {
|
||||||
|
console.log("userExists: ", json);
|
||||||
|
if (json.returnCode === "uc_0206") { // 用户已存在
|
||||||
|
return true;
|
||||||
|
} else if (json.returnCode === "uc_0205") {// 用户不存在
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
throw json;
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
uniqueDeviceIdentifier: function () {
|
uniqueDeviceIdentifier: function () {
|
||||||
let udid = localStorage.getItem('uniqueDeviceIdentifier');
|
let udid = localStorage.getItem('uniqueDeviceIdentifier');
|
||||||
if (!udid) {
|
if (!udid) {
|
||||||
|
@ -3,29 +3,16 @@ import React, { useState, useEffect, useRef } from 'react';
|
|||||||
import PhoneIphoneIcon from '@mui/icons-material/PhoneIphone';
|
import PhoneIphoneIcon from '@mui/icons-material/PhoneIphone';
|
||||||
import LockIcon from '@mui/icons-material/Lock';
|
import LockIcon from '@mui/icons-material/Lock';
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
import { setAccount, setVerificationCode } from "../business/userSlice.js"
|
|
||||||
import yzs from "../business/request.js";
|
import yzs from "../business/request.js";
|
||||||
import Agreement from "./Agreement.js";
|
import Agreement from "./Agreement.js";
|
||||||
import { validatePhoneNumber, textHintOfValidatePhoneNumber } from "../business/utilities.js"
|
import { validatePhoneNumber, textHintOfValidatePhoneNumber } from "../business/utilities.js"
|
||||||
|
|
||||||
export default function ({ udid, agreeAgreement, onAgreeChange }) {
|
export default function ({ udid, firstEnter, onChange, agreeAgreement, onAgreeChange }) {
|
||||||
const dispatch = useDispatch();
|
|
||||||
const code = useRef(null);
|
const code = useRef(null);
|
||||||
const [firstEnter, setFirstEnter] = useState(true);
|
|
||||||
const [seconds, setSeconds] = useState(0); // 倒计时
|
const [seconds, setSeconds] = useState(0); // 倒计时
|
||||||
|
|
||||||
const account = useSelector(state => state.user.account)
|
const account = useSelector(state => state.user.account)
|
||||||
const verificationCode = useSelector(state => state.user.verificationCode)
|
const verificationCode = useSelector(state => state.user.verificationCode)
|
||||||
|
|
||||||
const handleInputChange = (event) => {
|
|
||||||
const { name, value } = event.target;
|
|
||||||
if (name === 'username') {
|
|
||||||
dispatch(setAccount(value));
|
|
||||||
if (firstEnter) setFirstEnter(false);
|
|
||||||
}
|
|
||||||
if (name === 'password') dispatch(setVerificationCode(value));
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = window.setInterval(() => {
|
const timer = window.setInterval(() => {
|
||||||
if (seconds > 0) {
|
if (seconds > 0) {
|
||||||
@ -64,7 +51,7 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
|
|||||||
fullWidth
|
fullWidth
|
||||||
error={firstEnter ? false : !validatePhoneNumber(account)}
|
error={firstEnter ? false : !validatePhoneNumber(account)}
|
||||||
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
|
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
|
||||||
onChange={handleInputChange}
|
onChange={onChange}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
@ -82,14 +69,14 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
|
|||||||
}}
|
}}
|
||||||
hiddenLabel
|
hiddenLabel
|
||||||
fullWidth
|
fullWidth
|
||||||
name="password"
|
name="verification_code"
|
||||||
placeholder="请输入验证码"
|
placeholder="请输入验证码"
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
size="small"
|
size="small"
|
||||||
value={verificationCode}
|
value={verificationCode}
|
||||||
onChange={handleInputChange}
|
onChange={onChange}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
@ -121,7 +108,7 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
注册/登录
|
登录
|
||||||
</Button>
|
</Button>
|
||||||
<Agreement agree={agreeAgreement} onChange={onAgreeChange} />
|
<Agreement agree={agreeAgreement} onChange={onAgreeChange} />
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -3,23 +3,12 @@ import { Container, TextField, Button, InputAdornment } from "@mui/material";
|
|||||||
import PhoneIphoneIcon from '@mui/icons-material/PhoneIphone';
|
import PhoneIphoneIcon from '@mui/icons-material/PhoneIphone';
|
||||||
import LockIcon from '@mui/icons-material/Lock';
|
import LockIcon from '@mui/icons-material/Lock';
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
import { setAccount, setPassword } from "../business/userSlice.js"
|
|
||||||
import Agreement from './Agreement.js';
|
import Agreement from './Agreement.js';
|
||||||
import { validatePhoneNumber, textHintOfValidatePhoneNumber } from "../business/utilities.js"
|
import { validatePhoneNumber, textHintOfValidatePhoneNumber } from "../business/utilities.js"
|
||||||
|
|
||||||
export default function ({ agreeAgreement, onAgreeChange }) {
|
export default function ({ firstEnter, onChange, agreeAgreement, onAgreeChange }) {
|
||||||
const dispatch = useDispatch();
|
|
||||||
const account = useSelector(state => state.user.account)
|
const account = useSelector(state => state.user.account)
|
||||||
const password = useSelector(state => state.user.password)
|
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 (firstEnter) setFirstEnter(false);
|
|
||||||
}
|
|
||||||
if (name === 'password') dispatch(setPassword(value));
|
|
||||||
};
|
|
||||||
|
|
||||||
return <Container disableGutters={true}
|
return <Container disableGutters={true}
|
||||||
sx={{
|
sx={{
|
||||||
@ -38,7 +27,7 @@ export default function ({ agreeAgreement, onAgreeChange }) {
|
|||||||
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
|
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
|
||||||
value={account}
|
value={account}
|
||||||
fullWidth
|
fullWidth
|
||||||
onChange={handleInputChange}
|
onChange={onChange}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
@ -63,7 +52,7 @@ export default function ({ agreeAgreement, onAgreeChange }) {
|
|||||||
variant="outlined"
|
variant="outlined"
|
||||||
size="small"
|
size="small"
|
||||||
value={password}
|
value={password}
|
||||||
onChange={handleInputChange}
|
onChange={onChange}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
|
@ -8,7 +8,7 @@ import ListItemButton from '@mui/material/ListItemButton';
|
|||||||
import ListItemText from '@mui/material/ListItemText';
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import Toolbar from '@mui/material/Toolbar';
|
import Toolbar from '@mui/material/Toolbar';
|
||||||
import { setCurrentIndex } from "../business/recorderSlice.js"
|
import { setCurrentIndex, fecthRecord } from "../business/recorderSlice.js"
|
||||||
import AccessTimeFilledIcon from '@mui/icons-material/AccessTimeFilled';
|
import AccessTimeFilledIcon from '@mui/icons-material/AccessTimeFilled';
|
||||||
|
|
||||||
const drawerWidth = 240;
|
const drawerWidth = 240;
|
||||||
@ -20,6 +20,7 @@ export default function ({ open, recordList, currentIndex, fetchRecord }) {
|
|||||||
console.log("onSelected", index, recordList.at(index).transResultUrl)
|
console.log("onSelected", index, recordList.at(index).transResultUrl)
|
||||||
dispatch(setCurrentIndex(index));
|
dispatch(setCurrentIndex(index));
|
||||||
fetchRecord(accessToken, recordList.at(index));
|
fetchRecord(accessToken, recordList.at(index));
|
||||||
|
dispatch(fecthRecord(index));
|
||||||
}
|
}
|
||||||
return <Drawer
|
return <Drawer
|
||||||
variant="persistent"
|
variant="persistent"
|
||||||
@ -40,9 +41,13 @@ export default function ({ open, recordList, currentIndex, fetchRecord }) {
|
|||||||
{recordList === undefined ? <React.Fragment /> : recordList.map((item, index) => (
|
{recordList === undefined ? <React.Fragment /> : recordList.map((item, index) => (
|
||||||
<ListItem key={index} disablePadding>
|
<ListItem key={index} disablePadding>
|
||||||
<ListItemButton selected={currentIndex === index} onClick={(event) => onSelected(event, index)}>
|
<ListItemButton selected={currentIndex === index} onClick={(event) => onSelected(event, index)}>
|
||||||
<ListItemText primary={item.editName} secondary={
|
<ListItemText primary={item.editName} sx={{ color: currentIndex === index ? "#FF595A" : "#000000" }} secondary={
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Typography component="span" variant="body1">{item.content.slice(0, 50) + '......'}</Typography>
|
<Typography component="span" variant="body1"
|
||||||
|
sx={{
|
||||||
|
overflowWrap: "anywhere"
|
||||||
|
}}
|
||||||
|
>{item.content.slice(0, 50) + '......'}</Typography>
|
||||||
<br />
|
<br />
|
||||||
<AccessTimeFilledIcon sx={{ fontSize: 12 }} />
|
<AccessTimeFilledIcon sx={{ fontSize: 12 }} />
|
||||||
<Typography component="span" variant="body2"> 更新于 {new Date(item.createTime).toLocaleString()}</Typography>
|
<Typography component="span" variant="body2"> 更新于 {new Date(item.createTime).toLocaleString()}</Typography>
|
||||||
|
@ -9,6 +9,14 @@ const server = "https://ai-api.hivoice.cn";
|
|||||||
const accessServer = "https://uc.hivoice.cn";
|
const accessServer = "https://uc.hivoice.cn";
|
||||||
|
|
||||||
module.exports = function (app) {
|
module.exports = function (app) {
|
||||||
|
app.use(
|
||||||
|
'/rest/v2/user/is_user_exist',
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: accessServer,
|
||||||
|
changeOrigin: true,
|
||||||
|
logger: console,
|
||||||
|
})
|
||||||
|
);
|
||||||
app.use(
|
app.use(
|
||||||
'/rest/v2/phone/login',
|
'/rest/v2/phone/login',
|
||||||
createProxyMiddleware({
|
createProxyMiddleware({
|
||||||
|
Loading…
Reference in New Issue
Block a user