🎨 更新 React 登录界面:多身份选择

功能:
- 身份模式选择(人类/龙虾/双重)
- 龙虾选择下拉框
- 自动扫描本机龙虾
- 登录时保存 sessions 信息

界面:
- 单选按钮选择身份模式
- 根据模式显示/隐藏龙虾选择
- 显示龙虾列表(从实例扫描)
This commit is contained in:
2026-04-04 12:57:24 +08:00
parent 97da46b219
commit 598e55794a

View File

@@ -14,17 +14,49 @@ axios.interceptors.request.use(config => {
function LoginPage() {
const [username, setUsername] = useState('test');
const [password, setPassword] = useState('test123');
const [loginMode, setLoginMode] = useState('human_only');
const [agents, setAgents] = useState([]);
const [selectedAgent, setSelectedAgent] = useState('');
const navigate = useNavigate();
// 扫描本机龙虾
useEffect(() => {
scanAgents();
}, []);
const scanAgents = async () => {
try {
const res = await axios.get(`${API_BASE}/user/scan-local-agents/`);
setAgents(res.data.agents || []);
if (res.data.agents?.length > 0) {
setSelectedAgent(res.data.agents[0].agent_id);
}
} catch (error) {
console.error('扫描龙虾失败:', error);
}
};
const handleLogin = async (e) => {
e.preventDefault();
try {
const res = await axios.post(`${API_BASE}/auth/login/`, { username, password });
const payload = {
username,
password,
login_mode: loginMode
};
if (loginMode !== 'human_only' && selectedAgent) {
payload.selected_agent_id = selectedAgent;
}
const res = await axios.post(`${API_BASE}/auth/login/`, payload);
localStorage.setItem('token', res.data.token);
localStorage.setItem('user', JSON.stringify(res.data.user));
localStorage.setItem('sessions', JSON.stringify(res.data.sessions));
localStorage.setItem('login_mode', res.data.login_mode);
navigate('/meetings');
} catch (error) {
alert('登录失败:' + (error.response?.data?.detail || error.message));
alert('登录失败:' + (error.response?.data?.detail || error.response?.data?.error || error.message));
}
};
@@ -32,9 +64,67 @@ function LoginPage() {
<div style={styles.center}>
<div style={styles.card}>
<h1 style={styles.title}>🏛 龙虾议事厅</h1>
<form onSubmit={handleLogin} style={styles.form}>
<form onSubmit={handleLogin} style={{...styles.form, flexDirection: 'column'}}>
<input type="text" placeholder="用户名" value={username} onChange={e => setUsername(e.target.value)} style={styles.input} required />
<input type="password" placeholder="密码" value={password} onChange={e => setPassword(e.target.value)} style={styles.input} required />
{/* 身份模式选择 */}
<div style={{margin: '15px 0'}}>
<label style={{display: 'block', marginBottom: '10px', fontWeight: '600'}}>登录身份</label>
<label style={{display: 'block', marginBottom: '8px', cursor: 'pointer'}}>
<input
type="radio"
name="loginMode"
value="human_only"
checked={loginMode === 'human_only'}
onChange={e => setLoginMode(e.target.value)}
/>
{' '}👤 人类身份纯人类参会
</label>
<label style={{display: 'block', marginBottom: '8px', cursor: 'pointer'}}>
<input
type="radio"
name="loginMode"
value="agent_only"
checked={loginMode === 'agent_only'}
onChange={e => setLoginMode(e.target.value)}
/>
{' '}🦞 龙虾身份Agent 参会
</label>
<label style={{display: 'block', marginBottom: '8px', cursor: 'pointer'}}>
<input
type="radio"
name="loginMode"
value="both"
checked={loginMode === 'both'}
onChange={e => setLoginMode(e.target.value)}
/>
{' '}👤+ 双重身份人类 + 龙虾
</label>
</div>
{/* 龙虾选择 */}
{loginMode !== 'human_only' && (
<div style={{margin: '15px 0'}}>
<label style={{display: 'block', marginBottom: '8px', fontWeight: '600'}}>选择龙虾</label>
<select
value={selectedAgent}
onChange={e => setSelectedAgent(e.target.value)}
style={styles.input}
>
{agents.length === 0 ? (
<option value="">未找到龙虾</option>
) : (
agents.map(a => (
<option key={a.agent_id} value={a.agent_id}>
{a.agent_id} ({a.instance_name})
</option>
))
)}
</select>
</div>
)}
<button type="submit" style={styles.btn}>登录</button>
</form>
</div>