当前位置: 首页 > news >正文

【慧游鲁博】【10】全端优化用户信息存储+网页端user模块与后端对接

文章目录

  • (小程序端)
    • 本次更新
    • 1. 数据库与实体类调整
      • 1.1 数据库表修改
      • 1.2 Java 实体类 `User` 调整
    • 2. 后端接口修改
      • 2.1 更新 `UserVO`(视图对象)
      • 2.2 修改 `getUserInfo` 方法
    • 3. 小程序端存储优化(Pinia 状态管理)
      • 3.1 重构 `member.js`
      • 3.2 持久化配置
    • 4. 登录逻辑优化
      • 4.1 修改 `handleLogin` 方法
      • 4.2 获取用户信息的策略
  • (网页端)
    • 本次更新
      • 网页端调整
    • 网页端关键实现
      • 1. API服务 (user.js)
        • 1. 模块结构
        • 2. 依赖分析
        • 3. API 方法详解
          • 3.1 用户登录 (`login`)
          • 3.2 获取用户信息 (`getUserInfo`)
          • 3.3 更新用户信息 (`updateUserInfo`)
          • 3.4 更新用户头像 (`updateAvatar`)
          • 3.5 更新用户密码 (`updatePassword`)
          • 3.6 获取用户列表 (`getUserList`)
      • 2. Token管理 (token.js)
        • setToken
        • clearToken
      • 3. 用户信息组件 (UserInfo.vue)
        • 字段与后端 UserVO 匹配
        • 编辑逻辑优化
          • 可编辑字段控制
          • 编辑状态管理
          • 数据恢复机制
          • 保存逻辑
        • 与API的交互
      • 4. 登录组件 (Login.vue)
        • 表单验证修改
          • 验证规则配置
          • 自定义验证方法
        • 登录逻辑实现
        • 与API的交互

(小程序端)

本次更新

在开发微信小程序等移动应用时,用户信息的存储和安全性是需要重点考虑的问题。本次优化通过最小化客户端存储的用户数据,仅保留必要的 idrole,既保证了功能完整性,又提升了安全性。

在这里插入图片描述

