Artifact 27da4e7c0d09d3f5c27e737de02720f3a3e23a68f94d125ce1c9ddee1378583e:
- File
web/src/pages/Account.tsx
— part of check-in
[dfa747c1ad]
at
2026-10-23 06:08:28
on branch trunk
— Web 管理控制台
- 用 Vite 和 React 做完整的 Web 端:登录、按权限显示菜单、切换当前作业仓库 - 覆盖来肯同步、仓库、库位规划、商品、销售订单、采购入库与批次码、采购订单、库存、用户授权和审计日志 - 开发时由 Vite 把 /api 代理到本机后端 - SQLite 写入和页面读取冲突时自动重试,避免请求进程因数据库忙碌直接崩溃 (user: pluto size: 2241)
import { useState, type FormEvent } from 'react' import { api } from '../api' import { useSession } from '../session' import { Banner, Field, Page } from '../ui' export function Account() { const { user } = useSession() const [oldPassword, setOldPassword] = useState('') const [newPassword, setNewPassword] = useState('') const [error, setError] = useState('') const [ok, setOk] = useState('') async function onSubmit(event: FormEvent) { event.preventDefault() setError('') setOk('') try { await api('/api/auth/password', { method: 'POST', body: JSON.stringify({ old_password: oldPassword, new_password: newPassword }), }) setOldPassword('') setNewPassword('') setOk('密码已修改,其他终端的登录已失效') } catch (err) { setError(err instanceof Error ? err.message : '修改失败') } } return ( <Page title="账号"> <div className="cards"> <div className="card"> <span>姓名</span> <strong>{user?.display_name}</strong> </div> <div className="card"> <span>账号</span> <strong>{user?.username}</strong> </div> <div className="card"> <span>角色</span> <strong>{user?.roles.join('、')}</strong> </div> <div className="card"> <span>本次登录到期</span> <strong>{user?.expires_at}</strong> </div> </div> <form className="panel" onSubmit={onSubmit}> <h2>修改密码</h2> <Banner kind="error" text={error} /> <Banner kind="ok" text={ok} /> <Field label="原密码"> <input type="password" value={oldPassword} onChange={(event) => setOldPassword(event.target.value)} /> </Field> <Field label="新密码(至少 8 位)"> <input type="password" value={newPassword} onChange={(event) => setNewPassword(event.target.value)} /> </Field> <button type="submit" disabled={newPassword.length < 8 || !oldPassword}> 保存新密码 </button> </form> </Page> ) }