Springboot项目搭建(8)-用户登出与个人中心修改

1.提要信息

1.1 catch和then方法

thencatch是JavaScript中Promise对象的两个方法,用于处理异步操作的成功(成功回调)和失败(失败回调)情况。这两个方法通常与async/await语法一起使用,但也可以单独使用。

(1) then 方法

then方法是Promise实例链式调用的一部分,它接收一个或多个函数作为参数。

这些函数会在Promise成功解决(fulfilled)后被调用。如果Promise成功解决,then方法的第一个参数(如果有的话)会被调用,并且它的返回值会传递给下一个then方法,或者被catch方法捕获(如果没有更多的then方法)。

promise.then(onFulfilled, onRejected);

  • onFulfilled:当Promise成功解决时调用的函数。
  • onRejected:当Promise被拒绝时调用的函数(可选)。

(2) catch 方法

catch方法是Promise实例链式调用的一部分,它接收一个函数作为参数。

这个函数会在Promise被拒绝(rejected)后被调用。catch方法返回一个新的Promise,这个新的Promise会在捕获到错误后解决。

promise.catch(onRejected);

  • onRejected:当Promise被拒绝时调用的函数。

2.退出登录

2.1 代码处理

这段处理了用户在界面上执行的命令:如果是退出登录,则清除token和用户信息,并跳转到登录页面;如果不是退出登录,则跳转到用户页面。

<script setup>
import ...
import { ElMessage, ElMessageBox } from "element-plus";//确认框&提示框
// import { useTokenStore } from "@/stores/token";
// import useUserInfoStore from "@/stores/userInfo";
const tokenStore = useTokenStore()
// const userInfoStore = useUserInfoStore()
import { useRouter } from "vue-router";
const router = useRouter()
const handleCommand = (command)=>{//在浏览器控制台中,输出command数据
    // console.log(command) 👈测试函数
    if (command === 'logout'){
        ElMessageBox.confirm('退?','提示',{
            confirmButtonText:'确认',
            cancelButtonText:'取消',
            type:'warning'
        }).then(async()=>{
            // console.log('点击了确认') 👈测试函数
            //退出登录
            //清除状态管理Pinia中存放的数据
            tokenStore.removeToken()
            userInfoStore.removeInfo()
            //跳转至登录界面
            router.push('/login')
            ElMessage({
                type:'success',
                message:'用户退啦!'
            })
        }).catch(()=>{
            ElMessage({
                type:'info',
                message:'用户取消了退出'
            })
        })
    }else{
        router.push('/user/'+command)
    }
}
</script>

2.2 效果视图

3.用户基本资料界面

3.1 修改信息函数代码

文件地址:src\views\user\UserInfo.vue

允许用户修改他们的昵称和邮箱信息,并通过表单验证确保输入符合要求。

如果输入验证通过,用户点击提交按钮后,会调用updateUserInfo函数将信息提交到后端,并在成功后更新用户信息。

<script setup>
import { ref } from 'vue';
import useUserInfoStore from '@/stores/userInfo';
const userInfoStore = useUserInfoStore()
const userInfo = ref({ ...userInfoStore.info })
//数据校验
const rules = {
    nickname: [
        {
            required: true, message: "用户请输入用户昵称", trigger: 'blur'
        }, {
            pattern: /^\S{2,10}$/,
            message: '昵称必须是2-10位的非空字符',
            trigger: 'blur'
        }
    ],
    email: [
        {
            required: true, message: "请输入用户邮箱", trigger: 'blur'
        }, {
            type:'email',
            message: '邮箱格式不正确',
            trigger: 'blur'
        }
    ]
}
//修改个人信息
import { userInfoUpdateService } from '@/apis/user.js'
import { ElMessage } from 'element-plus';
const updateUserInfo = async()=>{
    let result = await userInfoUpdateService(userInfo.value)
    ElMessage.success(result.msg?result.msg:'修改成功')
    userInfoStore.setInfo(userInfo.value)//更新pinia中存放用户信息的数据
}
</script>
<template>
    <el-card class="page-container">
        <template #header>
            <div class="header">
                <span>
                    基本资料
                </span>
            </div>
        </template>
        <el-row>
            <el-col :span="12">
                <el-form :model="userInfo" :rules = "rules" label-width="100px" size="large">
                    <el-form-item label="登录名称">
                        <el-input v-model="userInfo.username" disabled />
                    </el-form-item>
                    <el-form-item label="用户昵称" prop="nickname">
                        <el-input v-model="userInfo.nickname" />
                    </el-form-item>
                    <el-form-item label="用户邮箱" prop="email">
                        <el-input v-model="userInfo.email" />
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="updateUserInfo">提交修改</el-button>
                    </el-form-item>
                </el-form>
            </el-col>
        </el-row>
    </el-card>