本文将围绕本次修改,详细介绍:

  1. 数据库与实体类调整(添加 role 字段)
  2. 后端接口修改UserVOgetUserInfo 方法)
  3. 小程序端存储优化Pinia 状态管理调整)
  4. 登录逻辑优化(仅存储 idrole

1. 数据库与实体类调整

1.1 数据库表修改

users 表中新增 role 字段,用于区分用户权限:

ALTER TABLE users
ADD COLUMN role INTEGER NOT NULL DEFAULT 1;  -- 默认普通用户(1),0表示管理员

1.2 Java 实体类 User 调整

User.java 中添加 role 字段:

@Data
@TableName("users")
public class User {// 其他字段...@TableField("role")private Integer role; // 0=管理员,1=普通用户
}

2. 后端接口修改

2.1 更新 UserVO(视图对象)

UserVO.java 中添加 role 字段,确保返回给小程序端的数据包含权限信息:

@Data
public class UserVO {// 其他字段...private Integer role; // 0=管理员,1=普通用户
}

2.2 修改 getUserInfo 方法

确保 getUserInfo 返回的数据包含 role

@Override
public Result<UserVO> getUserInfo() {// 查询用户...UserVO userVO = new UserVO();userVO.setId(user.getId());// 其他字段...userVO.setRole(user.getRole()); // 新增 role 字段return Result.success(userVO);
}

3. 小程序端存储优化(Pinia 状态管理)

3.1 重构 member.js

优化 useMemberStore,仅存储 userIduserRole

export const useMemberStore = defineStore('member', () => {const profile = ref({token: '',      // 登录令牌userId: null,   // 仅存储用户IDuserRole: null  // 仅存储用户角色});const setUserBasicInfo = (userInfo) => {profile.value.userId = userInfo?.id || null;profile.value.userRole = userInfo?.role ?? null;};// 其他方法...
});

3.2 持久化配置

仍然使用 uni-app 的本地存储,但数据量更小:

persist: {storage: {getItem(key) { return uni.getStorageSync(key); },setItem(key, value) { uni.setStorageSync(key, value); },},
}

4. 登录逻辑优化

4.1 修改 handleLogin 方法

登录成功后,仅存储 idrole

async handleLogin() {try {const res = await post('/user/login', { ... });const memberStore = useMemberStore();memberStore.setToken(res);// 仅存储 id 和 roleconst userInfoRes = await get('/user/getUserInfo');memberStore.setUserBasicInfo({id: userInfoRes.id,role: userInfoRes.role});// 跳转逻辑...} catch (error) {// 错误处理...}
}

4.2 获取用户信息的策略

  • 需要完整信息时(如个人中心页面),再通过 userId 调用接口获取。
  • 权限检查 直接使用 getUserRole() 判断:
    if (memberStore.getUserRole() === 0) {// 管理员逻辑
    }
    

(网页端)

本次更新

  • ✅ 用户登录/退出流程完整
  • ✅ 个人信息显示与编辑功能完善
  • ✅ 前后端数据无缝对接
  • ✅ 存储管理安全可靠

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

网页端调整

(1) API 请求 (user.js)

  • 标准化请求方式(与 story.js 保持一致):
    • 使用 instance 替代 request
    • 改为 函数式导出(如 export function login(data)
  • 接口调整
    • getUserInfo() 不再需要 userId(从 Token 获取当前用户)
    • updateUserInfo() 仅允许修改 nicknameemail

(2) Token 管理 (token.js)

  • 新增 clearToken()
    • 清空 Pinia 的 token 状态
    • 移除 localStorage 中的 token
    • 额外清除 Pinia 持久化存储(避免插件自动恢复)

(3) 登录页 (Login.vue)

  • 表单验证同步后端规则
    • 用户名/密码长度:5-16位
    • 禁止空白字符(通过 validateNoWhitespace 自定义校验)
  • 真实登录逻辑
    • 调用 login() API
    • 成功后将 token 存入 Pinia 和 localStorage

(4) 用户信息页 (UserInfo.vue)

  • 字段匹配后端 UserVO
    • 显示 nickname 而非 realName
    • 新增 avatarUrl 头像预览
    • 角色显示为 “管理员”“普通用户”(根据 role: 0 | 1
  • 编辑逻辑优化
    • 仅允许修改 nicknameemail
    • 取消编辑时恢复原始数据

(5) 退出登录

  • 彻底清除所有存储
    tokenStore.clearToken();  // 清空 Pinia + localStorage
    userInfoStore.$reset();  // 重置用户信息
    router.push('/login');   // 跳转登录页
    

网页端关键实现

1. API服务 (user.js)

user.js 是一个用户相关的 API 封装模块,它基于 request.js 提供的 axios 实例封装了一系列与用户相关的接口。

1. 模块结构

user.js 导出了 6 个函数,分别对应不同的用户操作:

  1. login - 用户登录
  2. getUserInfo - 获取用户详细信息
  3. updateUserInfo - 更新用户基本信息
  4. updateAvatar - 更新用户头像
  5. updatePassword - 更新用户密码
  6. getUserList - 获取用户列表(分页)
2. 依赖分析

模块顶部导入了 request.js 中创建的 axios 实例:

import instance from '@/utils/request';
3. API 方法详解
3.1 用户登录 (login)
export function login(data) {return instance({url: '/user/login',method: 'post',data});
}
  • 功能:用户登录接口
  • 方法:POST
  • 参数:通过 data 传递登录表单数据(如用户名和密码)
  • 特点:不需要 token,是获取 token 的入口
3.2 获取用户信息 (getUserInfo)
export function getUserInfo() {return instance({url: '/user/getUserInfo',method: 'get'});
}
  • 功能:获取当前登录用户的详细信息
  • 方法:GET
  • 特点:需要 token(通过请求拦截器自动添加)
3.3 更新用户信息 (updateUserInfo)
export function updateUserInfo(data) {return instance({url: '/user/updateUserInfo',method: 'put',data});
}
  • 功能:更新用户基本信息
  • 方法:PUT
  • 参数:通过 data 传递更新后的用户信息
  • 特点:需要 token,使用 PUT 方法表示更新操作
3.4 更新用户头像 (updateAvatar)
export function updateAvatar(avatarUrl) {return instance({url: '/user/avatar',method: 'patch',params: { avatarUrl }});
}
  • 功能:更新用户头像
  • 方法:PATCH(部分更新)
  • 参数:通过 params 传递头像 URL
  • 特点:使用 PATCH 方法表示部分更新,参数通过 URL 查询字符串传递
3.5 更新用户密码 (updatePassword)
export function updatePassword(data) {return instance({url: '/user/password',method: 'patch',data});
}
  • 功能:更新用户密码
  • 方法:PATCH
  • 参数:通过 data 传递新旧密码
  • 特点:敏感操作,通常需要额外验证
3.6 获取用户列表 (getUserList)
export function getUserList(params) {return instance({url: '/user/page',method: 'get',params});
}
  • 功能:分页获取用户列表(管理员功能)
  • 方法:GET
  • 参数:通过 params 传递分页参数(如 pageNum, pageSize)
  • 特点:需要管理员权限,参数通过 URL 查询字符串传递

2. Token管理 (token.js)

token.js 是一个使用 Pinia 实现的状态管理模块,专门用于管理用户的认证 token。本次完善如下:

setToken
setToken(token) {this.token = token;localStorage.setItem('token', token); // 同步到 localStorage
},
  • 功能:设置 token
  • 同时更新内存状态和 localStorage
  • 确保 token 在页面刷新后仍然可用
clearToken
clearToken() {this.token = ''; // 清空 statelocalStorage.removeItem('token'); // 清除 localStorage// 关键:清除 Pinia 持久化插件的存储if (this.$hydrate) {this.$hydrate({ reset: true }); // 重置持久化状态}// 或者直接清除特定的持久化 keyconst PERSIST_KEY = `pinia-${this.$id}`;localStorage.removeItem(PERSIST_KEY);sessionStorage.removeItem(PERSIST_KEY);
}
  • 功能:清除 token
  • 清空内存状态
  • 从 localStorage 移除 token
  • 特别处理了 Pinia 持久化插件的存储(两种方式):
    1. 使用插件的 $hydrate 方法(如果存在)
    2. 直接移除插件使用的存储 key

3. 用户信息组件 (UserInfo.vue)

字段与后端 UserVO 匹配

组件中的 userForm 对象字段与后端数据结构对齐:

const userForm = reactive({id: '',           // 用户IDusername: '',     // 用户名nickname: '',     // 昵称 (替代了原来的realName)email: '',        // 电子邮箱avatarUrl: '',    // 新增-头像URLrole: 0,          // 用户角色 (0-管理员,1-普通用户)createTime: '',   // 创建时间updateTime: ''    // 更新时间
});

关键字段变更

  • nickname 替代 realName:更符合常见用户系统的命名习惯
  • 新增 avatarUrl:支持头像显示和预览功能
  • 角色显示优化:将数字角色转换为易读文本
    <el-input :value="userForm.role === 0 ? '管理员' : '普通用户'" disabled />
    
编辑逻辑优化
可编辑字段控制
  • 允许编辑的字段:仅 nicknameemail
    <el-form-item label="昵称"><el-input v-model="userForm.nickname" />
    </el-form-item><el-form-item label="电子邮箱"><el-input v-model="userForm.email" />
    </el-form-item>
    
  • 禁用字段:其他所有字段都设置为 disabled
编辑状态管理
  • 使用 isEditing ref 控制编辑状态
  • 编辑按钮条件渲染:
    <el-button type="primary" @click="handleEdit" v-if="!isEditing">编辑</el-button>
    <div v-else class="action-buttons"><el-button type="success" @click="handleSave">保存</el-button><el-button @click="cancelEdit">取消</el-button>
    </div>
    
数据恢复机制
  • 使用 originalUserData 保存原始数据:
    const originalUserData = reactive({});// 获取用户信息时保存原始数据
    Object.assign(originalUserData, res.data);
    
  • 取消编辑时恢复数据:
    const cancelEdit = () => {isEditing.value = false;Object.assign(userForm, originalUserData);
    };
    
保存逻辑
  • 仅提交可修改的字段:
    const res = await updateUserInfo({nickname: userForm.nickname,email: userForm.email
    });
    
  • 成功保存后刷新数据:
    if (res.code === 200) {ElMessage.success('用户信息更新成功');isEditing.value = false;fetchUserInfo(); // 刷新数据
    }
    
与API的交互

组件使用了 user.js 中的两个API方法:

  1. 获取用户信息

    import { getUserInfo } from '@/api/user';const res = await getUserInfo();
    
  2. 更新用户信息

    import { updateUserInfo } from '@/api/user';const res = await updateUserInfo({ nickname, email });
    

4. 登录组件 (Login.vue)

表单验证修改
验证规则配置

组件中定义了严格的表单验证规则,与后端要求保持一致:

const loginRules = {username: [{ required: true, message: "请输入用户名", trigger: "blur" },{ min: 5, max: 16, message: "用户名长度应为5-16个字符", trigger: "blur" },{ validator: validateNoWhitespace, trigger: "blur" },],password: [{ required: true, message: "请输入密码", trigger: "blur" },{ min: 5, max: 16, message: "密码长度应为5-16个字符", trigger: "blur" },{ validator: validateNoWhitespace, trigger: "blur" },],
};
自定义验证方法

实现了禁止空白字符的自定义验证:

const validateNoWhitespace = (rule, value, callback) => {if (/\s/.test(value)) {callback(new Error("不能包含空白字符"));} else {callback();}
};
登录逻辑实现
const handleLogin = async () => {try {// 1. 表单验证await loginFormRef.value.validate();loading.value = true;// 2. 调用登录APIconst response = await login({username: loginForm.username,password: loginForm.password,});if (response.code === 200) {// 3. 存储tokentokenStore.setToken(response.data);// 4. 获取用户信息const userInfoResponse = await getUserInfo();if (userInfoResponse.code === 200) {userInfoStore.setUserInfo(userInfoResponse.data);}ElMessage.success("登录成功");// 5. 跳转到首页router.push("/dashboard");} else {ElMessage.error(response.message || "登录失败");}} catch (error) {ElMessage.error(error.message || "登录失败");} finally {loading.value = false;}
};
  1. 表单验证:先验证表单数据是否符合规则
  2. API调用:使用 login() 方法发送登录请求
  3. Token存储:登录成功后,通过 tokenStore.setToken() 存储token
    • 同时保存到Pinia状态和localStorage
  4. 用户信息获取:获取并存储用户详细信息
  5. 页面跳转:登录成功后跳转到仪表盘页面

使用了两个Pinia store:

  1. tokenStore:管理认证token
    const tokenStore = useTokenStore();
    tokenStore.setToken(response.data);
    
  2. userInfoStore:管理用户信息
    const userInfoStore = useUserInfoStore();
    userInfoStore.setUserInfo(userInfoResponse.data);
    
与API的交互

组件使用了 user.js 中的两个API方法:

  1. 登录接口
    import { login } from "@/api/user";
    const response = await login({ username, password });
    
  2. 获取用户信息
    import { getUserInfo } from "@/api/user";
    const userInfoResponse = await getUserInfo();
    

相关文章:

  • PHPStudy 一键式网站搭建工具的下载使用
  • Controller层中常用的接收前端参数的方式
  • 通义智文开源QwenLong-L1: 迈向长上下文大推理模型的强化学习
  • syslog 和 logrotate
  • 字节跳动BAGEL-7B-MoT模型开源:多模态AI技术的新范式与行业涟漪
  • NLua性能对比:C#注册函数 vs 纯Lua实现
  • SMT贴片制造流程关键环节解析
  • React从基础入门到高级实战:React 核心技术 - 动画与过渡效果:提升 UI 交互体验
  • Qt基础终结篇:从文件操作到多线程异步UI,深度解析核心要点
  • Excel 操作 转图片,转pdf等
  • 新编辑器编写指南--给自己的备忘
  • 【数据结构】——二叉树堆(下)
  • 【深度学习】7. 深度卷积神经网络架构:从 ILSVRC、LeNet 到 AlexNet、ZFNet、VGGNet,含pytorch代码结构
  • uni-app学习笔记十五-vue3页面生命周期(一)
  • pycharm终端遇不显示虚拟环境的问题
  • 【第1章 基础知识】1.8 在 Canvas 中使用 HTML 元素
  • WPF【11_3】WPF实战-重构与美化(可复用的UI组件)
  • 【AI工具应用】使用 trae 实现 word 转成 html
  • PH热榜 | 2025-05-24
  • 【Linux】shell脚本的常用命令
  • 网站中的滚动字幕怎么做/百度指数移动版app
  • app界面设计欣赏/上海外贸seo公司
  • 怎样用网站做单笔外贸/网络平台推广具体是怎么推广
  • 网站上的链接怎么做的/淘宝关键词排名查询工具免费
  • 不良网站正能量进入窗口/百度开户怎么开
  • 桐庐网站建设/口碑营销有哪些方式