ForceChangePassword.tsx 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { useState } from 'react'
  2. import { Card, Form, Input, Button, Typography, message, Result } from 'antd'
  3. import { LockOutlined } from '@ant-design/icons'
  4. import { useNavigate } from 'react-router-dom'
  5. import { useAppStore } from '../store'
  6. import api from '../api/client'
  7. const { Title, Text } = Typography
  8. export default function ForceChangePassword() {
  9. const [loading, setLoading] = useState(false)
  10. const [done, setDone] = useState(false)
  11. const navigate = useNavigate()
  12. const { user, setAuth, token } = useAppStore()
  13. const handleSubmit = async (values: { old_password: string; new_password: string; confirm: string }) => {
  14. if (values.new_password !== values.confirm) {
  15. message.error('两次密码不一致')
  16. return
  17. }
  18. setLoading(true)
  19. try {
  20. await api.put('/auth/password', {
  21. old_password: values.old_password,
  22. new_password: values.new_password,
  23. })
  24. // Update user in store to clear must_change_password
  25. if (user && token) {
  26. setAuth(token, { ...user, must_change_password: false })
  27. }
  28. setDone(true)
  29. } catch (err: any) {
  30. message.error(err?.response?.data?.message || err?.data?.message || '修改失败')
  31. } finally {
  32. setLoading(false)
  33. }
  34. }
  35. if (done) {
  36. return (
  37. <div style={{ minHeight: '100vh', display: 'flex', justifyContent: 'center', alignItems: 'center', background: '#f0f2f5' }}>
  38. <Card style={{ width: 420, borderRadius: 12 }}>
  39. <Result
  40. status="success"
  41. title="密码已修改"
  42. subTitle="请使用新密码登录系统"
  43. extra={
  44. <Button type="primary" onClick={() => navigate('/dashboard')}>
  45. 进入系统
  46. </Button>
  47. }
  48. />
  49. </Card>
  50. </div>
  51. )
  52. }
  53. return (
  54. <div style={{ minHeight: '100vh', display: 'flex', justifyContent: 'center', alignItems: 'center', background: '#f0f2f5' }}>
  55. <Card style={{ width: 420, borderRadius: 12, boxShadow: '0 4px 16px rgba(0,0,0,0.1)' }}>
  56. <div style={{ textAlign: 'center', marginBottom: 24 }}>
  57. <LockOutlined style={{ fontSize: 40, color: '#faad14', marginBottom: 12 }} />
  58. <Title level={4} style={{ margin: 0 }}>首次登录需修改密码</Title>
  59. <Text type="secondary">为确保账号安全,请设置新密码</Text>
  60. </div>
  61. <Form onFinish={handleSubmit} layout="vertical">
  62. <Form.Item name="old_password" label="当前密码" rules={[{ required: true }]}>
  63. <Input.Password placeholder="输入当前密码" />
  64. </Form.Item>
  65. <Form.Item name="new_password" label="新密码"
  66. rules={[{ required: true, min: 8, message: '至少8位,包含大小写和数字' }]}>
  67. <Input.Password placeholder="至少8位,包含大小写字母和数字" />
  68. </Form.Item>
  69. <Form.Item name="confirm" label="确认新密码" rules={[{ required: true }]}>
  70. <Input.Password placeholder="再次输入新密码" />
  71. </Form.Item>
  72. <Form.Item>
  73. <Button type="primary" htmlType="submit" loading={loading} block style={{ height: 44 }}>
  74. 修改密码
  75. </Button>
  76. </Form.Item>
  77. </Form>
  78. </Card>
  79. </div>
  80. )
  81. }