update nginx

Change-Id: Ia5695f05d68dcae340c97a9cdd923ce5b56455d7
diff --git a/src/pages/register/index.jsx b/src/pages/register/index.jsx
new file mode 100644
index 0000000..a91d63b
--- /dev/null
+++ b/src/pages/register/index.jsx
@@ -0,0 +1,115 @@
+import React, { useState } from 'react'
+import { connect } from 'dva'
+import { history } from 'umi'
+import { Form, Input, Button, message } from 'antd'
+import { UserOutlined, LockOutlined } from '@ant-design/icons'
+import styles from './index.less'
+
+const RegisterPage = ({ dispatch, register }) => {
+  const [form] = Form.useForm()
+  
+  const onFinish = values => {
+    dispatch({
+      type: 'register/submit',
+      payload: values
+    }).then(() => {
+      if (!register.error) {
+        message.success('注册成功')
+        history.push('/user/login')
+      } else {
+        message.error(register.error)
+      }
+    })
+  }
+  
+  return (
+    <div className={styles.container}>
+      <div className={styles.content}>
+        <div className={styles.top}>
+          <div className={styles.header}>
+            <span className={styles.title}>用户注册</span>
+          </div>
+        </div>
+        
+        <div className={styles.main}>
+          <Form
+            form={form}
+            name="register"
+            onFinish={onFinish}
+            scrollToFirstError
+          >
+            <Form.Item
+              name="username"
+              rules={[
+                { required: true, message: '请输入用户名!' },
+                { min: 4, message: '用户名至少4个字符' },
+                { max: 20, message: '用户名最多20个字符' },
+                { pattern: /^[a-zA-Z0-9_]+$/, message: '用户名只能包含字母、数字和下划线' }
+              ]}
+            >
+              <Input
+                prefix={<UserOutlined className={styles.prefixIcon} />}
+                placeholder="用户名"
+                size="large"
+              />
+            </Form.Item>
+            
+            <Form.Item
+              name="password"
+              rules={[
+                { required: true, message: '请输入密码!' },
+                { min: 6, message: '密码至少6个字符' },
+                { max: 20, message: '密码最多20个字符' }
+              ]}
+            >
+              <Input.Password
+                prefix={<LockOutlined className={styles.prefixIcon} />}
+                type="password"
+                placeholder="密码"
+                size="large"
+              />
+            </Form.Item>
+            
+            <Form.Item
+              name="confirmPassword"
+              dependencies={['password']}
+              rules={[
+                { required: true, message: '请确认密码!' },
+                ({ getFieldValue }) => ({
+                  validator(_, value) {
+                    if (!value || getFieldValue('password') === value) {
+                      return Promise.resolve()
+                    }
+                    return Promise.reject(new Error('两次输入的密码不一致!'))
+                  }
+                })
+              ]}
+            >
+              <Input.Password
+                prefix={<LockOutlined className={styles.prefixIcon} />}
+                type="password"
+                placeholder="确认密码"
+                size="large"
+              />
+            </Form.Item>
+            
+            <Form.Item>
+              <Button
+                type="primary"
+                htmlType="submit"
+                size="large"
+                className={styles.submit}
+                loading={register.submitting}
+                block
+              >
+                注册
+              </Button>
+            </Form.Item>
+          </Form>
+        </div>
+      </div>
+    </div>
+  )
+}
+
+export default connect(({ register }) => ({ register }))(RegisterPage)
\ No newline at end of file
diff --git a/src/pages/register/index.less b/src/pages/register/index.less
new file mode 100644
index 0000000..a6337d6
--- /dev/null
+++ b/src/pages/register/index.less
@@ -0,0 +1,52 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  overflow: auto;
+  background: #f0f2f5;
+  background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg');
+  background-repeat: no-repeat;
+  background-position: center 110px;
+  background-size: 100%;
+}
+
+.content {
+  flex: 1;
+  padding: 32px 0;
+}
+
+.top {
+  text-align: center;
+}
+
+.header {
+  height: 44px;
+  line-height: 44px;
+  
+  .title {
+    position: relative;
+    top: 2px;
+    color: rgba(0, 0, 0, 0.85);
+    font-weight: 600;
+    font-size: 33px;
+    font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif;
+  }
+}
+
+.main {
+  width: 368px;
+  margin: 0 auto;
+  
+  @media screen and (max-width: 576px) {
+    width: 95%;
+  }
+  
+  .prefixIcon {
+    color: rgba(0, 0, 0, 0.25);
+  }
+  
+  .submit {
+    width: 100%;
+    margin-top: 24px;
+  }
+}
\ No newline at end of file
diff --git a/src/pages/register/model.js b/src/pages/register/model.js
new file mode 100644
index 0000000..891869e
--- /dev/null
+++ b/src/pages/register/model.js
@@ -0,0 +1,65 @@
+import * as registerApi from '@/api/system/register'
+
+export default {
+  namespace: 'register',
+  
+  state: {
+    submitting: false,
+    error: null
+  },
+  
+  effects: {
+    *submit({ payload }, { call, put }) {
+      yield put({
+        type: 'changeSubmitting',
+        payload: true
+      })
+      
+      try {
+        const response = yield call(registerApi.register, payload)
+        
+        if (response.code === 200) {
+          yield put({
+            type: 'registerSuccess'
+          })
+        } else {
+          yield put({
+            type: 'registerFailure',
+            payload: response.msg
+          })
+        }
+      } catch (error) {
+        yield put({
+          type: 'registerFailure',
+          payload: error.response?.data?.msg || '注册失败'
+        })
+      }
+      
+      yield put({
+        type: 'changeSubmitting',
+        payload: false
+      })
+    }
+  },
+  
+  reducers: {
+    changeSubmitting(state, { payload }) {
+      return {
+        ...state,
+        submitting: payload
+      }
+    },
+    registerSuccess(state) {
+      return {
+        ...state,
+        error: null
+      }
+    },
+    registerFailure(state, { payload }) {
+      return {
+        ...state,
+        error: payload
+      }
+    }
+  }
+}
\ No newline at end of file