mirror of
https://github.com/Zhuym07/Tsumugiboshi.git
synced 2025-05-20 22:07:27 +08:00
删除不再使用的常量、工具函数和样式文件
This commit is contained in:
parent
1a471bc07e
commit
569b30e921
197
index.html
197
index.html
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>API调试工具</title>
|
<title>TsumugiBoshi|纺星</title>
|
||||||
<!-- Material Icons -->
|
<!-- Material Icons -->
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
|
||||||
@ -25,8 +25,16 @@
|
|||||||
}
|
}
|
||||||
#root {
|
#root {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
pre { background: #f5f5f5; padding: 10px; border-radius: 4px; }
|
|
||||||
.api-description {
|
.api-description {
|
||||||
margin: 8px 0 16px !important;
|
margin: 8px 0 16px !important;
|
||||||
color: #666;
|
color: #666;
|
||||||
@ -36,6 +44,7 @@
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border-left: 4px solid #1976d2;
|
border-left: 4px solid #1976d2;
|
||||||
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
.selected-backend { font-weight: bold; color: #1976d2; }
|
.selected-backend { font-weight: bold; color: #1976d2; }
|
||||||
.scrollable-tabs {
|
.scrollable-tabs {
|
||||||
@ -63,13 +72,37 @@
|
|||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
.backend-selector {
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.MuiContainer-root {
|
.MuiContainer-root {
|
||||||
padding: 12px !important;
|
padding: 8px !important;
|
||||||
}
|
}
|
||||||
.MuiPaper-root {
|
.MuiPaper-root {
|
||||||
padding: 12px !important;
|
padding: 12px !important;
|
||||||
}
|
}
|
||||||
|
.MuiTypography-h4 {
|
||||||
|
font-size: 1.5rem !important;
|
||||||
|
}
|
||||||
|
.MuiTypography-h6 {
|
||||||
|
font-size: 1.1rem !important;
|
||||||
|
}
|
||||||
|
.MuiTab-root {
|
||||||
|
min-height: 48px !important;
|
||||||
|
padding: 6px 12px !important;
|
||||||
|
font-size: 0.8rem !important;
|
||||||
|
}
|
||||||
|
.MuiInputBase-input {
|
||||||
|
font-size: 0.9rem !important;
|
||||||
|
}
|
||||||
|
.backend-selector {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
h4.MuiTypography-root {
|
h4.MuiTypography-root {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
@ -87,7 +120,7 @@
|
|||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<footer>
|
<footer>
|
||||||
<Typography variant="body2" color="textSecondary">
|
<Typography variant="body2" color="textSecondary">
|
||||||
© 2023 Tsumugiboshi. All rights reserved.
|
© 2025 Tsumugiboshi. All rights reserved.
|
||||||
<br />
|
<br />
|
||||||
</Typography>
|
</Typography>
|
||||||
</footer>
|
</footer>
|
||||||
@ -367,97 +400,14 @@
|
|||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
<Container maxWidth="md" style={{ marginTop: '1rem', marginBottom: '2rem' }}>
|
<Container maxWidth="md" style={{ marginTop: '1rem', marginBottom: '2rem' }}>
|
||||||
{/* 后端地址选择器 */}
|
|
||||||
<FormControl fullWidth style={{ marginBottom: '2rem' }}>
|
|
||||||
<InputLabel>选择后端地址</InputLabel>
|
|
||||||
<Select
|
|
||||||
value={apiBase}
|
|
||||||
onChange={handleApiBaseChange}
|
|
||||||
label="选择后端地址"
|
|
||||||
>
|
|
||||||
{/* 默认后端 */}
|
|
||||||
{PRESET_BACKENDS.map((backend) => (
|
|
||||||
<MenuItem key={backend.value} value={backend.value}>
|
|
||||||
{backend.label} - {backend.value}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{/* 分割线 */}
|
|
||||||
{backends.some(b => !PRESET_BACKENDS.some(preset => preset.value === b.value)) && (
|
|
||||||
<MenuItem disabled>
|
|
||||||
<hr style={{ width: '100%', margin: '4px 0' }} />
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 自定义后端 */}
|
|
||||||
{backends
|
|
||||||
.filter(b => !PRESET_BACKENDS.some(preset => preset.value === b.value))
|
|
||||||
.map((backend) => (
|
|
||||||
<MenuItem key={backend.value} value={backend.value}>
|
|
||||||
<Box display="flex" justifyContent="space-between" width="100%">
|
|
||||||
<span>{backend.label} - {backend.value}</span>
|
|
||||||
<Button
|
|
||||||
size="small"
|
|
||||||
color="error"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
handleDeleteBackend(backend.value);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
color="primary"
|
|
||||||
style={{ marginTop: '1rem' }}
|
|
||||||
onClick={handleAddBackend}
|
|
||||||
>
|
|
||||||
添加自定义后端
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
{/* 添加自定义后端对话框 */}
|
|
||||||
<Dialog open={isDialogOpen} onClose={handleDialogClose}>
|
|
||||||
<DialogTitle>添加自定义后端</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
label="后端名称"
|
|
||||||
value={newBackend.label}
|
|
||||||
onChange={(e) => setNewBackend({ ...newBackend, label: e.target.value })}
|
|
||||||
style={{ marginBottom: '1rem' }}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
label="后端地址"
|
|
||||||
value={newBackend.value}
|
|
||||||
onChange={(e) => setNewBackend({ ...newBackend, value: e.target.value })}
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={handleDialogClose}>取消</Button>
|
|
||||||
<Button onClick={handleSaveBackend} color="primary">保存</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
{/* Snackbar 提示 */}
|
|
||||||
<Snackbar
|
|
||||||
open={snackbarOpen}
|
|
||||||
autoHideDuration={3000}
|
|
||||||
onClose={handleSnackbarClose}
|
|
||||||
>
|
|
||||||
<Alert onClose={handleSnackbarClose} severity="success">
|
|
||||||
{snackbarMessage}
|
|
||||||
</Alert>
|
|
||||||
</Snackbar>
|
|
||||||
|
|
||||||
<Typography variant="h4" gutterBottom>
|
<Typography variant="h4" gutterBottom>
|
||||||
API调试工具
|
💫TsumugiBoshi
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="subtitle1" gutterBottom>
|
||||||
|
神秘API调试工具
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
|
{/* API表单部分 */}
|
||||||
<Paper elevation={3} style={{ padding: '1rem', marginBottom: '1rem' }}>
|
<Paper elevation={3} style={{ padding: '1rem', marginBottom: '1rem' }}>
|
||||||
<div className="tabs-container">
|
<div className="tabs-container">
|
||||||
<Box className="scrollable-tabs">
|
<Box className="scrollable-tabs">
|
||||||
@ -523,19 +473,78 @@
|
|||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
{response && (
|
{response && (
|
||||||
<Paper elevation={3} style={{ padding: '1rem' }}>
|
<Paper elevation={3} style={{ padding: '1rem', marginBottom: '1rem' }}>
|
||||||
<Typography variant="h6" gutterBottom>响应结果:</Typography>
|
<Typography variant="h6" gutterBottom>响应结果:</Typography>
|
||||||
<pre style={{
|
<pre style={{
|
||||||
whiteSpace: 'pre-wrap',
|
whiteSpace: 'pre-wrap',
|
||||||
wordWrap: 'break-word',
|
wordWrap: 'break-word',
|
||||||
backgroundColor: '#f5f5f5',
|
backgroundColor: '#f5f5f5',
|
||||||
padding: '1rem',
|
padding: '1rem',
|
||||||
borderRadius: '4px'
|
borderRadius: '4px',
|
||||||
|
fontSize: '0.9rem'
|
||||||
}}>
|
}}>
|
||||||
{response}
|
{response}
|
||||||
</pre>
|
</pre>
|
||||||
</Paper>
|
</Paper>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* 移动后端选择器到底部 */}
|
||||||
|
<Paper elevation={3} className="backend-selector">
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
后端设置
|
||||||
|
</Typography>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<InputLabel>选择后端地址</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={apiBase}
|
||||||
|
onChange={handleApiBaseChange}
|
||||||
|
label="选择后端地址"
|
||||||
|
>
|
||||||
|
{/* 默认后端 */}
|
||||||
|
{PRESET_BACKENDS.map((backend) => (
|
||||||
|
<MenuItem key={backend.value} value={backend.value}>
|
||||||
|
{backend.label} - {backend.value}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* 分割线 */}
|
||||||
|
{backends.some(b => !PRESET_BACKENDS.some(preset => preset.value === b.value)) && (
|
||||||
|
<MenuItem disabled>
|
||||||
|
<hr style={{ width: '100%', margin: '4px 0' }} />
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 自定义后端 */}
|
||||||
|
{backends
|
||||||
|
.filter(b => !PRESET_BACKENDS.some(preset => preset.value === b.value))
|
||||||
|
.map((backend) => (
|
||||||
|
<MenuItem key={backend.value} value={backend.value}>
|
||||||
|
<Box display="flex" justifyContent="space-between" width="100%">
|
||||||
|
<span>{backend.label} - {backend.value}</span>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
color="error"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleDeleteBackend(backend.value);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
style={{ marginTop: '1rem' }}
|
||||||
|
onClick={handleAddBackend}
|
||||||
|
>
|
||||||
|
添加自定义后端
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</Paper>
|
||||||
</Container>
|
</Container>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
|
@ -1,228 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import {
|
|
||||||
Tabs,
|
|
||||||
Tab,
|
|
||||||
TextField,
|
|
||||||
Button,
|
|
||||||
Paper,
|
|
||||||
Typography,
|
|
||||||
Grid,
|
|
||||||
Box,
|
|
||||||
Select,
|
|
||||||
MenuItem,
|
|
||||||
InputLabel,
|
|
||||||
FormControl,
|
|
||||||
Dialog,
|
|
||||||
DialogTitle,
|
|
||||||
DialogContent,
|
|
||||||
DialogActions,
|
|
||||||
Snackbar,
|
|
||||||
Alert,
|
|
||||||
Radio,
|
|
||||||
RadioGroup,
|
|
||||||
FormControlLabel
|
|
||||||
} from '@mui/material';
|
|
||||||
import { setCookie } from '../utils/cookies';
|
|
||||||
|
|
||||||
function ApiTabs({
|
|
||||||
tabValue,
|
|
||||||
setTabValue,
|
|
||||||
qrInput,
|
|
||||||
setQrInput,
|
|
||||||
userId,
|
|
||||||
setUserId,
|
|
||||||
response,
|
|
||||||
setResponse,
|
|
||||||
musicData,
|
|
||||||
setMusicData,
|
|
||||||
apiBase,
|
|
||||||
setApiBase,
|
|
||||||
backends,
|
|
||||||
setBackends,
|
|
||||||
isDialogOpen,
|
|
||||||
setIsDialogOpen,
|
|
||||||
newBackend,
|
|
||||||
setNewBackend,
|
|
||||||
snackbarOpen,
|
|
||||||
setSnackbarOpen,
|
|
||||||
snackbarMessage,
|
|
||||||
setSnackbarMessage
|
|
||||||
}) {
|
|
||||||
const handleTabChange = (event, newValue) => {
|
|
||||||
setTabValue(newValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleUserIdChange = (event) => {
|
|
||||||
const value = event.target.value;
|
|
||||||
setUserId(value);
|
|
||||||
setCookie('userId', value);
|
|
||||||
setMusicData(prev => ({ ...prev, userId: parseInt(value) || 0 }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleBackendChange = (event) => {
|
|
||||||
const value = event.target.value;
|
|
||||||
setApiBase(value);
|
|
||||||
localStorage.setItem('apiBase', value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAddBackend = () => {
|
|
||||||
if (!newBackend.label || !newBackend.value) {
|
|
||||||
setSnackbarMessage('请填写完整的后端信息');
|
|
||||||
setSnackbarOpen(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedBackends = [...backends, newBackend];
|
|
||||||
setBackends(updatedBackends);
|
|
||||||
localStorage.setItem('customBackends', JSON.stringify(
|
|
||||||
updatedBackends.slice(PRESET_BACKENDS.length)
|
|
||||||
));
|
|
||||||
setIsDialogOpen(false);
|
|
||||||
setNewBackend({ label: '', value: '' });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Paper elevation={3} sx={{ p: 3, mb: 4 }}>
|
|
||||||
<Typography variant="h4" gutterBottom>
|
|
||||||
API调试工具
|
|
||||||
</Typography>
|
|
||||||
<div className="tabs-container">
|
|
||||||
<div className="scrollable-tabs">
|
|
||||||
<Tabs
|
|
||||||
value={tabValue}
|
|
||||||
onChange={handleTabChange}
|
|
||||||
variant="scrollable"
|
|
||||||
scrollButtons="auto"
|
|
||||||
>
|
|
||||||
<Tab label="二维码解析" />
|
|
||||||
<Tab label="音乐数据" />
|
|
||||||
</Tabs>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Box sx={{ mt: 3 }}>
|
|
||||||
<Grid container spacing={3}>
|
|
||||||
<Grid item xs={12} md={6}>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
label="用户ID"
|
|
||||||
value={userId}
|
|
||||||
onChange={handleUserIdChange}
|
|
||||||
variant="outlined"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12} md={6}>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<InputLabel>后端环境</InputLabel>
|
|
||||||
<Select
|
|
||||||
value={apiBase}
|
|
||||||
onChange={handleBackendChange}
|
|
||||||
label="后端环境"
|
|
||||||
>
|
|
||||||
{backends.map((backend, index) => (
|
|
||||||
<MenuItem key={index} value={backend.value}>
|
|
||||||
{backend.label}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
{tabValue === 0 && (
|
|
||||||
<Box sx={{ mt: 3 }}>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
multiline
|
|
||||||
rows={4}
|
|
||||||
label="二维码内容"
|
|
||||||
value={qrInput}
|
|
||||||
onChange={(e) => setQrInput(e.target.value)}
|
|
||||||
variant="outlined"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{tabValue === 1 && (
|
|
||||||
<Box sx={{ mt: 3 }}>
|
|
||||||
<Grid container spacing={2}>
|
|
||||||
{Object.entries(musicData.music).map(([key, value]) => (
|
|
||||||
<Grid item xs={12} sm={6} md={4} key={key}>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
label={key}
|
|
||||||
type="number"
|
|
||||||
value={value}
|
|
||||||
onChange={(e) => {
|
|
||||||
const newValue = parseInt(e.target.value) || 0;
|
|
||||||
setMusicData(prev => ({
|
|
||||||
...prev,
|
|
||||||
music: {
|
|
||||||
...prev.music,
|
|
||||||
[key]: newValue
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}}
|
|
||||||
variant="outlined"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{response && (
|
|
||||||
<Box sx={{ mt: 3 }}>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
响应结果
|
|
||||||
</Typography>
|
|
||||||
<pre>{JSON.stringify(response, null, 2)}</pre>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</Paper>
|
|
||||||
|
|
||||||
<Dialog open={isDialogOpen} onClose={() => setIsDialogOpen(false)}>
|
|
||||||
<DialogTitle>添加自定义后端</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<TextField
|
|
||||||
autoFocus
|
|
||||||
margin="dense"
|
|
||||||
label="名称"
|
|
||||||
fullWidth
|
|
||||||
value={newBackend.label}
|
|
||||||
onChange={(e) => setNewBackend(prev => ({ ...prev, label: e.target.value }))}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
margin="dense"
|
|
||||||
label="地址"
|
|
||||||
fullWidth
|
|
||||||
value={newBackend.value}
|
|
||||||
onChange={(e) => setNewBackend(prev => ({ ...prev, value: e.target.value }))}
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={() => setIsDialogOpen(false)}>取消</Button>
|
|
||||||
<Button onClick={handleAddBackend}>添加</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
<Snackbar
|
|
||||||
open={snackbarOpen}
|
|
||||||
autoHideDuration={6000}
|
|
||||||
onClose={() => setSnackbarOpen(false)}
|
|
||||||
>
|
|
||||||
<Alert
|
|
||||||
onClose={() => setSnackbarOpen(false)}
|
|
||||||
severity="error"
|
|
||||||
sx={{ width: '100%' }}
|
|
||||||
>
|
|
||||||
{snackbarMessage}
|
|
||||||
</Alert>
|
|
||||||
</Snackbar>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ApiTabs;
|
|
@ -1,79 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import { Container, Typography } from '@mui/material';
|
|
||||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
|
||||||
import ApiTabs from './ApiTabs';
|
|
||||||
import { PRESET_BACKENDS } from '../constants';
|
|
||||||
import { getCookie, setCookie } from '../utils/cookies';
|
|
||||||
|
|
||||||
const theme = createTheme();
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
const [tabValue, setTabValue] = useState(0);
|
|
||||||
const [qrInput, setQrInput] = useState('');
|
|
||||||
const [userId, setUserId] = useState(getCookie('userId') || '');
|
|
||||||
const [response, setResponse] = useState('');
|
|
||||||
const [musicData, setMusicData] = useState({
|
|
||||||
userId: parseInt(userId) || 0,
|
|
||||||
music: {
|
|
||||||
musicId: 0,
|
|
||||||
level: 0,
|
|
||||||
achievement: 0,
|
|
||||||
playCount: 0,
|
|
||||||
comboStatus: 0,
|
|
||||||
syncStatus: 0,
|
|
||||||
deluxscoreMax: 0,
|
|
||||||
scoreRank: 0
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const [apiBase, setApiBase] = useState(
|
|
||||||
localStorage.getItem('apiBase') || PRESET_BACKENDS[0].value
|
|
||||||
);
|
|
||||||
const [backends, setBackends] = useState([
|
|
||||||
...PRESET_BACKENDS,
|
|
||||||
...JSON.parse(localStorage.getItem('customBackends') || '[]')
|
|
||||||
]);
|
|
||||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
||||||
const [newBackend, setNewBackend] = useState({ label: '', value: '' });
|
|
||||||
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
|
||||||
const [snackbarMessage, setSnackbarMessage] = useState('');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ThemeProvider theme={theme}>
|
|
||||||
<div id="root">
|
|
||||||
<Container maxWidth="md" sx={{ mt: 4, mb: 4 }}>
|
|
||||||
<ApiTabs
|
|
||||||
tabValue={tabValue}
|
|
||||||
setTabValue={setTabValue}
|
|
||||||
qrInput={qrInput}
|
|
||||||
setQrInput={setQrInput}
|
|
||||||
userId={userId}
|
|
||||||
setUserId={setUserId}
|
|
||||||
response={response}
|
|
||||||
setResponse={setResponse}
|
|
||||||
musicData={musicData}
|
|
||||||
setMusicData={setMusicData}
|
|
||||||
apiBase={apiBase}
|
|
||||||
setApiBase={setApiBase}
|
|
||||||
backends={backends}
|
|
||||||
setBackends={setBackends}
|
|
||||||
isDialogOpen={isDialogOpen}
|
|
||||||
setIsDialogOpen={setIsDialogOpen}
|
|
||||||
newBackend={newBackend}
|
|
||||||
setNewBackend={setNewBackend}
|
|
||||||
snackbarOpen={snackbarOpen}
|
|
||||||
setSnackbarOpen={setSnackbarOpen}
|
|
||||||
snackbarMessage={snackbarMessage}
|
|
||||||
setSnackbarMessage={setSnackbarMessage}
|
|
||||||
/>
|
|
||||||
</Container>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
<Typography variant="body2" color="textSecondary">
|
|
||||||
© 2023 Tsumugiboshi. All rights reserved.
|
|
||||||
</Typography>
|
|
||||||
</footer>
|
|
||||||
</ThemeProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
@ -1,5 +0,0 @@
|
|||||||
export const PRESET_BACKENDS = [
|
|
||||||
{ label: "开发环境", value: "http://dev-api.example.com" },
|
|
||||||
{ label: "测试环境", value: "http://test-api.example.com" },
|
|
||||||
{ label: "生产环境", value: "http://api.example.com" }
|
|
||||||
];
|
|
@ -1,85 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
#root {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
background: #f5f5f5;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.api-description {
|
|
||||||
margin: 8px 0 16px !important;
|
|
||||||
color: #666;
|
|
||||||
white-space: pre-line;
|
|
||||||
line-height: 1.5;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
padding: 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border-left: 4px solid #1976d2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-backend {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #1976d2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrollable-tabs {
|
|
||||||
max-width: calc(100% - 48px);
|
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-button {
|
|
||||||
position: absolute !important;
|
|
||||||
right: 0;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
margin-top: auto;
|
|
||||||
padding: 16px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.MuiContainer-root {
|
|
||||||
padding: 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.MuiPaper-root {
|
|
||||||
padding: 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4.MuiTypography-root {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrollable-tabs::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.api-description {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
export function setCookie(name, value, days = 30) {
|
|
||||||
const d = new Date();
|
|
||||||
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
|
||||||
const expires = `expires=${d.toUTCString()}`;
|
|
||||||
document.cookie = `${name}=${value};${expires};path=/`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCookie(name) {
|
|
||||||
const nameEQ = `${name}=`;
|
|
||||||
const ca = document.cookie.split(';');
|
|
||||||
for (let i = 0; i < ca.length; i++) {
|
|
||||||
let c = ca[i];
|
|
||||||
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
|
|
||||||
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteCookie(name) {
|
|
||||||
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/`;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user