🐛 fix: exception handling

This commit is contained in:
Martial BE 2024-01-13 02:46:32 +08:00 committed by Buer
parent 3b46e4ca16
commit 290523b675
25 changed files with 754 additions and 538 deletions

View File

@ -11,40 +11,43 @@ const StatusProvider = ({ children }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const loadStatus = useCallback(async () => { const loadStatus = useCallback(async () => {
const res = await API.get('/api/status');
const { success, data } = res.data;
let system_name = ''; let system_name = '';
if (success) { try {
if (!data.chat_link) { const res = await API.get('/api/status');
delete data.chat_link; const { success, data } = res.data;
} if (success) {
localStorage.setItem('siteInfo', JSON.stringify(data)); if (!data.chat_link) {
localStorage.setItem('quota_per_unit', data.quota_per_unit); delete data.chat_link;
localStorage.setItem('display_in_currency', data.display_in_currency); }
dispatch({ type: SET_SITE_INFO, payload: data }); localStorage.setItem('siteInfo', JSON.stringify(data));
if ( localStorage.setItem('quota_per_unit', data.quota_per_unit);
data.version !== process.env.REACT_APP_VERSION && localStorage.setItem('display_in_currency', data.display_in_currency);
data.version !== 'v0.0.0' && dispatch({ type: SET_SITE_INFO, payload: data });
data.version !== '' && if (
process.env.REACT_APP_VERSION !== '' data.version !== process.env.REACT_APP_VERSION &&
) { data.version !== 'v0.0.0' &&
showNotice(`新版本可用:${data.version},请使用快捷键 Shift + F5 刷新页面`); data.version !== '' &&
} process.env.REACT_APP_VERSION !== ''
if (data.system_name) { ) {
system_name = data.system_name; showNotice(`新版本可用:${data.version},请使用快捷键 Shift + F5 刷新页面`);
} }
} else {
const backupSiteInfo = localStorage.getItem('siteInfo');
if (backupSiteInfo) {
const data = JSON.parse(backupSiteInfo);
if (data.system_name) { if (data.system_name) {
system_name = data.system_name; system_name = data.system_name;
} }
dispatch({ } else {
type: SET_SITE_INFO, const backupSiteInfo = localStorage.getItem('siteInfo');
payload: data if (backupSiteInfo) {
}); const data = JSON.parse(backupSiteInfo);
if (data.system_name) {
system_name = data.system_name;
}
dispatch({
type: SET_SITE_INFO,
payload: data
});
}
} }
} catch (error) {
showError('无法正常连接至服务器!'); showError('无法正常连接至服务器!');
} }

View File

@ -13,7 +13,7 @@ API.interceptors.response.use(
if (error.response?.status === 401) { if (error.response?.status === 401) {
localStorage.removeItem('user'); localStorage.removeItem('user');
store.dispatch({ type: LOGIN, payload: null }); store.dispatch({ type: LOGIN, payload: null });
window.location.href = '/login'; // window.location.href = '/login';
} }
if (error.response?.data?.message) { if (error.response?.data?.message) {

View File

@ -70,12 +70,16 @@ export function showInfo(message) {
} }
export async function getOAuthState() { export async function getOAuthState() {
const res = await API.get('/api/oauth/state'); try {
const { success, message, data } = res.data; const res = await API.get('/api/oauth/state');
if (success) { const { success, message, data } = res.data;
return data; if (success) {
} else { return data;
showError(message); } else {
showError(message);
return '';
}
} catch (error) {
return ''; return '';
} }
} }

View File

@ -11,19 +11,24 @@ const About = () => {
const displayAbout = async () => { const displayAbout = async () => {
setAbout(localStorage.getItem('about') || ''); setAbout(localStorage.getItem('about') || '');
const res = await API.get('/api/about'); try {
const { success, message, data } = res.data; const res = await API.get('/api/about');
if (success) { const { success, message, data } = res.data;
let aboutContent = data; if (success) {
if (!data.startsWith('https://')) { let aboutContent = data;
aboutContent = marked.parse(data); if (!data.startsWith('https://')) {
aboutContent = marked.parse(data);
}
setAbout(aboutContent);
localStorage.setItem('about', aboutContent);
} else {
showError(message);
setAbout('加载关于内容失败...');
} }
setAbout(aboutContent); } catch (error) {
localStorage.setItem('about', aboutContent);
} else {
showError(message);
setAbout('加载关于内容失败...'); setAbout('加载关于内容失败...');
} }
setAboutLoaded(true); setAboutLoaded(true);
}; };

View File

@ -30,6 +30,12 @@ const ForgetPasswordForm = ({ ...others }) => {
const [disableButton, setDisableButton] = useState(false); const [disableButton, setDisableButton] = useState(false);
const [countdown, setCountdown] = useState(30); const [countdown, setCountdown] = useState(30);
const handleFailure = (message) => {
showError(message);
setDisableButton(false);
setCountdown(30);
};
const submit = async (values, { setSubmitting }) => { const submit = async (values, { setSubmitting }) => {
setDisableButton(true); setDisableButton(true);
setSubmitting(true); setSubmitting(true);
@ -38,15 +44,17 @@ const ForgetPasswordForm = ({ ...others }) => {
setSubmitting(false); setSubmitting(false);
return; return;
} }
const res = await API.get(`/api/reset_password?email=${values.email}&turnstile=${turnstileToken}`); try {
const { success, message } = res.data; const res = await API.get(`/api/reset_password?email=${values.email}&turnstile=${turnstileToken}`);
if (success) { const { success, message } = res.data;
showSuccess('重置邮件发送成功,请检查邮箱!'); if (success) {
setSendEmail(true); showSuccess('重置邮件发送成功,请检查邮箱!');
} else { setSendEmail(true);
showError(message); } else {
setDisableButton(false); handleFailure(message);
setCountdown(30); }
} catch (error) {
handleFailure('服务器错误');
} }
setSubmitting(false); setSubmitting(false);
}; };

View File

@ -19,15 +19,19 @@ const ResetPasswordForm = () => {
const [newPassword, setNewPassword] = useState(''); const [newPassword, setNewPassword] = useState('');
const submit = async () => { const submit = async () => {
const res = await API.post(`/api/user/reset`, inputs); try {
const { success, message } = res.data; const res = await API.post(`/api/user/reset`, inputs);
if (success) { const { success, message } = res.data;
let password = res.data.data; if (success) {
setNewPassword(password); let password = res.data.data;
navigator.clipboard.writeText(password); setNewPassword(password);
showInfo(`新密码已复制到剪贴板:${password}`); navigator.clipboard.writeText(password);
} else { showInfo(`新密码已复制到剪贴板:${password}`);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -171,25 +171,33 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => {
let res; let res;
const modelsStr = values.models.map((model) => model.id).join(','); const modelsStr = values.models.map((model) => model.id).join(',');
values.group = values.groups.join(','); values.group = values.groups.join(',');
if (channelId) { try {
res = await API.put(`/api/channel/`, { ...values, id: parseInt(channelId), models: modelsStr });
} else {
res = await API.post(`/api/channel/`, { ...values, models: modelsStr });
}
const { success, message } = res.data;
if (success) {
if (channelId) { if (channelId) {
showSuccess('渠道更新成功!'); res = await API.put(`/api/channel/`, { ...values, id: parseInt(channelId), models: modelsStr });
} else { } else {
showSuccess('渠道创建成功!'); res = await API.post(`/api/channel/`, { ...values, models: modelsStr });
} }
setSubmitting(false); const { success, message } = res.data;
setStatus({ success: true }); if (success) {
onOk(true); if (channelId) {
} else { showSuccess('渠道更新成功!');
} else {
showSuccess('渠道创建成功!');
}
setSubmitting(false);
setStatus({ success: true });
onOk(true);
return;
} else {
setStatus({ success: false });
showError(message);
setErrors({ submit: message });
}
} catch (error) {
setStatus({ success: false }); setStatus({ success: false });
showError(message); showError(error.message);
setErrors({ submit: message }); setErrors({ submit: error.message });
return;
} }
}; };
@ -213,29 +221,33 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => {
} }
const loadChannel = async () => { const loadChannel = async () => {
let res = await API.get(`/api/channel/${channelId}`); try {
const { success, message, data } = res.data; let res = await API.get(`/api/channel/${channelId}`);
if (success) { const { success, message, data } = res.data;
if (data.models === '') { if (success) {
data.models = []; if (data.models === '') {
} else { data.models = [];
data.models = initialModel(data.models); } else {
} data.models = initialModel(data.models);
if (data.group === '') { }
data.groups = []; if (data.group === '') {
} else { data.groups = [];
data.groups = data.group.split(','); } else {
} data.groups = data.group.split(',');
if (data.model_mapping !== '') { }
data.model_mapping = JSON.stringify(JSON.parse(data.model_mapping), null, 2); if (data.model_mapping !== '') {
} data.model_mapping = JSON.stringify(JSON.parse(data.model_mapping), null, 2);
}
data.base_url = data.base_url ?? ''; data.base_url = data.base_url ?? '';
data.is_edit = true; data.is_edit = true;
initChannel(data.type); initChannel(data.type);
setInitialInput(data); setInitialInput(data);
} else { } else {
showError(message); showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -82,14 +82,18 @@ export default function ChannelTableRow({ item, manageChannel, handleOpenModal,
}; };
const updateChannelBalance = async () => { const updateChannelBalance = async () => {
const res = await API.get(`/api/channel/update_balance/${item.id}`); try {
const { success, message, balance } = res.data; const res = await API.get(`/api/channel/update_balance/${item.id}`);
if (success) { const { success, message, balance } = res.data;
setItemBalance(balance); if (success) {
setItemBalance(balance);
showInfo(`余额更新成功!`); showInfo(`余额更新成功!`);
} else { } else {
showError(message); showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -36,19 +36,24 @@ export default function ChannelPage() {
const loadChannels = async (startIdx) => { const loadChannels = async (startIdx) => {
setSearching(true); setSearching(true);
const res = await API.get(`/api/channel/?p=${startIdx}`); try {
const { success, message, data } = res.data; const res = await API.get(`/api/channel/?p=${startIdx}`);
if (success) { const { success, message, data } = res.data;
if (startIdx === 0) { if (success) {
setChannels(data); if (startIdx === 0) {
setChannels(data);
} else {
let newChannels = [...channels];
newChannels.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setChannels(newChannels);
}
} else { } else {
let newChannels = [...channels]; showError(message);
newChannels.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setChannels(newChannels);
} }
} else { } catch (error) {
showError(message); console.error(error);
} }
setSearching(false); setSearching(false);
}; };
@ -70,13 +75,17 @@ export default function ChannelPage() {
return; return;
} }
setSearching(true); setSearching(true);
const res = await API.get(`/api/channel/search?keyword=${searchKeyword}`); try {
const { success, message, data } = res.data; const res = await API.get(`/api/channel/search?keyword=${searchKeyword}`);
if (success) { const { success, message, data } = res.data;
setChannels(data); if (success) {
setActivePage(0); setChannels(data);
} else { setActivePage(0);
showError(message); } else {
showError(message);
}
} catch (error) {
console.error(error);
} }
setSearching(false); setSearching(false);
}; };
@ -89,40 +98,45 @@ export default function ChannelPage() {
const url = '/api/channel/'; const url = '/api/channel/';
let data = { id }; let data = { id };
let res; let res;
switch (action) {
case 'delete':
res = await API.delete(url + id);
break;
case 'status':
res = await API.put(url, {
...data,
status: value
});
break;
case 'priority':
if (value === '') {
return;
}
res = await API.put(url, {
...data,
priority: parseInt(value)
});
break;
case 'test':
res = await API.get(url + `test/${id}`);
break;
}
const { success, message } = res.data;
if (success) {
showSuccess('操作成功完成!');
if (action === 'delete') {
await handleRefresh();
}
} else {
showError(message);
}
return res.data; try {
switch (action) {
case 'delete':
res = await API.delete(url + id);
break;
case 'status':
res = await API.put(url, {
...data,
status: value
});
break;
case 'priority':
if (value === '') {
return;
}
res = await API.put(url, {
...data,
priority: parseInt(value)
});
break;
case 'test':
res = await API.get(url + `test/${id}`);
break;
}
const { success, message } = res.data;
if (success) {
showSuccess('操作成功完成!');
if (action === 'delete') {
await handleRefresh();
}
} else {
showError(message);
}
return res.data;
} catch (error) {
return;
}
}; };
// 处理刷新 // 处理刷新
@ -132,37 +146,50 @@ export default function ChannelPage() {
// 处理测试所有启用渠道 // 处理测试所有启用渠道
const testAllChannels = async () => { const testAllChannels = async () => {
const res = await API.get(`/api/channel/test`); try {
const { success, message } = res.data; const res = await API.get(`/api/channel/test`);
if (success) { const { success, message } = res.data;
showInfo('已成功开始测试所有通道,请刷新页面查看结果。'); if (success) {
} else { showInfo('已成功开始测试所有通道,请刷新页面查看结果。');
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };
// 处理删除所有禁用渠道 // 处理删除所有禁用渠道
const deleteAllDisabledChannels = async () => { const deleteAllDisabledChannels = async () => {
const res = await API.delete(`/api/channel/disabled`); try {
const { success, message, data } = res.data; const res = await API.delete(`/api/channel/disabled`);
if (success) { const { success, message, data } = res.data;
showSuccess(`已删除所有禁用渠道,共计 ${data}`); if (success) {
await handleRefresh(); showSuccess(`已删除所有禁用渠道,共计 ${data}`);
} else { await handleRefresh();
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };
// 处理更新所有启用渠道余额 // 处理更新所有启用渠道余额
const updateAllChannelsBalance = async () => { const updateAllChannelsBalance = async () => {
setSearching(true); setSearching(true);
const res = await API.get(`/api/channel/update_balance`); try {
const { success, message } = res.data; const res = await API.get(`/api/channel/update_balance`);
if (success) { const { success, message } = res.data;
showInfo('已更新完毕所有已启用通道余额!'); if (success) {
} else { showInfo('已更新完毕所有已启用通道余额!');
showError(message); } else {
showError(message);
}
} catch (error) {
console.log(error);
} }
setSearching(false); setSearching(false);
}; };

View File

@ -18,29 +18,37 @@ const Dashboard = () => {
const [users, setUsers] = useState([]); const [users, setUsers] = useState([]);
const userDashboard = async () => { const userDashboard = async () => {
const res = await API.get('/api/user/dashboard'); try {
const { success, message, data } = res.data; const res = await API.get('/api/user/dashboard');
if (success) { const { success, message, data } = res.data;
if (data) { if (success) {
let lineData = getLineDataGroup(data); if (data) {
setRequestChart(getLineCardOption(lineData, 'RequestCount')); let lineData = getLineDataGroup(data);
setQuotaChart(getLineCardOption(lineData, 'Quota')); setRequestChart(getLineCardOption(lineData, 'RequestCount'));
setTokenChart(getLineCardOption(lineData, 'PromptTokens')); setQuotaChart(getLineCardOption(lineData, 'Quota'));
setStatisticalData(getBarDataGroup(data)); setTokenChart(getLineCardOption(lineData, 'PromptTokens'));
setStatisticalData(getBarDataGroup(data));
}
} else {
showError(message);
} }
} else { setLoading(false);
showError(message); } catch (error) {
return;
} }
setLoading(false);
}; };
const loadUser = async () => { const loadUser = async () => {
let res = await API.get(`/api/user/self`); try {
const { success, message, data } = res.data; let res = await API.get(`/api/user/self`);
if (success) { const { success, message, data } = res.data;
setUsers(data); if (success) {
} else { setUsers(data);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -9,36 +9,44 @@ const Home = () => {
const [homePageContentLoaded, setHomePageContentLoaded] = useState(false); const [homePageContentLoaded, setHomePageContentLoaded] = useState(false);
const [homePageContent, setHomePageContent] = useState(''); const [homePageContent, setHomePageContent] = useState('');
const displayNotice = async () => { const displayNotice = async () => {
const res = await API.get('/api/notice'); try {
const { success, message, data } = res.data; const res = await API.get('/api/notice');
if (success) { const { success, message, data } = res.data;
let oldNotice = localStorage.getItem('notice'); if (success) {
if (data !== oldNotice && data !== '') { let oldNotice = localStorage.getItem('notice');
const htmlNotice = marked(data); if (data !== oldNotice && data !== '') {
showNotice(htmlNotice, true); const htmlNotice = marked(data);
localStorage.setItem('notice', data); showNotice(htmlNotice, true);
localStorage.setItem('notice', data);
}
} else {
showError(message);
} }
} else { } catch (error) {
showError(message); return;
} }
}; };
const displayHomePageContent = async () => { const displayHomePageContent = async () => {
setHomePageContent(localStorage.getItem('home_page_content') || ''); setHomePageContent(localStorage.getItem('home_page_content') || '');
const res = await API.get('/api/home_page_content'); try {
const { success, message, data } = res.data; const res = await API.get('/api/home_page_content');
if (success) { const { success, message, data } = res.data;
let content = data; if (success) {
if (!data.startsWith('https://')) { let content = data;
content = marked.parse(data); if (!data.startsWith('https://')) {
content = marked.parse(data);
}
setHomePageContent(content);
localStorage.setItem('home_page_content', content);
} else {
showError(message);
setHomePageContent('加载首页内容失败...');
} }
setHomePageContent(content); setHomePageContentLoaded(true);
localStorage.setItem('home_page_content', content); } catch (error) {
} else { return;
showError(message);
setHomePageContent('加载首页内容失败...');
} }
setHomePageContentLoaded(true);
}; };
useEffect(() => { useEffect(() => {

View File

@ -47,19 +47,25 @@ export default function Log() {
delete query.username; delete query.username;
delete query.channel; delete query.channel;
} }
const res = await API.get(url, { params: query });
const { success, message, data } = res.data; try {
if (success) { const res = await API.get(url, { params: query });
if (startIdx === 0) { const { success, message, data } = res.data;
setLogs(data); if (success) {
if (startIdx === 0) {
setLogs(data);
} else {
let newLogs = [...logs];
newLogs.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setLogs(newLogs);
}
} else { } else {
let newLogs = [...logs]; showError(message);
newLogs.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setLogs(newLogs);
} }
} else { } catch (error) {
showError(message); console.log(error);
} }
setSearching(false); setSearching(false);
}; };

View File

@ -26,7 +26,7 @@ const validationSchema = Yup.object().shape({
email_verification_code: Yup.string().required('验证码不能为空') email_verification_code: Yup.string().required('验证码不能为空')
}); });
const EmailModal = ({ open, handleClose, turnstileToken }) => { const EmailModal = ({ open, handleClose, turnstileToken, turnstileEnabled }) => {
const theme = useTheme(); const theme = useTheme();
const [countdown, setCountdown] = useState(30); const [countdown, setCountdown] = useState(30);
const [disableButton, setDisableButton] = useState(false); const [disableButton, setDisableButton] = useState(false);
@ -36,16 +36,20 @@ const EmailModal = ({ open, handleClose, turnstileToken }) => {
const submit = async (values, { setErrors, setStatus, setSubmitting }) => { const submit = async (values, { setErrors, setStatus, setSubmitting }) => {
setLoading(true); setLoading(true);
setSubmitting(true); setSubmitting(true);
const res = await API.get(`/api/oauth/email/bind?email=${values.email}&code=${values.email_verification_code}`); try {
const { success, message } = res.data; const res = await API.get(`/api/oauth/email/bind?email=${values.email}&code=${values.email_verification_code}`);
if (success) { const { success, message } = res.data;
showSuccess('邮箱账户绑定成功!'); if (success) {
setSubmitting(false); showSuccess('邮箱账户绑定成功!');
setStatus({ success: true }); setSubmitting(false);
handleClose(); setStatus({ success: true });
} else { handleClose();
showError(message); } else {
setErrors({ submit: message }); showError(message);
setErrors({ submit: message });
}
} catch (error) {
console.log(error);
} }
setLoading(false); setLoading(false);
}; };
@ -69,7 +73,7 @@ const EmailModal = ({ open, handleClose, turnstileToken }) => {
showError('请输入邮箱'); showError('请输入邮箱');
return; return;
} }
if (turnstileToken === '') { if (turnstileEnabled && turnstileToken === '') {
showError('请稍后几秒重试Turnstile 正在检查用户环境!'); showError('请稍后几秒重试Turnstile 正在检查用户环境!');
return; return;
} }
@ -168,5 +172,6 @@ export default EmailModal;
EmailModal.propTypes = { EmailModal.propTypes = {
open: PropTypes.bool, open: PropTypes.bool,
handleClose: PropTypes.func, handleClose: PropTypes.func,
turnstileToken: PropTypes.string turnstileToken: PropTypes.string,
turnstileEnabled: PropTypes.bool
}; };

View File

@ -59,12 +59,16 @@ export default function Profile() {
}; };
const loadUser = async () => { const loadUser = async () => {
let res = await API.get(`/api/user/self`); try {
const { success, message, data } = res.data; let res = await API.get(`/api/user/self`);
if (success) { const { success, message, data } = res.data;
setInputs(data); if (success) {
} else { setInputs(data);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };
@ -84,17 +88,19 @@ export default function Profile() {
}; };
const generateAccessToken = async () => { const generateAccessToken = async () => {
const res = await API.get('/api/user/token'); try {
const { success, message, data } = res.data; const res = await API.get('/api/user/token');
if (success) { const { success, message, data } = res.data;
setInputs((inputs) => ({ ...inputs, access_token: data })); if (success) {
navigator.clipboard.writeText(data); setInputs((inputs) => ({ ...inputs, access_token: data }));
showSuccess(`令牌已重置并已复制到剪贴板`); navigator.clipboard.writeText(data);
} else { showSuccess(`令牌已重置并已复制到剪贴板`);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
console.log(turnstileEnabled, turnstileSiteKey, status);
}; };
const submit = async () => { const submit = async () => {
@ -284,6 +290,7 @@ export default function Profile() {
<EmailModal <EmailModal
open={openEmail} open={openEmail}
turnstileToken={turnstileToken} turnstileToken={turnstileToken}
turnstileEnabled={turnstileEnabled}
handleClose={() => { handleClose={() => {
setOpenEmail(false); setOpenEmail(false);
}} }}

View File

@ -46,42 +46,50 @@ const EditModal = ({ open, redemptiondId, onCancel, onOk }) => {
setSubmitting(true); setSubmitting(true);
let res; let res;
if (values.is_edit) { try {
res = await API.put(`/api/redemption/`, { ...values, id: parseInt(redemptiondId) });
} else {
res = await API.post(`/api/redemption/`, values);
}
const { success, message, data } = res.data;
if (success) {
if (values.is_edit) { if (values.is_edit) {
showSuccess('兑换码更新成功!'); res = await API.put(`/api/redemption/`, { ...values, id: parseInt(redemptiondId) });
} else { } else {
showSuccess('兑换码创建成功!'); res = await API.post(`/api/redemption/`, values);
if (data.length > 1) {
let text = '';
for (let i = 0; i < data.length; i++) {
text += data[i] + '\n';
}
downloadTextAsFile(text, `${values.name}.txt`);
}
} }
setSubmitting(false); const { success, message, data } = res.data;
setStatus({ success: true }); if (success) {
onOk(true); if (values.is_edit) {
} else { showSuccess('兑换码更新成功!');
showError(message); } else {
setErrors({ submit: message }); showSuccess('兑换码创建成功!');
if (data.length > 1) {
let text = '';
for (let i = 0; i < data.length; i++) {
text += data[i] + '\n';
}
downloadTextAsFile(text, `${values.name}.txt`);
}
}
setSubmitting(false);
setStatus({ success: true });
onOk(true);
} else {
showError(message);
setErrors({ submit: message });
}
} catch (error) {
return;
} }
}; };
const loadRedemptiond = async () => { const loadRedemptiond = async () => {
let res = await API.get(`/api/redemption/${redemptiondId}`); try {
const { success, message, data } = res.data; let res = await API.get(`/api/redemption/${redemptiondId}`);
if (success) { const { success, message, data } = res.data;
data.is_edit = true; if (success) {
setInputs(data); data.is_edit = true;
} else { setInputs(data);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -30,18 +30,22 @@ export default function Redemption() {
const loadRedemptions = async (startIdx) => { const loadRedemptions = async (startIdx) => {
setSearching(true); setSearching(true);
const res = await API.get(`/api/redemption/?p=${startIdx}`); try {
const { success, message, data } = res.data; const res = await API.get(`/api/redemption/?p=${startIdx}`);
if (success) { const { success, message, data } = res.data;
if (startIdx === 0) { if (success) {
setRedemptions(data); if (startIdx === 0) {
setRedemptions(data);
} else {
let newRedemptions = [...redemptions];
newRedemptions.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setRedemptions(newRedemptions);
}
} else { } else {
let newRedemptions = [...redemptions]; showError(message);
newRedemptions.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setRedemptions(newRedemptions);
} }
} else { } catch (error) {
showError(message); console.log(error);
} }
setSearching(false); setSearching(false);
}; };
@ -64,14 +68,20 @@ export default function Redemption() {
return; return;
} }
setSearching(true); setSearching(true);
const res = await API.get(`/api/redemption/search?keyword=${searchKeyword}`);
const { success, message, data } = res.data; try {
if (success) { const res = await API.get(`/api/redemption/search?keyword=${searchKeyword}`);
setRedemptions(data); const { success, message, data } = res.data;
setActivePage(0); if (success) {
} else { setRedemptions(data);
showError(message); setActivePage(0);
} else {
showError(message);
}
} catch (error) {
console.log(error);
} }
setSearching(false); setSearching(false);
}; };
@ -83,28 +93,33 @@ export default function Redemption() {
const url = '/api/redemption/'; const url = '/api/redemption/';
let data = { id }; let data = { id };
let res; let res;
switch (action) {
case 'delete':
res = await API.delete(url + id);
break;
case 'status':
res = await API.put(url + '?status_only=true', {
...data,
status: value
});
break;
}
const { success, message } = res.data;
if (success) {
showSuccess('操作成功完成!');
if (action === 'delete') {
await loadRedemptions(0);
}
} else {
showError(message);
}
return res.data; try {
switch (action) {
case 'delete':
res = await API.delete(url + id);
break;
case 'status':
res = await API.put(url + '?status_only=true', {
...data,
status: value
});
break;
}
const { success, message } = res.data;
if (success) {
showSuccess('操作成功完成!');
if (action === 'delete') {
await loadRedemptions(0);
}
} else {
showError(message);
}
return res.data;
} catch (error) {
return;
}
}; };
// 处理刷新 // 处理刷新

View File

@ -36,20 +36,24 @@ const OperationSetting = () => {
let [historyTimestamp, setHistoryTimestamp] = useState(now.getTime() / 1000 - 30 * 24 * 3600); // a month ago new Date().getTime() / 1000 + 3600 let [historyTimestamp, setHistoryTimestamp] = useState(now.getTime() / 1000 - 30 * 24 * 3600); // a month ago new Date().getTime() / 1000 + 3600
const getOptions = async () => { const getOptions = async () => {
const res = await API.get('/api/option/'); try {
const { success, message, data } = res.data; const res = await API.get('/api/option/');
if (success) { const { success, message, data } = res.data;
let newInputs = {}; if (success) {
data.forEach((item) => { let newInputs = {};
if (item.key === 'ModelRatio' || item.key === 'GroupRatio') { data.forEach((item) => {
item.value = JSON.stringify(JSON.parse(item.value), null, 2); if (item.key === 'ModelRatio' || item.key === 'GroupRatio') {
} item.value = JSON.stringify(JSON.parse(item.value), null, 2);
newInputs[item.key] = item.value; }
}); newInputs[item.key] = item.value;
setInputs(newInputs); });
setOriginInputs(newInputs); setInputs(newInputs);
} else { setOriginInputs(newInputs);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };
@ -62,16 +66,22 @@ const OperationSetting = () => {
if (key.endsWith('Enabled')) { if (key.endsWith('Enabled')) {
value = inputs[key] === 'true' ? 'false' : 'true'; value = inputs[key] === 'true' ? 'false' : 'true';
} }
const res = await API.put('/api/option/', {
key, try {
value const res = await API.put('/api/option/', {
}); key,
const { success, message } = res.data; value
if (success) { });
setInputs((inputs) => ({ ...inputs, [key]: value })); const { success, message } = res.data;
} else { if (success) {
showError(message); setInputs((inputs) => ({ ...inputs, [key]: value }));
} else {
showError(message);
}
} catch (error) {
return;
} }
setLoading(false); setLoading(false);
}; };
@ -146,13 +156,17 @@ const OperationSetting = () => {
}; };
const deleteHistoryLogs = async () => { const deleteHistoryLogs = async () => {
const res = await API.delete(`/api/log/?target_timestamp=${Math.floor(historyTimestamp)}`); try {
const { success, message, data } = res.data; const res = await API.delete(`/api/log/?target_timestamp=${Math.floor(historyTimestamp)}`);
if (success) { const { success, message, data } = res.data;
showSuccess(`${data} 条日志已清理!`); if (success) {
showSuccess(`${data} 条日志已清理!`);
return;
}
showError('日志清理失败:' + message);
} catch (error) {
return; return;
} }
showError('日志清理失败:' + message);
}; };
return ( return (

View File

@ -36,18 +36,22 @@ const OtherSetting = () => {
}); });
const getOptions = async () => { const getOptions = async () => {
const res = await API.get('/api/option/'); try {
const { success, message, data } = res.data; const res = await API.get('/api/option/');
if (success) { const { success, message, data } = res.data;
let newInputs = {}; if (success) {
data.forEach((item) => { let newInputs = {};
if (item.key in inputs) { data.forEach((item) => {
newInputs[item.key] = item.value; if (item.key in inputs) {
} newInputs[item.key] = item.value;
}); }
setInputs(newInputs); });
} else { setInputs(newInputs);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };
@ -58,18 +62,22 @@ const OtherSetting = () => {
const updateOption = async (key, value) => { const updateOption = async (key, value) => {
setLoading(true); setLoading(true);
const res = await API.put('/api/option/', { try {
key, const res = await API.put('/api/option/', {
value key,
}); value
const { success, message } = res.data; });
if (success) { const { success, message } = res.data;
setInputs((inputs) => ({ ...inputs, [key]: value })); if (success) {
showSuccess('保存成功'); setInputs((inputs) => ({ ...inputs, [key]: value }));
} else { showSuccess('保存成功');
showError(message); } else {
showError(message);
}
setLoading(false);
} catch (error) {
return;
} }
setLoading(false);
}; };
const handleInputChange = async (event) => { const handleInputChange = async (event) => {
@ -106,16 +114,20 @@ const OtherSetting = () => {
}; };
const checkUpdate = async () => { const checkUpdate = async () => {
const res = await API.get('https://api.github.com/repos/MartialBE/one-api/releases/latest'); try {
const { tag_name, body } = res.data; const res = await API.get('https://api.github.com/repos/MartialBE/one-api/releases/latest');
if (tag_name === process.env.REACT_APP_VERSION) { const { tag_name, body } = res.data;
showSuccess(`已是最新版本:${tag_name}`); if (tag_name === process.env.REACT_APP_VERSION) {
} else { showSuccess(`已是最新版本:${tag_name}`);
setUpdateData({ } else {
tag_name: tag_name, setUpdateData({
content: marked.parse(body) tag_name: tag_name,
}); content: marked.parse(body)
setShowUpdateModal(true); });
setShowUpdateModal(true);
}
} catch (error) {
return;
} }
}; };

View File

@ -56,22 +56,26 @@ const SystemSetting = () => {
const [showPasswordWarningModal, setShowPasswordWarningModal] = useState(false); const [showPasswordWarningModal, setShowPasswordWarningModal] = useState(false);
const getOptions = async () => { const getOptions = async () => {
const res = await API.get('/api/option/'); try {
const { success, message, data } = res.data; const res = await API.get('/api/option/');
if (success) { const { success, message, data } = res.data;
let newInputs = {}; if (success) {
data.forEach((item) => { let newInputs = {};
newInputs[item.key] = item.value; data.forEach((item) => {
}); newInputs[item.key] = item.value;
setInputs({ });
...newInputs, setInputs({
EmailDomainWhitelist: newInputs.EmailDomainWhitelist.split(',') ...newInputs,
}); EmailDomainWhitelist: newInputs.EmailDomainWhitelist.split(',')
setOriginInputs(newInputs); });
setOriginInputs(newInputs);
setEmailDomainWhitelist(newInputs.EmailDomainWhitelist.split(',')); setEmailDomainWhitelist(newInputs.EmailDomainWhitelist.split(','));
} else { } else {
showError(message); showError(message);
}
} catch (error) {
return;
} }
}; };
@ -95,23 +99,29 @@ const SystemSetting = () => {
default: default:
break; break;
} }
const res = await API.put('/api/option/', {
key, try {
value const res = await API.put('/api/option/', {
}); key,
const { success, message } = res.data; value
if (success) { });
if (key === 'EmailDomainWhitelist') { const { success, message } = res.data;
value = value.split(','); if (success) {
if (key === 'EmailDomainWhitelist') {
value = value.split(',');
}
setInputs((inputs) => ({
...inputs,
[key]: value
}));
showSuccess('设置成功!');
} else {
showError(message);
} }
setInputs((inputs) => ({ } catch (error) {
...inputs, return;
[key]: value
}));
showSuccess('设置成功!');
} else {
showError(message);
} }
setLoading(false); setLoading(false);
}; };

View File

@ -52,35 +52,44 @@ const EditModal = ({ open, tokenId, onCancel, onOk }) => {
values.remain_quota = parseInt(values.remain_quota); values.remain_quota = parseInt(values.remain_quota);
let res; let res;
if (values.is_edit) {
res = await API.put(`/api/token/`, { ...values, id: parseInt(tokenId) }); try {
} else {
res = await API.post(`/api/token/`, values);
}
const { success, message } = res.data;
if (success) {
if (values.is_edit) { if (values.is_edit) {
showSuccess('令牌更新成功!'); res = await API.put(`/api/token/`, { ...values, id: parseInt(tokenId) });
} else { } else {
showSuccess('令牌创建成功,请在列表页面点击复制获取令牌!'); res = await API.post(`/api/token/`, values);
} }
setSubmitting(false); const { success, message } = res.data;
setStatus({ success: true }); if (success) {
onOk(true); if (values.is_edit) {
} else { showSuccess('令牌更新成功!');
showError(message); } else {
setErrors({ submit: message }); showSuccess('令牌创建成功,请在列表页面点击复制获取令牌!');
}
setSubmitting(false);
setStatus({ success: true });
onOk(true);
} else {
showError(message);
setErrors({ submit: message });
}
} catch (error) {
return;
} }
}; };
const loadToken = async () => { const loadToken = async () => {
let res = await API.get(`/api/token/${tokenId}`); try {
const { success, message, data } = res.data; let res = await API.get(`/api/token/${tokenId}`);
if (success) { const { success, message, data } = res.data;
data.is_edit = true; if (success) {
setInputs(data); data.is_edit = true;
} else { setInputs(data);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -32,19 +32,24 @@ export default function Token() {
const loadTokens = async (startIdx) => { const loadTokens = async (startIdx) => {
setSearching(true); setSearching(true);
const res = await API.get(`/api/token/?p=${startIdx}`); try {
const { success, message, data } = res.data; const res = await API.get(`/api/token/?p=${startIdx}`);
if (success) { const { success, message, data } = res.data;
if (startIdx === 0) { if (success) {
setTokens(data); if (startIdx === 0) {
setTokens(data);
} else {
let newTokens = [...tokens];
newTokens.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setTokens(newTokens);
}
} else { } else {
let newTokens = [...tokens]; showError(message);
newTokens.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setTokens(newTokens);
} }
} else { } catch (error) {
showError(message); console.log(error);
} }
setSearching(false); setSearching(false);
}; };
@ -75,14 +80,20 @@ export default function Token() {
return; return;
} }
setSearching(true); setSearching(true);
const res = await API.get(`/api/token/search?keyword=${searchKeyword}`);
const { success, message, data } = res.data; try {
if (success) { const res = await API.get(`/api/token/search?keyword=${searchKeyword}`);
setTokens(data); const { success, message, data } = res.data;
setActivePage(0); if (success) {
} else { setTokens(data);
showError(message); setActivePage(0);
} else {
showError(message);
}
} catch (error) {
return;
} }
setSearching(false); setSearching(false);
}; };
@ -94,28 +105,32 @@ export default function Token() {
const url = '/api/token/'; const url = '/api/token/';
let data = { id }; let data = { id };
let res; let res;
switch (action) { try {
case 'delete': switch (action) {
res = await API.delete(url + id); case 'delete':
break; res = await API.delete(url + id);
case 'status': break;
res = await API.put(url + `?status_only=true`, { case 'status':
...data, res = await API.put(url + `?status_only=true`, {
status: value ...data,
}); status: value
break; });
} break;
const { success, message } = res.data; }
if (success) { const { success, message } = res.data;
showSuccess('操作成功完成!'); if (success) {
if (action === 'delete') { showSuccess('操作成功完成!');
await handleRefresh(); if (action === 'delete') {
await handleRefresh();
}
} else {
showError(message);
} }
} else {
showError(message);
}
return res.data; return res.data;
} catch (error) {
return;
}
}; };
// 处理刷新 // 处理刷新

View File

@ -16,15 +16,20 @@ const InviteCard = () => {
showSuccess(`邀请链接已复制到剪切板`); showSuccess(`邀请链接已复制到剪切板`);
return; return;
} }
const res = await API.get('/api/user/aff');
const { success, message, data } = res.data; try {
if (success) { const res = await API.get('/api/user/aff');
let link = `${window.location.origin}/register?aff=${data}`; const { success, message, data } = res.data;
setInviteUrl(link); if (success) {
navigator.clipboard.writeText(link); let link = `${window.location.origin}/register?aff=${data}`;
showSuccess(`邀请链接已复制到剪切板`); setInviteUrl(link);
} else { navigator.clipboard.writeText(link);
showError(message); showSuccess(`邀请链接已复制到剪切板`);
} else {
showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -51,12 +51,16 @@ const TopupCard = () => {
}; };
const getUserQuota = async () => { const getUserQuota = async () => {
let res = await API.get(`/api/user/self`); try {
const { success, message, data } = res.data; let res = await API.get(`/api/user/self`);
if (success) { const { success, message, data } = res.data;
setUserQuota(data.quota); if (success) {
} else { setUserQuota(data.quota);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -66,24 +66,29 @@ const EditModal = ({ open, userId, onCancel, onOk }) => {
setSubmitting(true); setSubmitting(true);
let res; let res;
if (values.is_edit) {
res = await API.put(`/api/user/`, { ...values, id: parseInt(userId) }); try {
} else {
res = await API.post(`/api/user/`, values);
}
const { success, message } = res.data;
if (success) {
if (values.is_edit) { if (values.is_edit) {
showSuccess('用户更新成功!'); res = await API.put(`/api/user/`, { ...values, id: parseInt(userId) });
} else { } else {
showSuccess('用户创建成功!'); res = await API.post(`/api/user/`, values);
} }
setSubmitting(false); const { success, message } = res.data;
setStatus({ success: true }); if (success) {
onOk(true); if (values.is_edit) {
} else { showSuccess('用户更新成功!');
showError(message); } else {
setErrors({ submit: message }); showSuccess('用户创建成功!');
}
setSubmitting(false);
setStatus({ success: true });
onOk(true);
} else {
showError(message);
setErrors({ submit: message });
}
} catch (error) {
return;
} }
}; };
@ -96,13 +101,17 @@ const EditModal = ({ open, userId, onCancel, onOk }) => {
}; };
const loadUser = async () => { const loadUser = async () => {
let res = await API.get(`/api/user/${userId}`); try {
const { success, message, data } = res.data; let res = await API.get(`/api/user/${userId}`);
if (success) { const { success, message, data } = res.data;
data.is_edit = true; if (success) {
setInputs(data); data.is_edit = true;
} else { setInputs(data);
showError(message); } else {
showError(message);
}
} catch (error) {
return;
} }
}; };

View File

@ -30,20 +30,25 @@ export default function Users() {
const loadUsers = async (startIdx) => { const loadUsers = async (startIdx) => {
setSearching(true); setSearching(true);
const res = await API.get(`/api/user/?p=${startIdx}`); try {
const { success, message, data } = res.data; const res = await API.get(`/api/user/?p=${startIdx}`);
if (success) { const { success, message, data } = res.data;
if (startIdx === 0) { if (success) {
setUsers(data); if (startIdx === 0) {
setUsers(data);
} else {
let newUsers = [...users];
newUsers.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setUsers(newUsers);
}
} else { } else {
let newUsers = [...users]; showError(message);
newUsers.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setUsers(newUsers);
} }
} else { setSearching(false);
showError(message); } catch (error) {
setSearching(false);
return;
} }
setSearching(false);
}; };
const onPaginationChange = (event, activePage) => { const onPaginationChange = (event, activePage) => {
@ -64,15 +69,20 @@ export default function Users() {
return; return;
} }
setSearching(true); setSearching(true);
const res = await API.get(`/api/user/search?keyword=${searchKeyword}`); try {
const { success, message, data } = res.data; const res = await API.get(`/api/user/search?keyword=${searchKeyword}`);
if (success) { const { success, message, data } = res.data;
setUsers(data); if (success) {
setActivePage(0); setUsers(data);
} else { setActivePage(0);
showError(message); } else {
showError(message);
}
setSearching(false);
} catch (error) {
setSearching(false);
return;
} }
setSearching(false);
}; };
const handleSearchKeyword = (event) => { const handleSearchKeyword = (event) => {
@ -95,16 +105,20 @@ export default function Users() {
break; break;
} }
res = await API.post(url, data); try {
const { success, message } = res.data; res = await API.post(url, data);
if (success) { const { success, message } = res.data;
showSuccess('操作成功完成!'); if (success) {
await loadUsers(activePage); showSuccess('操作成功完成!');
} else { await loadUsers(activePage);
showError(message); } else {
} showError(message);
}
return res.data; return res.data;
} catch (error) {
return;
}
}; };
// 处理刷新 // 处理刷新