</template>

3.2 暴露地址

文件地址:src\apis\user.js

export const userInfoUpdateService = (userInfoData) => {
    return request.put('/user/update', userInfoData)
}

3.3 效果视图

4. 更换头像界面

4.1 更换头像函数代码

文件地址:src\views\user\UserAvatar.vue

<script setup>
import {
    Plus,
    Upload
} from "@element-plus/icons-vue"

import avatar from '@/assets/default.png'
import { ref } from "vue";
import { userAvatarUpdateService, userInfoService } from "@/apis/user.js";
import useUserInfoStore from "@/stores/userInfo";
import { useTokenStore } from "@/stores/token";
const tokenStore = useTokenStore()
const userInfoStore = useUserInfoStore()
import { ElMessage, ElMessageBox } from "element-plus";
import { useRouter } from "vue-router";
const router = useRouter()
const imgUrl = ref(userInfoStore.info.userPic)

const uploadRef = ref()
//上传成功回调函数
const uploadSuccess = (result)=>{
    imgUrl.value = result.data
}
//修改头像
const updateAvatar = async()=>{
    let result = await userAvatarUpdateService(imgUrl.value)
    ElMessage.success(result.msg?result.msg:'修改成功')
    //同步修改pinia中的头像
    userInfoStore.info.userPic = imgUrl.value
}
</script>

<template>
    <el-card class="page-container">
        <template #header>
            <div class="header">
                <span>
                    更换头像
                </span>
            </div>
        </template>
        <el-row>
            <el-col :span="12">
                <el-upload ref="uploadRef"
                class="avatar-uploader" 
                :show-file-list="false" 
                :auto-upload="true" 
                action="/apis/upload" name="file" 
                :header="{'Authorization':tokenStore.token}"
                :on-success="uploadSuccess">
                <img v-if="imgUrl" :src="imgUrl" class="avatar">
                <img v-else :src="avatar" width="300"/>
                </el-upload>
                <br>
                <el-button size="large" :icon="Plus" @click="uploadRef.$el.querySelector('input').click()">
                    选择图片
                </el-button>
                <el-button size="large" :icon="Upload" @click="updateAvatar">
                    上传头像
                </el-button>
            </el-col>
        </el-row>
    </el-card>
</template>

4.2 暴露地址

文件地址:src\apis\user.js

export const userAvatarUpdateService = (avatarURL) => {
    const params = new URLSearchParams()
    params.append('avatarURL', avatarURL)
    return request.patch('/user/updateavatar', params)
}

4.3 效果视图

5. 重置密码界面

5.1 重置密码函数代码

文件地址:src\views\user\UserPassword.vue

<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
import { userPsdUpdateService } from '@/apis/user';
import { useRouter } from 'vue-router';
const router = useRouter();
const passwordForm = ref(null);
const passwordData = ref({
  old_Pwd: '',
  new_Pwd: '',
  re_Pwd: ''
});

const checkRepassword = (rule, value, callback) => {
  if (value !== passwordData.value.new_Pwd) {
    callback(new Error('两次输入密码不一致'));
  } else {
    callback();
  }
};

