一、前言
在现代Web应用开发中,用户体验至关重要。其中一个重要的方面就是用户的活跃度管理,其中累计登录天数是一个衡量用户活跃程度的重要指标。本文将详细介绍如何在一个基于若依框架的应用中实现查询用户累计登录天数的功能,并且确保查询条件符合当前登录用户的信息、登录类型相同(登录、登出)以及状态正常。
二、背景知识
在开始之前,我们需要了解一些基础知识:
- 若依框架:这是一个基于Spring Boot的后台管理系统框架,它提供了丰富的组件和工具来快速搭建后端服务。
- MyBatis Plus:这是MyBatis的一个扩展插件,简化了常见的CRUD操作,并提供了强大的Lambda表达式支持。
- Spring Security:一个为Spring应用程序提供安全性的框架,用于认证和授权。
三、技术栈
- 后端:Java + Spring Boot
- 数据持久层:MyBatis Plus
- 安全框架:Spring Security
四、实现步骤
-
定义登录日志实体类
假设我们已经有了一个
LoginLogDO
实体类,它至少包含以下字段:public class LoginLogDO implements Serializable { private static final long serialVersionUID = 1L; private String username; private Integer type; private Integer status; private LocalDate loginDate; // 登录日期 // getter 和 setter 方法 }
这里我们假设
loginDate
字段已经是一个LocalDate
类型,这样可以直接用于日期比较,无需额外转换。 -
创建登录日志数据访问层
在若依框架中,我们可以利用MyBatis Plus提供的
BaseMapper
接口来创建一个登录日志的数据访问层:@Mapper public interface LoginLogMapper extends BaseMapper<LoginLogDO> { // 自定义方法 }
-
编写业务逻辑
接下来,我们需要在服务层编写一个方法来计算累计登录天数。这个方法将利用MyBatis Plus的查询功能来获取所有符合条件的登录日志,并计算不重复的登录日期数量。
@Service public class LoginLogService { @Autowired private LoginLogMapper loginLogMapper; @Autowired private SecurityHelper securityHelper; /** * 计算用户的累计登录天数 * @return 累计登录天数 */ public long calculateLoginDaysCount() { String currentUser = securityHelper.getUsername(); // 构建查询条件 Wrapper<LoginLogDO> countWrapper = Wrappers.<LoginLogDO>lambdaQuery() .eq(LoginLogDO::getUsername, currentUser) // 当前登录用户 .eq(LoginLogDO::getType, LoginConstants.TYPE_LOGIN) // 登录或登出类型 .eq(LoginLogDO::getStatus, CommonYNEnum.Y.integerVal()); // 状态正常 // 获取所有符合条件的日志记录 List<LoginLogDO> loginLogs = loginLogMapper.selectList(countWrapper); // 提取并去重登录日期 return loginLogs.stream() .map(LoginLogDO::getLoginTime) .map(date -> date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) .distinct() .count(); } }
-
添加安全辅助类
SecurityHelper
是一个帮助类,用于获取当前登录的用户名。这里假设它有一个静态方法getUsername()
来获取用户名。public class SecurityHelper { public static String getUsername() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || !authentication.isAuthenticated()) { throw new RuntimeException("未认证"); } return authentication.getName(); } }
-
定义常量和枚举
LoginConstants.TYPE_LOGIN
和LoginConstants.TYPE_LOGOUT
:分别代表登录和登出类型的常量值。CommonYNEnum.Y.integerVal()
:表示“是”的枚举值,通常用来表示成功的状态。
public class LoginConstants { public static final int TYPE_LOGIN = 1; public static final int TYPE_LOGOUT = 2; } public enum CommonYNEnum { Y(1), N(0); private int integerVal; CommonYNEnum(int integerVal) { this.integerVal = integerVal; } public int integerVal() { return integerVal; } }
-
测试功能
在完成以上步骤后,可以通过单元测试或集成测试来验证该功能是否正确工作。
@RunWith(SpringRunner.class) @SpringBootTest public class LoginLogServiceTest { @Autowired private LoginLogService loginLogService; @Test public void testCalculateLoginDaysCount() { long loginDaysCount = loginLogService.calculateLoginDaysCount(); System.out.println("累计登录天数: " + loginDaysCount); // 断言或其他验证 } }
五、注意事项
- 日期类型:确保
getLoginDate
方法返回的是LocalDate
类型的对象,以便于后续的日期处理。如果返回的是java.util.Date
或LocalDateTime
,则需要调整日期转换的方式。 - 异常处理:处理可能出现的异常情况,例如数据库查询失败等。可以使用
try-catch
块或者@ExceptionHandler
注解来捕获并处理异常。 - 性能优化:对于大数据量的系统,可以考虑使用索引来加速查询,或者采用分页查询的方式减少单次查询的数据量。
- 安全性:确保只有经过身份验证的用户才能调用此服务方法,并且只能查询自己的登录记录。
六、总结
通过上述步骤,我们可以在基于若依框架的应用中实现一个简单的用户累计登录天数的查询功能。