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 styles from './LoginPage.module.css';
|
||||
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 { Container, Tab, Box, Snackbar, Alert, Button } from '@mui/material';
|
||||
import TabPanel from '@mui/lab/TabPanel';
|
||||
@ -34,6 +38,7 @@ export default function () {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const [cookies, setCookie] = useCookies(['accessToken']);
|
||||
const [firstEnter, setFirstEnter] = useState(true);
|
||||
const [value, setValue] = useState("1");
|
||||
const [message, setMessage] = useState("");
|
||||
const [openTooltip, setOpenTooltip] = useState(false);
|
||||
@ -59,7 +64,24 @@ export default function () {
|
||||
|
||||
// const debug_test = () => {
|
||||
// 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) => {
|
||||
event.preventDefault();
|
||||
let result = null;
|
||||
@ -77,9 +99,9 @@ export default function () {
|
||||
yzs.get_user_info(yzs.uniqueDeviceIdentifier(), token).then(info => {
|
||||
dispatch(setUserInfo(info));
|
||||
yzs.user_select(yzs.uniqueDeviceIdentifier(), token).then(info => {
|
||||
dispatch(setSelectInfo(info));
|
||||
navigate("/");
|
||||
})
|
||||
|
||||
});
|
||||
})
|
||||
}).catch(error => {
|
||||
@ -121,10 +143,17 @@ export default function () {
|
||||
</Box>
|
||||
|
||||
<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 value="2" >
|
||||
<PasswordForm agreeAgreement={agreeAgreement} onAgreeChange={onAgreeChange} />
|
||||
<PasswordForm firstEnter={firstEnter}
|
||||
agreeAgreement={agreeAgreement} onAgreeChange={onAgreeChange}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
</TabPanel>
|
||||
</TabContext>
|
||||
</Container>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { React, useEffect, useState } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import AppBar from './AppBar';
|
||||
import RecordList from './components/RecordList';
|
||||
@ -7,6 +7,7 @@ import store from './business/store';
|
||||
import yzs from "./business/request.js";
|
||||
import { setList, setCurrentLyric, setCurrentBlob, setCurrentWaveData } from "./business/recorderSlice.js"
|
||||
import { CssBaseline, Box } from '@mui/material';
|
||||
import MainSkeleton from './MainSkeleton';
|
||||
import RecordLyrics from './RecordLyrics';
|
||||
import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
|
||||
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 () {
|
||||
const dispatch = useDispatch()
|
||||
const accessToken = useSelector(state => state.user.accessToken);
|
||||
@ -112,15 +126,16 @@ export default function () {
|
||||
const currentLyric = useSelector(state => state.recorder.currentLyric);
|
||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||
const recordList = useSelector(state => state.recorder.list);
|
||||
const loading = useSelector(state => state.recorder.loading);
|
||||
const [playerBarWidth, setPlayerBarWidth] = useState(0);
|
||||
const [open, setOpen] = useState(true);
|
||||
const [hasLyric, setHasLyric] = useState(true);
|
||||
useEffect(() => {
|
||||
if (passportId <= 0) return;
|
||||
yzs.get_record_list(accessToken, passportId).then(list => {
|
||||
dispatch(setList(list.result));
|
||||
if (list.result.length > 0) {
|
||||
fetchRecord(accessToken, list.result.at(0));
|
||||
dispatch(setList(list));
|
||||
if (list.length > 0) {
|
||||
fetchRecord(accessToken, list.at(0));
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log("get list failed", error);
|
||||
@ -168,10 +183,8 @@ export default function () {
|
||||
<Main open={open}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
>
|
||||
<PlayerBar width={playerBarWidth} currentTime={currentTime} />
|
||||
{hasLyric ? <RecordLyrics style={lyricsBrowserStyle} currentLyric={currentLyric} currentTime={currentTime} /> :
|
||||
<div style={lyricsBrowserStyle}
|
||||
/>}
|
||||
<RecordPlayer loading={loading}
|
||||
playerBarWidth={playerBarWidth} currentTime={currentTime} hasLyric={hasLyric} currentLyric={currentLyric} />
|
||||
</Main>
|
||||
</ThemeProvider>
|
||||
</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 }) {
|
||||
const dispatch = useDispatch();
|
||||
const [duration, setDuration] = useState(0); // 秒,有小数点
|
||||
const [playbackRate, setPlaybackRate] = useState(1.0);
|
||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||
const recordList = useSelector(state => state.recorder.list);
|
||||
const currentBlob = useSelector(state => state.recorder.currentBlob);
|
||||
@ -28,6 +29,7 @@ export default function ({ width, currentTime }) {
|
||||
const player = useRef(null);
|
||||
useEffect(() => {
|
||||
player.current.url = currentBlob
|
||||
setPlaybackRate(1.0); // 恢复默认
|
||||
console.log(player.current.url);
|
||||
}, [currentBlob]);
|
||||
|
||||
@ -66,6 +68,7 @@ export default function ({ width, currentTime }) {
|
||||
}
|
||||
|
||||
const onChange = (event) => {
|
||||
setPlaybackRate(event.target.value);
|
||||
player.current.playbackRate = event.target.value;
|
||||
};
|
||||
|
||||
@ -107,7 +110,7 @@ export default function ({ width, currentTime }) {
|
||||
waveData={currentWaveData}
|
||||
/>
|
||||
<Select
|
||||
defaultValue={1.0}
|
||||
value={playbackRate}
|
||||
onChange={onChange}
|
||||
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 { useSelector, useDispatch } from 'react-redux'
|
||||
|
||||
@ -7,17 +7,56 @@ function isHighlight(currentTime, { start, 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 }) {
|
||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||
const recordList = useSelector(state => state.recorder.list);
|
||||
|
||||
if (recordList.length === 0) return <React.Fragment />;
|
||||
|
||||
const currentType = useMemo(() => {
|
||||
if (recordList.length <= 0) return -1;
|
||||
return recordList.at(currentIndex).type;
|
||||
}, [currentLyric]);
|
||||
return <Paper style={style}>
|
||||
{recordList.at(currentIndex).type === 1 ? (typeof currentLyric === "object" ? currentLyric.map((lyric, index) => {
|
||||
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>}
|
||||
<LyricsContent type={currentType} lyrics={currentLyric} currentTime={currentTime} />
|
||||
</Paper>
|
||||
}
|
@ -15,6 +15,7 @@ export const recorderSlice = createSlice({
|
||||
currentWaveData: [],
|
||||
currentTime: 0, // 当前音频播放时间
|
||||
pause: true,
|
||||
loading: false,
|
||||
},
|
||||
reducers: {
|
||||
setList: (state, action) => {
|
||||
@ -41,11 +42,35 @@ export const recorderSlice = createSlice({
|
||||
},
|
||||
setPauseState: (state, action) => {
|
||||
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
|
||||
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
|
||||
|
||||
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") {
|
||||
throw json;
|
||||
}
|
||||
console.log(json)
|
||||
return json;
|
||||
let list = json.result;
|
||||
list.sort((lfs, rhs) => { // 要求倒序排序
|
||||
return rhs.modifyTime - lfs.modifyTime;
|
||||
})
|
||||
return list;
|
||||
});
|
||||
},
|
||||
download: function (accessToken, url) {
|
||||
@ -234,6 +237,31 @@ const yzs = {
|
||||
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 () {
|
||||
let udid = localStorage.getItem('uniqueDeviceIdentifier');
|
||||
if (!udid) {
|
||||
|
@ -3,29 +3,16 @@ import React, { useState, useEffect, useRef } from 'react';
|
||||
import PhoneIphoneIcon from '@mui/icons-material/PhoneIphone';
|
||||
import LockIcon from '@mui/icons-material/Lock';
|
||||
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();
|
||||
export default function ({ udid, firstEnter, onChange, agreeAgreement, onAgreeChange }) {
|
||||
const code = useRef(null);
|
||||
const [firstEnter, setFirstEnter] = useState(true);
|
||||
const [seconds, setSeconds] = useState(0); // 倒计时
|
||||
|
||||
const account = useSelector(state => state.user.account)
|
||||
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(() => {
|
||||
const timer = window.setInterval(() => {
|
||||
if (seconds > 0) {
|
||||
@ -64,7 +51,7 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
|
||||
fullWidth
|
||||
error={firstEnter ? false : !validatePhoneNumber(account)}
|
||||
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
|
||||
onChange={handleInputChange}
|
||||
onChange={onChange}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
@ -82,14 +69,14 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
|
||||
}}
|
||||
hiddenLabel
|
||||
fullWidth
|
||||
name="password"
|
||||
name="verification_code"
|
||||
placeholder="请输入验证码"
|
||||
type="text"
|
||||
autoComplete="current-password"
|
||||
variant="outlined"
|
||||
size="small"
|
||||
value={verificationCode}
|
||||
onChange={handleInputChange}
|
||||
onChange={onChange}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
@ -121,7 +108,7 @@ export default function ({ udid, agreeAgreement, onAgreeChange }) {
|
||||
},
|
||||
}}
|
||||
>
|
||||
注册/登录
|
||||
登录
|
||||
</Button>
|
||||
<Agreement agree={agreeAgreement} onChange={onAgreeChange} />
|
||||
</Container>
|
||||
|
@ -3,23 +3,12 @@ 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();
|
||||
export default function ({ firstEnter, onChange, agreeAgreement, onAgreeChange }) {
|
||||
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 (firstEnter) setFirstEnter(false);
|
||||
}
|
||||
if (name === 'password') dispatch(setPassword(value));
|
||||
};
|
||||
|
||||
return <Container disableGutters={true}
|
||||
sx={{
|
||||
@ -38,7 +27,7 @@ export default function ({ agreeAgreement, onAgreeChange }) {
|
||||
helperText={firstEnter ? "" : textHintOfValidatePhoneNumber(account)}
|
||||
value={account}
|
||||
fullWidth
|
||||
onChange={handleInputChange}
|
||||
onChange={onChange}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
@ -63,7 +52,7 @@ export default function ({ agreeAgreement, onAgreeChange }) {
|
||||
variant="outlined"
|
||||
size="small"
|
||||
value={password}
|
||||
onChange={handleInputChange}
|
||||
onChange={onChange}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
|
@ -8,7 +8,7 @@ import ListItemButton from '@mui/material/ListItemButton';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import Typography from '@mui/material/Typography';
|
||||
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';
|
||||
|
||||
const drawerWidth = 240;
|
||||
@ -20,6 +20,7 @@ export default function ({ open, recordList, currentIndex, fetchRecord }) {
|
||||
console.log("onSelected", index, recordList.at(index).transResultUrl)
|
||||
dispatch(setCurrentIndex(index));
|
||||
fetchRecord(accessToken, recordList.at(index));
|
||||
dispatch(fecthRecord(index));
|
||||
}
|
||||
return <Drawer
|
||||
variant="persistent"
|
||||
@ -40,9 +41,13 @@ export default function ({ open, recordList, currentIndex, fetchRecord }) {
|
||||
{recordList === undefined ? <React.Fragment /> : recordList.map((item, index) => (
|
||||
<ListItem key={index} disablePadding>
|
||||
<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>
|
||||
<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 />
|
||||
<AccessTimeFilledIcon sx={{ fontSize: 12 }} />
|
||||
<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";
|
||||
|
||||
module.exports = function (app) {
|
||||
app.use(
|
||||
'/rest/v2/user/is_user_exist',
|
||||
createProxyMiddleware({
|
||||
target: accessServer,
|
||||
changeOrigin: true,
|
||||
logger: console,
|
||||
})
|
||||
);
|
||||
app.use(
|
||||
'/rest/v2/phone/login',
|
||||
createProxyMiddleware({
|
||||
|
Loading…
Reference in New Issue
Block a user