const rules = {
  old_Pwd: [
    { required: true, message: '请输入原密码', trigger: 'blur' }
  ],
  new_Pwd: [
    { required: true, message: '请输入新密码', trigger: 'blur' },
    { min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
  ],
  re_Pwd: [
    { required: true, message: '请确认新密码', trigger: 'blur' },
    { validator: checkRepassword, trigger: 'blur' }
  ]
};

const submitPassword = async () => {
  if (!passwordForm.value) return;
  passwordForm.value.validate(async (valid) => {
    if (valid) {
      try {
        let result = await userPsdUpdateService(passwordData.value);
        ElMessage.success(result.msg ? result.msg : '重置密码成功');
        router.push("/login");
      } catch (error) {
        ElMessage.error('重置密码失败');
      }
    } else {
      ElMessage.error('表单校验失败');
    }
  });
};
</script>

<template>
  <el-card class="page-container">
    <template #header>
      <div class="header">
        <span>
          更改密码
        </span>
      </div>
    </template>
    <el-row>
      <el-col :span="12">
        <el-form :model="passwordData" :rules="rules" ref="passwordForm">
          <el-form-item label="原密码" prop="old_Pwd">
            <el-input type="password" v-model="passwordData.old_Pwd"></el-input>
          </el-form-item>
          <el-form-item label="新密码" prop="new_Pwd">
            <el-input type="password" v-model="passwordData.new_Pwd"></el-input>
          </el-form-item>
          <el-form-item label="确认新密码" prop="re_Pwd">
            <el-input type="password" v-model="passwordData.re_Pwd"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitPassword">修改密码</el-button>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
  </el-card>
</template>

5.2 暴露地址

文件地址:src\apis\user.js

export const userPsdUpdateService = (userPsdData) => {
    return request.post('/user/updatePwd', userPsdData);
  };
//
//export const userPsdUpdateService = (userPsdData) => {
//    const params = new URLSearchParams()
//    for (let key in userPsdData) {
//        params.append(key, userPsdData[key])
//    }
//    // return request.post('/user/updatePwd',params)
//    return request.post('/user/updatePwd', userPsdData, {
//        headers: {
//            'Content-Type': 'application/json'
//        }
//    });
//}

5.3 效果视图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/927199.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio 使用插件Database Navigation 连接 sqlite数据库

文章目录 Database Navigation 简介一&#xff0c;Database Navigation 下载二&#xff0c;将sqlite数据库文件存放到本地三&#xff0c;连接sqlite数据库四&#xff0c;使用SQL语句查看数据 Database Navigation 简介 Database Navigation 是一款在 Android Studio 开发环境中…

springboot kafka在kafka server AUTH变动后consumer自动销毁

前言 笔者使用了kafka用来传输数据&#xff0c;笔者在今年10月写了文章&#xff0c;怎么使用配置化实现kafka的装载&#xff1a;springboot kafka多数据源&#xff0c;通过配置动态加载发送者和消费者-CSDN博客 不过在实际运行中&#xff0c;kafka broker是加密的&#xff0c…

ansible使用说明

将安装包拷贝到主控端主机 在主控端主机安装ansible&#xff0c;sh setup.sh 确认安装成功后&#xff0c;编辑hosts文件&#xff08;按步骤逐个添加主机组&#xff0c;不要一开始全部配置好&#xff09; [site-init]下的主机列表为被控制的主机&#xff08;按照当前ai建模方案…

5G学习笔记之PRACH

即使是阴天&#xff0c;也要记得出门晒太阳哦 目录 1. 概述 2. PRACH Preamble 3. PRACH Preamble 类型 3.1 长前导码 3.2 短前导码 3.3 前导码格式与小区覆盖 4. PRACH时频资源 4.1 小区所有可用PRACH资源 4.2 SSB和RACH的关系 4.3 PRACH时频资源配置 1. 概述 随机接入…

单点登录深入详解之技术方案总结

技术方案之CAS认证 概述 CAS 是耶鲁大学的开源项目&#xff0c;宗旨是为 web 应用系统提供一种可靠的单点登录解决方案。 CAS 从安全性角度来考虑设计&#xff0c;用户在 CAS 输入用户名和密码之后通过ticket进行认证&#xff0c;能够有效防止密码泄露。 CAS 广泛使用于传统应…

不开流也可以知道文件大小(File类)file.length():long

但是文件的toString是这个东西&#xff0c;所以当你把一个文件对象转json&#xff0c;大概率只有paXXXXX” 这一个key&#xff0c;想要自动转成输出其他的文件大小或者文件名什么的&#xff0c;就自己封装file类&#xff0c;封装fiel的方法

数据结构 (16)特殊矩阵的压缩存储

前言 特殊矩阵的压缩存储是数据结构中的一个重要概念&#xff0c;它旨在通过找出特殊矩阵中值相同的矩阵元素的分布规律&#xff0c;把那些呈现规律性分布的、值相同的多个矩阵元素压缩存储到一个存储空间中&#xff0c;从而节省存储空间。 一、特殊矩阵的定义 特殊矩阵是指具有…

试题转excel;试题整理工具;试卷转excel;word转excel

一、问题描述 我父亲是一名教师&#xff0c;偶尔会需要将试卷转excel&#xff0c;方便管理处理一些特别重要的题目 于是&#xff0c;就抽空写一个专门将试题转excel的工具&#xff0c;便于各位教师从业者和教育行业的朋友更好的整理试题&#xff0c;减少一点重复枯燥的工作 …

CSP/信奥赛C++语法基础刷题训练(36):洛谷P11229:[CSP-J 2024] 小木棍

CSP/信奥赛C语法基础刷题训练&#xff08;36&#xff09;&#xff1a;洛谷P11229&#xff1a;[CSP-J 2024] 小木棍 题目描述 小 S 喜欢收集小木棍。在收集了 n n n 根长度相等的小木棍之后&#xff0c;他闲来无事&#xff0c;便用它们拼起了数字。用小木棍拼每种数字的方法如…

【NLP 4、数学基础】

此去经年&#xff0c;应是良辰美景虚设 —— 24.11.28 一、线性代数 1.标量和向量 ① 标量 Scalar 一个标量就是一个单独的数 ② 向量 Vector 一个向量是一列数 可以把向量看作空间中的点&#xff0c;每个元素是不同坐标轴上的坐标 向量中有几个数&#xff0c;就叫作几维…

IOC控制反转DI依赖注入(Java EE 学习笔记06)

1 IoC 控制反转 控制反转&#xff08;Inversion of Control&#xff0c;缩写为IoC&#xff09;是面向对象编程中的一个设计原则&#xff0c;用来降低程序代码之间的耦合度。在传统面向对象编程中&#xff0c;获取对象的方式是用new关键字主动创建一个对象&#xff0c;也就是说…

68 mysql 的 临键锁

前言 我们这里来说的就是 我们在 mysql 这边常见的 一种锁, 行临键锁 虽然 在平时我们用到的不是很多, 我们这里 主要是 讲一下 它的主要的触发的场景 行临键锁 等价于 行锁 间隙锁, 行间隙锁是一个 左开右开的区间, 行临键锁 是一个左开右闭的区间 但是 它 和 行锁的差异…

(数据结构与算法)如何提高学习算法的效率?面试算法重点有哪些?面试需要哪些能力?

面试官眼中的求职者 通过对你算法的考察&#xff01;&#xff01;&#xff01;&#xff01; 缩进太多&#xff01;&#xff01;一般不要超过三层&#xff01;&#xff01;&#xff01;缩进越少&#xff0c;bug越少&#xff1b;逻辑比较复杂&#xff0c;把这些包装成为函数&…

设计模式-适配器模式-注册器模式

设计模式-适配器模式-注册器模式 适配器模式 如果开发一个搜索中台&#xff0c;需要适配或接入不同的数据源&#xff0c;可能提供的方法参数和平台调用的方法参数不一致&#xff0c;可以使用适配器模式 适配器模式通过封装对象将复杂的转换过程隐藏于幕后。 被封装的对象甚至…

SpringBoot实战(三十二)集成 ofdrw,实现 PDF 和 OFD 的转换、SM2 签署OFD

目录 一、OFD 简介1.1 什么是 OFD&#xff1f;1.2 什么是 版式文档&#xff1f;1.3 为什么要用 OFD 而不是PDF&#xff1f; 二、ofdrw 简介2.1 定义2.2 Maven 依赖2.3 ofdrw 的 13 个模块 三、PDF/文本/图片 转 OFD&#xff08;ofdrw-conterver&#xff09;3.1 介绍&#xff1a…

Opencv+ROS实现摄像头读取处理画面信息

一、工具 ubuntu18.04 ROSopencv2 编译器&#xff1a;Visual Studio Code 二、原理 图像信息 ROS数据形式&#xff1a;sensor_msgs::Image OpenCV数据形式&#xff1a;cv:Mat 通过cv_bridge()函数进行ROS向opencv转换 cv_bridge是在ROS图像消息和OpenCV图像之间进行转…

【MySQL — 数据库基础】MySQL的安装与配置 & 数据库简单介绍

数据库基础 本节目标 掌握关系型数据库&#xff0c;数据库的作用掌握在Windows和Linux系统下安装MySQL数据库了解客户端工具的基本使用和SQL分类了解MySQL架构和存储引擎 1. 数据库的安装与配置 1.1 确认MYSQL版本 处理无法在 cmd 中使用 mysql 命令的情况&a…

shell编程基础笔记

目录 echo改字体颜色和字体背景颜色 bash基本功能&#xff1a; 运行方式&#xff1a;推荐使用第二种方法 变量类型 字符串处理&#xff1a; 条件判断&#xff1a;&#xff08;使用echo $?来判断条件结果&#xff0c;0为true&#xff0c;1为false&#xff09; 条件语句&a…

maxun爬虫工具docker搭建

思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地&#xff08;只有第一次需要&#xff09; git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…

redis揭秘-redis01-redis单例与集群安装总结

文章目录 【README】【1】安装单机【1.1】安装环境【1.2】安装步骤 【2】redis集群主从模式配置【2.1】集群架构【2.2】redis集群主从模式搭建步骤【2.3】redis集群主从模式的问题&#xff08;单点故障问题&#xff09; 【3】redis集群哨兵模式配置【3.1】集群架构【3.2】redis…