项目：11-Vue3管理系统开发个人信息，修改密码页面

## 一：管理员相关的增删改查
⭐把默认的路由重定向到/login，让用户每次启动项目后重新登录
```java
{path: '/', redirect: '/login'},
```
⭐三步骤
#### 1.sql--建表
#### 2.后端接口
实体类--controller--service--mapper--mapper.xml
⭐登录（管理员/员工）
```java
// 管理员/员工登录
 @PostMapping("/login")
public Result login(@RequestBody Account account){
        Account result = null;
        if("ADMIN".equals(account.getRole())){  // 管理员登录
            result = adminService.login(account);
        }else if ("EMP".equals(account.getRole())) {
            result = employeeService.login(account);
        }else {
            throw new CustomException("500","非法输入");
        }
        return Result.success(result);
    }
```
#### 3.前端页面
页面--路由--菜单
## 二：退出登录逻辑
```java
<el-menu-item @click="logout">
    <el-icon><SwitchButton /></el-icon>
    退出登录
</el-menu-item>
```
```java
const logout = () => {
  localStorage.removeItem('xm-pro-user')  // 清除当前登录的用户缓存数据
  location.href = '/login'  // 退出到登录页面
}
```
## 三：个人中心页面
#### 1.子组件发送请求更新父组件的数据
```java
const emit = defineEmits(['updateUser'])
    // 更新缓存数据
    localStorage.setItem('xm-pro-user',JSON.stringify(data.form))
emit('updateUser')
```
```java
const updateUser = () => {
  if (data.user.role === 'EMP') {
    request.put('/employee/update',data.form).then(res => {
      if(res.code === '200' ){
          ElMessage.success('更新成功')
          // 更新缓存数据
          localStorage.setItem('xm-pro-user',JSON.stringify(data.form))
          // chu'fa
          emit('updateUser')
      }
    })
  }else{
  }
}
```
```java
<div style="flex: 1;width: 0;background-color: #f5f7ff;padding: 10px">
    <RouterView @updateUser = 'updateUser'/>
</div>
```
```java
const updateUser = () => {
  data.user = JSON.parse(localStorage.getItem('xm-pro-user'))
}
```
#### 2.源码
```java
<template>
  <div class="card" style="width: 50%;padding: 40px 20px">
    <el-form ref="formRef" :rules="data.rules" :model="data.form" label-width="80px"
      style="padding-right: 40px;padding-top: 20px">
      <el-form-item label="账号" prop="username">
        <el-input disabled v-model="data.form.username" autocomplete="off" placeholder="请输入账号" />
      </el-form-item>
      <el-form-item label="名称" prop="name">
        <el-input v-model="data.form.name" autocomplete="off" placeholder="请输入名称" />
      </el-form-item>
      <div v-if="data.user.role === 'EMP'">
        <el-form-item label="性别">
          <el-radio-group v-model="data.form.sex">
            <el-radio value="男" label="男"></el-radio>
            <el-radio value="女" label="女"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="工号" prop="no">
          <el-input disabled v-model="data.form.no" autocomplete="off" placeholder="请输入工号" />
        </el-form-item>
        <el-form-item label="年龄">
          <el-input-number style="width: 180px" :min="18" v-model="data.form.age" autocomplete="off"
            placeholder="请输入年龄" />
        </el-form-item>
        <el-form-item label="个人介绍">
          <el-input :rows="3" type="textarea" style="width: 180px" :min="18" v-model="data.form.description"
            autocomplete="off" placeholder="请输入个人介绍" />
        </el-form-item>
      </div>
      <div style="text-align: center">
        <el-button @click="updateUser" type="primary" style="padding: 20px 30px">更新个人信息</el-button>
      </div>
    </el-form>
  </div>
</template>

<script setup>
import request from '@/utils/request';
import { ElMessage } from 'element-plus';
import { reactive, ref } from 'vue';

const formRef = ref()
const data = reactive({
  user: JSON.parse(localStorage.getItem('xm-pro-user')),
  form: {},
  rules: {
    username: [
      { required: true, message: '请输入账号', trigger: 'blur' }
    ],
    name: [
      { required: true, message: '请输入名称', trigger: 'blur' }
    ],
    no: [
      { required: true, message: '请输入工号', trigger: 'blur' }
    ]
  }
})

const emit = defineEmits(['updateUser'])

if (data.user.role === 'EMP') {
  request.get('/employee/selectById/' + data.user.id).then(res => {
    data.form = res.data
  })
} else {
  data.form = data.user
}

const updateUser = () => {
  if (data.user.role === 'EMP') {
    request.put('/employee/update', data.form).then(res => {
      if (res.code === '200') {
        ElMessage.success('更新成功')
        // 更新缓存数据
        localStorage.setItem('xm-pro-user', JSON.stringify(data.form))
        // chu'fa
        emit('updateUser')
      } else {
        ElMessage.error(res.msg)
      }
    })
  } else {
    request.put('/admin/update', data.form).then(res => {
      if (res.code === '200') {
        ElMessage.success('更新成功')
        // 更新缓存数据
        localStorage.setItem('xm-pro-user', JSON.stringify(data.form))
        // chu'fa
        emit('updateUser')
      } else {
        ElMessage.error(res.msg)
      }
    })
  }
}
</script>
```
## 四：修改密码
#### 1.后端代码
```java
public void updatePassword(Account account) {
    Integer id = account.getId();
    Admin admin = this.selectById(id);
    if(!admin.getPassword().equals(account.getPassword())){
        // 页面传来的原密码和数据库密码对比不匹配就报错
        throw new CustomException("500","对不起，原密码错误");
    }
    admin.setPassword(account.getNewPassword()); // 设置新密码
    this.update(admin);
    }
```    
```java
public void updatePassword(Account account) {
    Integer id = account.getId();
    Employee employee = this.selectById(id);
    if(!employee.getPassword().equals(account.getPassword())){
        // 页面传来的原密码和数据库密码对比不匹配就报错
        throw new CustomException("500","对不起，原密码错误");
    }
    employee.setPassword(account.getNewPassword()); // 设置新密码
    this.update(employee);
    }
```
#### 2.前端代码
```java
<template>
    <div class="card" style="width: 50%;padding: 40px 20px">
        <el-form ref="formRef" :rules="data.rules" :model="data.form" label-width="100px"
            style="padding-right: 40px;padding-top: 20px">
            <el-form-item label="原密码" prop="password">
                <el-input show-password v-model="data.form.password" autocomplete="off" placeholder="请输入原密码" />
            </el-form-item>
            <el-form-item label="新密码" prop="newPassword">
                <el-input show-password v-model="data.form.newPassword" autocomplete="off" placeholder="请输入新密码" />
            </el-form-item>
            <el-form-item label="确认新密码" prop="confirmPassword" required>
                <el-input show-password v-model="data.form.confirmPassword" autocomplete="off" placeholder="请再次确认新密码" />
            </el-form-item>
            <div style="text-align: center">
                <el-button @click="updatePassword" type="primary" style="padding: 20px 30px">立即修改</el-button>
            </div>
        </el-form>
    </div>
</template>

<script setup>
import request from '@/utils/request';
import { ElMessage } from 'element-plus';
import { reactive, ref } from 'vue';

const validatePass = (rule, value, callback) => {
    if (!value) {
        callback(new Error('请再次确认新密码'))
    } else if (value !== data.form.newPassword) {
        callback(new Error("两次输入的密码不一致"))
    } else {
        callback()
    }
}
const formRef = ref()
const data = reactive({
    user: JSON.parse(localStorage.getItem('xm-pro-user')),
    form: {},
    rules: {
        password: [
            { required: true, message: '请输入原密码', trigger: 'blur' }
        ],
        newPassword: [
            { required: true, message: '请输入新密码', trigger: 'blur' }
        ],
        confirmPassword: [
            { validator: validatePass, trigger: 'blur' }
        ],
    }
})

const updatePassword = () => {
    data.form.id = data.user.id
    data.form.role = data.user.role
    formRef.value.validate((valid) => {
        if (valid) {
            request.put('/updatePassword', data.form).then(res => {
                if (res.code === '200') {
                    ElMessage.success('修改成功')
                    localStorage.removeItem('xm-pro-user')
                    setTimeout(() => {
                        location.href = '/login'
                    }, 500)
                } else {
                    ElMessage.error(res.msg)
                }
            })
        }
    })
}
</script>
```