|
|
@@ -0,0 +1,815 @@
|
|
|
+# LoginUserUtil 工具类使用文档
|
|
|
+
|
|
|
+## 概述
|
|
|
+
|
|
|
+`LoginUserUtil` 是一个用于在web端商户平台(`alien-store-platform`)中获取当前登录用户信息的工具类。它封装了从JWT Token中提取用户信息以及从数据库查询完整用户信息的常用方法。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 核心特性
|
|
|
+
|
|
|
+- ✅ **静态方法**: 所有方法都是静态方法,可直接调用,无需实例化
|
|
|
+- ✅ **自动注入**: 使用`@Autowired`自动注入`StoreUserMapper`
|
|
|
+- ✅ **异常处理**: 所有方法都包含完善的异常处理,确保不会抛出异常
|
|
|
+- ✅ **日志记录**: 详细的日志记录,便于调试和问题排查
|
|
|
+- ✅ **多种获取方式**: 支持从Token获取基本信息,或从数据库查询完整信息
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 类结构
|
|
|
+
|
|
|
+```java
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class LoginUserUtil {
|
|
|
+ // 核心方法
|
|
|
+ public static Integer getCurrentUserId() // 获取用户ID
|
|
|
+ public static String getCurrentUserPhone() // 获取手机号
|
|
|
+ public static String getCurrentUserType() // 获取用户类型
|
|
|
+ public static JSONObject getCurrentUserInfo() // 获取Token中的用户信息
|
|
|
+ public static StoreUser getCurrentStoreUser() // 获取完整用户信息(数据库)
|
|
|
+ public static StoreUser getCurrentStoreUserByPhone() // 根据手机号获取用户信息
|
|
|
+
|
|
|
+ // 辅助方法
|
|
|
+ public static boolean isCurrentUser(Integer userId) // 验证是否为当前用户
|
|
|
+ public static boolean isLogin() // 验证是否已登录
|
|
|
+ public static boolean isStorePlatformUser() // 验证是否为商户平台用户
|
|
|
+
|
|
|
+ // 便捷方法
|
|
|
+ public static Integer getCurrentStoreId() // 获取门店ID
|
|
|
+ public static String getCurrentNickName() // 获取昵称
|
|
|
+ public static String getCurrentName() // 获取真实姓名
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 方法详解
|
|
|
+
|
|
|
+### 1. getCurrentUserId()
|
|
|
+
|
|
|
+获取当前登录用户的ID(从Token中获取,无需查询数据库)
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的ID
|
|
|
+ * @return 用户ID,如果未登录返回null
|
|
|
+ */
|
|
|
+public static Integer getCurrentUserId()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+Integer userId = LoginUserUtil.getCurrentUserId();
|
|
|
+if (userId != null) {
|
|
|
+ System.out.println("当前用户ID: " + userId);
|
|
|
+} else {
|
|
|
+ System.out.println("用户未登录");
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回用户ID(Integer)
|
|
|
+- 未登录: 返回`null`
|
|
|
+
|
|
|
+**性能**: ⚡ 快速(只解析Token,不查询数据库)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 2. getCurrentUserPhone()
|
|
|
+
|
|
|
+获取当前登录用户的手机号(从Token中获取)
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的手机号
|
|
|
+ * @return 手机号,如果未登录返回null
|
|
|
+ */
|
|
|
+public static String getCurrentUserPhone()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+String phone = LoginUserUtil.getCurrentUserPhone();
|
|
|
+if (phone != null) {
|
|
|
+ System.out.println("当前用户手机号: " + phone);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回手机号(String)
|
|
|
+- 未登录: 返回`null`
|
|
|
+
|
|
|
+**性能**: ⚡ 快速(只解析Token)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 3. getCurrentUserType()
|
|
|
+
|
|
|
+获取当前登录用户的用户类型(从Token中获取)
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的用户类型
|
|
|
+ * @return 用户类型,如果未登录返回null
|
|
|
+ */
|
|
|
+public static String getCurrentUserType()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+String userType = LoginUserUtil.getCurrentUserType();
|
|
|
+if ("storePlatform".equals(userType)) {
|
|
|
+ System.out.println("商户平台用户");
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回用户类型(String),如 `"storePlatform"`
|
|
|
+- 未登录: 返回`null`
|
|
|
+
|
|
|
+**性能**: ⚡ 快速(只解析Token)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 4. getCurrentUserInfo()
|
|
|
+
|
|
|
+获取当前登录用户的Token信息(JSONObject格式)
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的Token信息(JSONObject格式)
|
|
|
+ * @return 用户信息JSONObject,包含userId、phone、userType等字段
|
|
|
+ */
|
|
|
+public static JSONObject getCurrentUserInfo()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+JSONObject userInfo = LoginUserUtil.getCurrentUserInfo();
|
|
|
+if (userInfo != null) {
|
|
|
+ Integer userId = userInfo.getInteger("userId");
|
|
|
+ String phone = userInfo.getString("phone");
|
|
|
+ String userType = userInfo.getString("userType");
|
|
|
+
|
|
|
+ System.out.println("用户ID: " + userId);
|
|
|
+ System.out.println("手机号: " + phone);
|
|
|
+ System.out.println("用户类型: " + userType);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回包含用户信息的`JSONObject`
|
|
|
+- 未登录: 返回`null`
|
|
|
+
|
|
|
+**包含字段**:
|
|
|
+- `userId`: 用户ID
|
|
|
+- `phone`: 手机号
|
|
|
+- `userType`: 用户类型
|
|
|
+
|
|
|
+**性能**: ⚡ 快速(只解析Token)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 5. getCurrentStoreUser()
|
|
|
+
|
|
|
+获取当前登录用户的完整商户用户信息(从数据库查询)
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的完整商户用户信息(从数据库查询)
|
|
|
+ * @return StoreUser对象,如果未登录或查询失败返回null
|
|
|
+ */
|
|
|
+public static StoreUser getCurrentStoreUser()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+StoreUser storeUser = LoginUserUtil.getCurrentStoreUser();
|
|
|
+if (storeUser != null) {
|
|
|
+ System.out.println("用户ID: " + storeUser.getId());
|
|
|
+ System.out.println("手机号: " + storeUser.getPhone());
|
|
|
+ System.out.println("昵称: " + storeUser.getNickName());
|
|
|
+ System.out.println("真实姓名: " + storeUser.getName());
|
|
|
+ System.out.println("门店ID: " + storeUser.getStoreId());
|
|
|
+ System.out.println("账户余额: " + storeUser.getMoney());
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回`StoreUser`对象(包含所有字段)
|
|
|
+- 未登录: 返回`null`
|
|
|
+- 查询失败: 返回`null`
|
|
|
+
|
|
|
+**性能**: 🐢 较慢(需要查询数据库)
|
|
|
+
|
|
|
+**注意**:
|
|
|
+- 适用于需要完整用户信息的场景
|
|
|
+- 会产生数据库查询,建议在需要时才调用
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 6. getCurrentStoreUserByPhone()
|
|
|
+
|
|
|
+根据手机号获取商户用户信息(从数据库查询)
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 根据手机号获取商户用户信息
|
|
|
+ * @return StoreUser对象,如果未登录或查询失败返回null
|
|
|
+ */
|
|
|
+public static StoreUser getCurrentStoreUserByPhone()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+StoreUser storeUser = LoginUserUtil.getCurrentStoreUserByPhone();
|
|
|
+if (storeUser != null) {
|
|
|
+ System.out.println("用户信息: " + storeUser);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回`StoreUser`对象
|
|
|
+- 未登录: 返回`null`
|
|
|
+- 查询失败: 返回`null`
|
|
|
+
|
|
|
+**性能**: 🐢 较慢(需要查询数据库)
|
|
|
+
|
|
|
+**与 getCurrentStoreUser() 的区别**:
|
|
|
+- `getCurrentStoreUser()`: 根据用户ID查询(主键查询,更快)
|
|
|
+- `getCurrentStoreUserByPhone()`: 根据手机号查询(索引查询,稍慢)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 7. isCurrentUser(Integer userId)
|
|
|
+
|
|
|
+验证当前登录用户是否为指定用户
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 验证当前登录用户是否为指定用户
|
|
|
+ * @param userId 要验证的用户ID
|
|
|
+ * @return true-是当前用户, false-不是当前用户
|
|
|
+ */
|
|
|
+public static boolean isCurrentUser(Integer userId)
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+Integer targetUserId = 12345;
|
|
|
+if (LoginUserUtil.isCurrentUser(targetUserId)) {
|
|
|
+ System.out.println("是当前用户,允许操作");
|
|
|
+} else {
|
|
|
+ System.out.println("不是当前用户,拒绝操作");
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**使用场景**:
|
|
|
+- 权限验证:确保用户只能修改自己的信息
|
|
|
+- 安全检查:防止用户操作其他用户的数据
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- `true`: 是当前登录用户
|
|
|
+- `false`: 不是当前登录用户或未登录
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 8. isLogin()
|
|
|
+
|
|
|
+验证当前用户是否已登录
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 验证当前用户是否已登录
|
|
|
+ * @return true-已登录, false-未登录
|
|
|
+ */
|
|
|
+public static boolean isLogin()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+if (LoginUserUtil.isLogin()) {
|
|
|
+ System.out.println("用户已登录");
|
|
|
+} else {
|
|
|
+ System.out.println("用户未登录");
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- `true`: 已登录
|
|
|
+- `false`: 未登录
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 9. isStorePlatformUser()
|
|
|
+
|
|
|
+验证当前用户类型是否为web端商户平台
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 验证当前用户类型是否为web端商户平台
|
|
|
+ * @return true-是商户平台用户, false-不是
|
|
|
+ */
|
|
|
+public static boolean isStorePlatformUser()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+if (LoginUserUtil.isStorePlatformUser()) {
|
|
|
+ System.out.println("商户平台用户,允许访问");
|
|
|
+} else {
|
|
|
+ System.out.println("非商户平台用户,拒绝访问");
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- `true`: 用户类型为 `storePlatform`
|
|
|
+- `false`: 用户类型不是 `storePlatform` 或未登录
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 10. getCurrentStoreId()
|
|
|
+
|
|
|
+获取当前登录用户的门店ID
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的门店ID
|
|
|
+ * @return 门店ID,如果未登录或用户无门店返回null
|
|
|
+ */
|
|
|
+public static Integer getCurrentStoreId()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+Integer storeId = LoginUserUtil.getCurrentStoreId();
|
|
|
+if (storeId != null) {
|
|
|
+ System.out.println("当前用户的门店ID: " + storeId);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回门店ID(Integer)
|
|
|
+- 未登录: 返回`null`
|
|
|
+- 用户无门店: 返回`null`
|
|
|
+
|
|
|
+**性能**: 🐢 较慢(需要查询数据库)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 11. getCurrentNickName()
|
|
|
+
|
|
|
+获取当前登录用户的昵称
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的昵称
|
|
|
+ * @return 昵称,如果未登录返回null
|
|
|
+ */
|
|
|
+public static String getCurrentNickName()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+String nickName = LoginUserUtil.getCurrentNickName();
|
|
|
+if (nickName != null) {
|
|
|
+ System.out.println("欢迎," + nickName);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回昵称(String)
|
|
|
+- 未登录: 返回`null`
|
|
|
+
|
|
|
+**性能**: 🐢 较慢(需要查询数据库)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 12. getCurrentName()
|
|
|
+
|
|
|
+获取当前登录用户的真实姓名
|
|
|
+
|
|
|
+```java
|
|
|
+/**
|
|
|
+ * 获取当前登录用户的真实姓名
|
|
|
+ * @return 真实姓名,如果未登录返回null
|
|
|
+ */
|
|
|
+public static String getCurrentName()
|
|
|
+```
|
|
|
+
|
|
|
+**使用示例**:
|
|
|
+```java
|
|
|
+String name = LoginUserUtil.getCurrentName();
|
|
|
+if (name != null) {
|
|
|
+ System.out.println("真实姓名: " + name);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**返回值**:
|
|
|
+- 成功: 返回真实姓名(String)
|
|
|
+- 未登录: 返回`null`
|
|
|
+
|
|
|
+**性能**: 🐢 较慢(需要查询数据库)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 实际应用场景
|
|
|
+
|
|
|
+### 场景1: 获取当前用户的基本信息
|
|
|
+
|
|
|
+```java
|
|
|
+@RestController
|
|
|
+@RequestMapping("/user")
|
|
|
+public class UserController {
|
|
|
+
|
|
|
+ @GetMapping("/profile")
|
|
|
+ public R<StoreUser> getUserProfile() {
|
|
|
+ // 获取当前登录用户的完整信息
|
|
|
+ StoreUser storeUser = LoginUserUtil.getCurrentStoreUser();
|
|
|
+ if (storeUser == null) {
|
|
|
+ return R.fail("请先登录");
|
|
|
+ }
|
|
|
+ return R.data(storeUser);
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 场景2: 验证用户权限(只能操作自己的数据)
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class StoreServiceImpl implements StoreService {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean updateStore(Integer storeId, StoreInfo storeInfo) {
|
|
|
+ // 获取当前用户的门店ID
|
|
|
+ Integer currentStoreId = LoginUserUtil.getCurrentStoreId();
|
|
|
+
|
|
|
+ // 验证用户只能修改自己的门店信息
|
|
|
+ if (!storeId.equals(currentStoreId)) {
|
|
|
+ throw new RuntimeException("您只能修改自己的门店信息");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行更新操作
|
|
|
+ return updateStoreInfo(storeInfo);
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 场景3: 自动填充当前用户信息
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class OrderServiceImpl implements OrderService {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean createOrder(Order order) {
|
|
|
+ // 自动填充当前用户信息
|
|
|
+ Integer userId = LoginUserUtil.getCurrentUserId();
|
|
|
+ Integer storeId = LoginUserUtil.getCurrentStoreId();
|
|
|
+
|
|
|
+ order.setUserId(userId);
|
|
|
+ order.setStoreId(storeId);
|
|
|
+ order.setCreateTime(new Date());
|
|
|
+
|
|
|
+ return orderMapper.insert(order) > 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 场景4: 根据用户类型返回不同数据
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class DashboardServiceImpl implements DashboardService {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public JSONObject getDashboardData() {
|
|
|
+ JSONObject result = new JSONObject();
|
|
|
+
|
|
|
+ // 验证用户类型
|
|
|
+ if (!LoginUserUtil.isStorePlatformUser()) {
|
|
|
+ throw new RuntimeException("只有商户平台用户可以访问");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取用户信息
|
|
|
+ Integer storeId = LoginUserUtil.getCurrentStoreId();
|
|
|
+
|
|
|
+ // 查询仪表盘数据
|
|
|
+ result.put("todayIncome", getTodayIncome(storeId));
|
|
|
+ result.put("todayOrderCount", getTodayOrderCount(storeId));
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 场景5: 日志记录(记录操作人)
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class AuditLogServiceImpl implements AuditLogService {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void logOperation(String action, String details) {
|
|
|
+ AuditLog log = new AuditLog();
|
|
|
+
|
|
|
+ // 记录操作人信息
|
|
|
+ log.setUserId(LoginUserUtil.getCurrentUserId());
|
|
|
+ log.setUserPhone(LoginUserUtil.getCurrentUserPhone());
|
|
|
+ log.setUserName(LoginUserUtil.getCurrentName());
|
|
|
+ log.setAction(action);
|
|
|
+ log.setDetails(details);
|
|
|
+ log.setOperateTime(new Date());
|
|
|
+
|
|
|
+ auditLogMapper.insert(log);
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 场景6: 条件查询(只查询当前用户的数据)
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class OrderServiceImpl implements OrderService {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<Order> getMyOrders(Integer page, Integer size) {
|
|
|
+ // 获取当前用户ID
|
|
|
+ Integer userId = LoginUserUtil.getCurrentUserId();
|
|
|
+ if (userId == null) {
|
|
|
+ throw new RuntimeException("请先登录");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询当前用户的订单
|
|
|
+ LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(Order::getUserId, userId)
|
|
|
+ .orderByDesc(Order::getCreateTime);
|
|
|
+
|
|
|
+ return orderMapper.selectPage(new Page<>(page, size), wrapper).getRecords();
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 场景7: 简化Controller代码
|
|
|
+
|
|
|
+**之前的写法**:
|
|
|
+```java
|
|
|
+@PostMapping("/updateProfile")
|
|
|
+public R<Boolean> updateProfile(@RequestBody StoreUser storeUser) {
|
|
|
+ // 需要手动获取用户信息
|
|
|
+ JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
+ if (userInfo == null) {
|
|
|
+ return R.fail("请先登录");
|
|
|
+ }
|
|
|
+ Integer userId = userInfo.getInteger("userId");
|
|
|
+ storeUser.setId(userId);
|
|
|
+
|
|
|
+ boolean success = storeUserService.updateById(storeUser);
|
|
|
+ return success ? R.success("修改成功") : R.fail("修改失败");
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**使用工具类后**:
|
|
|
+```java
|
|
|
+@PostMapping("/updateProfile")
|
|
|
+public R<Boolean> updateProfile(@RequestBody StoreUser storeUser) {
|
|
|
+ // 直接获取用户ID
|
|
|
+ Integer userId = LoginUserUtil.getCurrentUserId();
|
|
|
+ if (userId == null) {
|
|
|
+ return R.fail("请先登录");
|
|
|
+ }
|
|
|
+ storeUser.setId(userId);
|
|
|
+
|
|
|
+ boolean success = storeUserService.updateById(storeUser);
|
|
|
+ return success ? R.success("修改成功") : R.fail("修改失败");
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 性能对比
|
|
|
+
|
|
|
+| 方法 | 性能 | 是否查询数据库 | 适用场景 |
|
|
|
+|------|------|---------------|----------|
|
|
|
+| `getCurrentUserId()` | ⚡⚡⚡ 极快 | ❌ 否 | 只需要用户ID |
|
|
|
+| `getCurrentUserPhone()` | ⚡⚡⚡ 极快 | ❌ 否 | 只需要手机号 |
|
|
|
+| `getCurrentUserType()` | ⚡⚡⚡ 极快 | ❌ 否 | 验证用户类型 |
|
|
|
+| `getCurrentUserInfo()` | ⚡⚡⚡ 极快 | ❌ 否 | 需要Token中的多个字段 |
|
|
|
+| `getCurrentStoreUser()` | 🐢 较慢 | ✅ 是 | 需要完整用户信息 |
|
|
|
+| `getCurrentStoreUserByPhone()` | 🐢 较慢 | ✅ 是 | 根据手机号查询 |
|
|
|
+| `getCurrentStoreId()` | 🐢 较慢 | ✅ 是 | 只需要门店ID |
|
|
|
+| `getCurrentNickName()` | 🐢 较慢 | ✅ 是 | 只需要昵称 |
|
|
|
+| `getCurrentName()` | 🐢 较慢 | ✅ 是 | 只需要真实姓名 |
|
|
|
+
|
|
|
+**优化建议**:
|
|
|
+- ✅ 优先使用不查询数据库的方法(`getCurrentUserId()`、`getCurrentUserPhone()`等)
|
|
|
+- ✅ 如果需要多个用户字段,使用`getCurrentStoreUser()`一次性获取,避免多次查询
|
|
|
+- ✅ 不要在循环中调用需要查询数据库的方法
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 注意事项
|
|
|
+
|
|
|
+### 1. 空值处理
|
|
|
+
|
|
|
+所有方法在获取失败时都返回`null`,使用时需要判空:
|
|
|
+
|
|
|
+```java
|
|
|
+Integer userId = LoginUserUtil.getCurrentUserId();
|
|
|
+if (userId != null) {
|
|
|
+ // 处理业务逻辑
|
|
|
+} else {
|
|
|
+ // 处理未登录情况
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 异常处理
|
|
|
+
|
|
|
+工具类内部已处理所有异常,不会向外抛出异常,确保调用安全。
|
|
|
+
|
|
|
+### 3. 静态方法限制
|
|
|
+
|
|
|
+由于使用静态方法,需要通过`@Autowired`注入`StoreUserMapper`到静态字段。这是通过`@Component`和setter方法实现的。
|
|
|
+
|
|
|
+### 4. 性能考虑
|
|
|
+
|
|
|
+- **频繁调用**: 如果需要频繁获取用户信息,建议在Service层缓存
|
|
|
+- **数据库查询**: 避免在循环中调用需要查询数据库的方法
|
|
|
+
|
|
|
+### 5. 线程安全
|
|
|
+
|
|
|
+工具类是线程安全的,可以在多线程环境下使用。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 与 @LoginRequired 注解配合使用
|
|
|
+
|
|
|
+`LoginUserUtil` 与 `@LoginRequired` 注解配合使用效果更佳:
|
|
|
+
|
|
|
+```java
|
|
|
+@RestController
|
|
|
+@RequestMapping("/store")
|
|
|
+public class StoreController {
|
|
|
+
|
|
|
+ @LoginRequired // AOP切面验证登录
|
|
|
+ @GetMapping("/myStore")
|
|
|
+ public R<StoreInfo> getMyStore() {
|
|
|
+ // 登录验证已通过,直接获取门店ID
|
|
|
+ Integer storeId = LoginUserUtil.getCurrentStoreId();
|
|
|
+ StoreInfo storeInfo = storeService.getById(storeId);
|
|
|
+ return R.data(storeInfo);
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 配置要求
|
|
|
+
|
|
|
+### 1. Spring Bean注册
|
|
|
+
|
|
|
+工具类使用`@Component`注解,需要被Spring扫描到:
|
|
|
+
|
|
|
+```java
|
|
|
+@Component // 必须
|
|
|
+public class LoginUserUtil {
|
|
|
+ // ...
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 包扫描配置
|
|
|
+
|
|
|
+确保`LoginUserUtil`所在的包被Spring Boot扫描:
|
|
|
+
|
|
|
+```java
|
|
|
+@SpringBootApplication
|
|
|
+@ComponentScan(basePackages = {"shop.alien.storeplatform"})
|
|
|
+public class Application {
|
|
|
+ // ...
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 3. Mapper依赖
|
|
|
+
|
|
|
+确保`StoreUserMapper`已注册为Spring Bean:
|
|
|
+
|
|
|
+```java
|
|
|
+@Mapper
|
|
|
+public interface StoreUserMapper extends BaseMapper<StoreUser> {
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 常见问题
|
|
|
+
|
|
|
+### Q1: 为什么有时返回null?
|
|
|
+
|
|
|
+**原因**:
|
|
|
+1. 用户未登录(Token不存在或无效)
|
|
|
+2. Token已过期
|
|
|
+3. 用户在数据库中不存在
|
|
|
+4. 网络或数据库异常
|
|
|
+
|
|
|
+**解决方案**:
|
|
|
+- 使用前先判断是否已登录:`LoginUserUtil.isLogin()`
|
|
|
+- 检查日志中的错误信息
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Q2: 如何在非Controller层使用?
|
|
|
+
|
|
|
+**答案**: 工具类可以在任何Spring管理的Bean中使用:
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class MyService {
|
|
|
+
|
|
|
+ public void someMethod() {
|
|
|
+ Integer userId = LoginUserUtil.getCurrentUserId();
|
|
|
+ // 使用userId
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Q3: 性能是否有问题?
|
|
|
+
|
|
|
+**答案**:
|
|
|
+- Token解析方法(如`getCurrentUserId()`)性能很高,可以频繁调用
|
|
|
+- 数据库查询方法(如`getCurrentStoreUser()`)性能较低,建议缓存结果
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Q4: 如何缓存用户信息?
|
|
|
+
|
|
|
+**建议方案**:
|
|
|
+
|
|
|
+```java
|
|
|
+@Service
|
|
|
+public class MyService {
|
|
|
+
|
|
|
+ private StoreUser currentUser;
|
|
|
+
|
|
|
+ public void processOrder() {
|
|
|
+ // 第一次获取
|
|
|
+ if (currentUser == null) {
|
|
|
+ currentUser = LoginUserUtil.getCurrentStoreUser();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 后续使用缓存的数据
|
|
|
+ Integer storeId = currentUser.getStoreId();
|
|
|
+ // ...
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+或使用ThreadLocal缓存(适用于同一次请求)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 更新日志
|
|
|
+
|
|
|
+### 2025-11-17
|
|
|
+
|
|
|
+**新增工具类**:
|
|
|
+- ✅ 创建`LoginUserUtil`工具类
|
|
|
+
|
|
|
+**核心功能**:
|
|
|
+- ✅ 获取当前登录用户ID、手机号、用户类型
|
|
|
+- ✅ 获取Token中的用户信息(JSONObject)
|
|
|
+- ✅ 从数据库查询完整用户信息
|
|
|
+- ✅ 验证用户登录状态
|
|
|
+- ✅ 验证用户类型
|
|
|
+- ✅ 验证是否为当前用户
|
|
|
+- ✅ 获取门店ID、昵称、姓名等便捷方法
|
|
|
+
|
|
|
+**技术特点**:
|
|
|
+- ✅ 静态方法,方便调用
|
|
|
+- ✅ 完善的异常处理
|
|
|
+- ✅ 详细的日志记录
|
|
|
+- ✅ 支持多种获取方式
|
|
|
+
|
|
|
+**开发人员**: ssk
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+**文档版本**: v1.0
|
|
|
+**最后更新**: 2025-11-17
|
|
|
+**维护人员**: ssk
|
|
|
+
|