feat(common): 添加通用工具类和配置优化
- 新增 JsonConfig,统一配置Long转字符串和LocalDateTime多格式支持 - 新增 MybatisPlusConfig,集成分页插件支持PostgreSQL数据库 - 新增 PhoneUtils,提供手机号格式化、验证及脱敏工具方法 - 优化 UserRoleController,使用MyBatis-Plus分页插件实现分页查询和模糊搜索 - FeishuAuthServiceImpl中调用PhoneUtils去除手机号+86前缀,确保手机号一致性处理
This commit is contained in:
60
src/main/java/cn/yinlihupo/common/config/JsonConfig.java
Normal file
60
src/main/java/cn/yinlihupo/common/config/JsonConfig.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package cn.yinlihupo.common.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import org.springframework.boot.jackson.JsonComponent;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.ChronoField;
|
||||
|
||||
/**
|
||||
* Spring MVC Json 配置
|
||||
*/
|
||||
@JsonComponent
|
||||
public class JsonConfig {
|
||||
|
||||
/**
|
||||
* 添加 Long 转 json 精度丢失的配置
|
||||
* 配置 LocalDateTime 支持多种日期时间格式
|
||||
*/
|
||||
@Bean
|
||||
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
|
||||
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
|
||||
|
||||
// Long 类型序列化配置
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.addSerializer(Long.class, ToStringSerializer.instance);
|
||||
module.addSerializer(Long.TYPE, ToStringSerializer.instance);
|
||||
objectMapper.registerModule(module);
|
||||
|
||||
// Java 8 日期时间类型支持
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
|
||||
// 配置 LocalDateTime 的序列化和反序列化格式
|
||||
// 支持 "yyyy-MM-dd HH:mm:ss" 和 "yyyy-MM-dd HH:mm" 两种格式
|
||||
DateTimeFormatter deserializeFormatter = new DateTimeFormatterBuilder()
|
||||
.appendPattern("yyyy-MM-dd HH:mm")
|
||||
.optionalStart()
|
||||
.appendPattern(":ss")
|
||||
.optionalEnd()
|
||||
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) // 如果没有秒,默认00秒
|
||||
.toFormatter();
|
||||
|
||||
DateTimeFormatter serializeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(serializeFormatter));
|
||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(deserializeFormatter));
|
||||
|
||||
objectMapper.registerModule(javaTimeModule);
|
||||
|
||||
return objectMapper;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.yinlihupo.common.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* MyBatis-Plus 配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
/**
|
||||
* 添加分页插件
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
// 如果配置多个插件, 注意分页插件要放在最后
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
|
||||
return interceptor;
|
||||
}
|
||||
}
|
||||
90
src/main/java/cn/yinlihupo/common/util/PhoneUtils.java
Normal file
90
src/main/java/cn/yinlihupo/common/util/PhoneUtils.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package cn.yinlihupo.common.util;
|
||||
|
||||
/**
|
||||
* 手机号工具类
|
||||
* 提供手机号格式化、验证等通用方法
|
||||
*/
|
||||
public class PhoneUtils {
|
||||
|
||||
/**
|
||||
* 中国大陆手机号前缀
|
||||
*/
|
||||
private static final String CHINA_MOBILE_PREFIX = "+86";
|
||||
|
||||
/**
|
||||
* 去除手机号中的国家码前缀(如 +86)
|
||||
*
|
||||
* @param phone 原始手机号
|
||||
* @return 去除前缀后的手机号
|
||||
*/
|
||||
public static String normalizePhone(String phone) {
|
||||
if (phone == null || phone.isEmpty()) {
|
||||
return phone;
|
||||
}
|
||||
|
||||
// 去除 +86 前缀
|
||||
if (phone.startsWith(CHINA_MOBILE_PREFIX)) {
|
||||
return phone.substring(3);
|
||||
}
|
||||
|
||||
return phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加中国大陆手机号前缀(+86)
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return 添加前缀后的手机号
|
||||
*/
|
||||
public static String addChinaPrefix(String phone) {
|
||||
if (phone == null || phone.isEmpty()) {
|
||||
return phone;
|
||||
}
|
||||
|
||||
// 如果已经有前缀,直接返回
|
||||
if (phone.startsWith(CHINA_MOBILE_PREFIX)) {
|
||||
return phone;
|
||||
}
|
||||
|
||||
return CHINA_MOBILE_PREFIX + phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证手机号格式(中国大陆)
|
||||
* 简单验证:1开头,11位数字
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return true-格式正确, false-格式错误
|
||||
*/
|
||||
public static boolean isValidChinaPhone(String phone) {
|
||||
if (phone == null || phone.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 先去除前缀
|
||||
String normalizedPhone = normalizePhone(phone);
|
||||
|
||||
// 验证:1开头,11位数字
|
||||
return normalizedPhone.matches("^1[3-9]\\d{9}$");
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏手机号中间4位
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return 隐藏后的手机号,如:138****8888
|
||||
*/
|
||||
public static String maskPhone(String phone) {
|
||||
if (phone == null || phone.isEmpty()) {
|
||||
return phone;
|
||||
}
|
||||
|
||||
String normalizedPhone = normalizePhone(phone);
|
||||
|
||||
if (normalizedPhone.length() != 11) {
|
||||
return phone;
|
||||
}
|
||||
|
||||
return normalizedPhone.substring(0, 3) + "****" + normalizedPhone.substring(7);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -42,15 +43,21 @@ public class UserRoleController {
|
||||
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String keyword) {
|
||||
|
||||
|
||||
Page<SysUser> page = new Page<>(pageNum, pageSize);
|
||||
List<SysUser> users = userMapper.selectPageList(null, null, keyword);
|
||||
|
||||
// 手动设置分页结果
|
||||
page.setRecords(users);
|
||||
page.setTotal(users.size());
|
||||
|
||||
return ResultUtils.success("查询成功", page);
|
||||
// 使用MyBatis-Plus分页插件,将page作为第一个参数传入
|
||||
Page<SysUser> resultPage = userMapper.selectPage(page, new LambdaQueryWrapper<SysUser>()
|
||||
.eq(SysUser::getDeleted, 0)
|
||||
.and(StringUtils.hasText(keyword), qw -> qw
|
||||
.like(SysUser::getUsername, keyword)
|
||||
.or()
|
||||
.like(SysUser::getRealName, keyword)
|
||||
.or()
|
||||
.like(SysUser::getPhone, keyword)
|
||||
)
|
||||
.orderByDesc(SysUser::getCreateTime));
|
||||
|
||||
return ResultUtils.success("查询成功", resultPage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.yinlihupo.common.config.FeishuConfig;
|
||||
import cn.yinlihupo.common.util.PhoneUtils;
|
||||
import cn.yinlihupo.domain.entity.SysUser;
|
||||
import cn.yinlihupo.mapper.SysPermissionMapper;
|
||||
import cn.yinlihupo.mapper.SysUserMapper;
|
||||
@@ -84,6 +85,9 @@ public class FeishuAuthServiceImpl implements FeishuAuthService {
|
||||
String email = userInfo.getStr("email");
|
||||
String openId = userInfo.getStr("open_id");
|
||||
|
||||
// 去除手机号前缀 +86
|
||||
phone = PhoneUtils.normalizePhone(phone);
|
||||
|
||||
log.info("飞书用户信息: phone={}, name={}, openId={}", phone, realName, openId);
|
||||
|
||||
// 5. 根据手机号获取或创建用户
|
||||
|
||||
Reference in New Issue
Block a user