Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
luolm 2025-02-15 16:41:16 +08:00
commit 0ac1420b81
19 changed files with 172 additions and 94 deletions

View File

@ -23,6 +23,7 @@ import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
import com.nflg.mobilebroken.starter.service.EmailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
@ -34,7 +35,6 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.nio.charset.Charset;
import java.time.Duration;
import java.util.Base64;
import java.util.List;
@ -46,6 +46,7 @@ import java.util.List;
@RestController
@RequestMapping("/adminuser")
@Slf4j
@RefreshScope
public class AdminUserController extends ControllerBase {
@Value("${email.activate.admin.url}")
@ -196,21 +197,8 @@ public class AdminUserController extends ControllerBase {
return ApiResult.success();
}
/**
* 根据code获取email
*
* @param code 代码
* @return email
*/
@GetMapping("getEmailFromCode")
@ApiMark(moduleName = "账号管理", apiName = "根据code获取email", isPublic = true)
private ApiResult<String> getEmailFromCode(@Valid @NotBlank @RequestParam("code") String code) {
return ApiResult.success(StrUtil.str(Base64.getUrlDecoder().decode(code), Charset.defaultCharset()));
}
/**
* 激活账号
*
* @param request 请求信息
**/
@PostMapping("activateUser")

View File

@ -32,7 +32,6 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.nio.charset.Charset;
import java.time.Duration;
import java.util.Base64;
import java.util.List;
@ -240,16 +239,6 @@ public class UserController extends ControllerBase {
return ApiResult.success();
}
/**
* 根据code获取email
* @param code 代码
* @return email
*/
@GetMapping("getEmailFromCode")
private ApiResult<String> getEmailFromCode(@Valid @NotBlank @RequestParam("code") String code) {
return ApiResult.success(StrUtil.str(Base64.getUrlDecoder().decode(code), Charset.defaultCharset()));
}
/**
* 激活用户
* @param request 请求信息

View File

@ -16,7 +16,8 @@ public enum MessageSubType {
TicketCompletion(6, "工单完成"),
TicketClosed(7, "工单关闭"),
TicketCancellation(8, "工单撤销"),
TicketReopen(9, "工单重启");
TicketReopen(9, "工单重启"),
TicketTimeout(10, "工单超时");
private final Integer state;
private final String description;

View File

@ -3,14 +3,11 @@ package com.nflg.mobilebroken.common.pojo.request;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
@EqualsAndHashCode(callSuper = false)
@Data
public class AccountUpdateRequest extends AccountAddRequest {
private Integer id;
@NotNull
private Boolean enable;
}

View File

@ -2,15 +2,20 @@ package com.nflg.mobilebroken.common.pojo.request;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class UserActivateRequest {
//邮箱
private String email;
//随机码
//代码
@NotBlank
private String code;
//随机码
@NotBlank
private String randomCode;
//新密码
@NotBlank
private String password;
}

View File

@ -1,8 +1,10 @@
package com.nflg.mobilebroken.common.pojo.vo;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class DictionaryItemTranslateVO {
private Integer id;

View File

@ -1,5 +1,7 @@
package com.nflg.mobilebroken.common.util;
import com.nflg.mobilebroken.common.constant.STATE;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -9,43 +11,27 @@ public class AdminUserUtil {
private static final Map<Integer, List<String>> PERMISSION_MAP = new ConcurrentHashMap<>();
public static Integer getUserId(){
// SaTokenInfo tokenValue = SaTokenAdminUtil.getTokenInfo();
// if (SaTokenAdminUtil.isLogin()) {
// return SaTokenAdminUtil.getLoginIdAsInt();
// }
// return 1;
VUtils.trueThrow(!SaTokenAdminUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return SaTokenAdminUtil.getLoginIdAsInt();
}
public static String getUserName() {
// if (SaTokenAdminUtil.isLogin()) {
// return (String) SaTokenAdminUtil.getExtra("name");
// }
// return "admin";
VUtils.trueThrow(!SaTokenAdminUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return (String) SaTokenAdminUtil.getExtra("name");
}
public static List<String> getRoles() {
// if (SaTokenAdminUtil.isLogin()) {
// return (List<String>) SaTokenAdminUtil.getExtra("roles");
// }
// return ListUtil.of("管理员");
VUtils.trueThrow(!SaTokenAdminUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return (List<String>) SaTokenAdminUtil.getExtra("roles");
}
public static String getUserNo(){
// if (SaTokenAdminUtil.isLogin()) {
// return (String) SaTokenAdminUtil.getExtra("code");
// }
// return "admin";
VUtils.trueThrow(!SaTokenAdminUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return (String) SaTokenAdminUtil.getExtra("code");
}
public static String getEmail() {
// if (SaTokenAdminUtil.isLogin()) {
// return (String) SaTokenAdminUtil.getExtra("email");
// }
// return "aa@gmail.com";
VUtils.trueThrow(!SaTokenAdminUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return (String) SaTokenAdminUtil.getExtra("email");
}

View File

@ -1,5 +1,6 @@
package com.nflg.mobilebroken.common.util;
import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.pojo.dto.UserDTO;
import java.util.List;
@ -7,34 +8,22 @@ import java.util.List;
public class AppUserUtil {
public static Integer getUserId() {
// if (SaTokenAppUtil.isLogin()) {
// return SaTokenAppUtil.getLoginIdAsInt();
// }
// return 1;
VUtils.trueThrow(!SaTokenAppUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return SaTokenAppUtil.getLoginIdAsInt();
}
public static String getUserName() {
// if (SaTokenAppUtil.isLogin()) {
// return (String) SaTokenAppUtil.getExtra("name");
// }
// return "admin";
VUtils.trueThrow(!SaTokenAppUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return (String) SaTokenAppUtil.getExtra("name");
}
public static String getEmail() {
// if (SaTokenAppUtil.isLogin()) {
// return (String) SaTokenAppUtil.getExtra("email");
// }
// return "aa@gmail.com";
VUtils.trueThrow(!SaTokenAppUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return (String) SaTokenAppUtil.getExtra("email");
}
public static List<Integer> getCompanyIds() {
// if (SaTokenAppUtil.isLogin()) {
// return (List<Integer>) SaTokenAppUtil.getExtra("companyIds");
// }
// return ListUtil.of(1);
VUtils.trueThrow(!SaTokenAppUtil.isLogin()).throwMessage(STATE.LoginError,"请重新登录");
return (List<Integer>) SaTokenAppUtil.getExtra("companyIds");
}

View File

@ -55,7 +55,7 @@ public class AdminMessage implements Serializable {
private Integer type;
/**
* 任务事项0账号申请1账号启用2账号延期3工单待分派4工单分派5工单新消息6工单完成7工单关闭8工单撤销9工单重启
* 任务事项0账号申请1账号启用2账号延期3工单待分派4工单分派5工单新消息6工单完成7工单关闭8工单撤销9工单重启10工单超时
*/
private Integer subType;

View File

@ -3,12 +3,13 @@ package com.nflg.mobilebroken.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 消息
@ -39,9 +40,9 @@ public class AppMessage implements Serializable {
private Integer userId;
/**
* 提醒事项
* 任务事项5工单新消息6工单完成10工单超时
*/
private String content;
private Integer subType;
/**
* 是否已读

View File

@ -247,7 +247,7 @@ public class AdminMenuServiceImpl extends ServiceImpl<AdminMenuMapper, AdminMenu
.eq(AdminMenuButton::getMenuId, menu.getId())
.eq(AdminMenuButton::getEnable, true)
.list();
menu.setChildren(datas.stream()
menu.setChildren(vos.stream()
.map(d -> new AuthorizeMenuVO().setType(2).setId(d.getId()).setName(d.getName()).setSelected(buttonIsSelected(roleId, d.getId())))
.collect(Collectors.toList()));
}

View File

@ -7,7 +7,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.constant.UserState;
import com.nflg.mobilebroken.common.exception.NflgException;
import com.nflg.mobilebroken.common.pojo.PageData;
import com.nflg.mobilebroken.common.pojo.request.*;
import com.nflg.mobilebroken.common.pojo.vo.AdminUserVO;
@ -23,11 +25,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -92,12 +92,14 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
.setAvatar(request.getAvatar())
.setDepartmentId(request.getDepartmentId())
.setEmail(request.getEmail())
.setState(request.getEnable() ? UserState.Activated.getState() : UserState.Disabled.getState())
.setLoginName(request.getLoginName())
.setPhone(request.getPhone())
.setTitleId(request.getTitleId())
.setUpdateBy(AdminUserUtil.getUserId())
.setUpdateTime(LocalDateTime.now());
if (Objects.nonNull(request.getEnable())){
user.setState(request.getEnable() ? UserState.Activated.getState() : UserState.Disabled.getState());
}
updateById(user);
}
@ -174,6 +176,7 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
VUtils.trueThrowBusinessError(Objects.isNull(user)).throwMessage("用户不存在");
user.setPassword(encodePassword);
user.setUpdateTime(LocalDateTime.now());
user.setState(UserState.ToBeActivated.getState());
updateById(user);
return user.getEmail();
}
@ -196,8 +199,15 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
@Override
public void activateUser(UserActivateRequest request) {
String email="";
try {
email=StrUtil.str(Base64.getUrlDecoder().decode(request.getCode()), Charset.defaultCharset());
}catch (IllegalArgumentException ex){
log.error("无效的code:"+request.getCode());
throw new NflgException(STATE.ParamErr,"无效的code:"+request.getCode());
}
AdminUser adminUser = lambdaQuery()
.eq(AdminUser::getLoginName, request.getEmail())
.eq(AdminUser::getLoginName, email)
.one();
VUtils.trueThrowBusinessError(Objects.isNull(adminUser)).throwMessage("用户不存");
VUtils.trueThrowBusinessError(!Objects.equals(adminUser.getState(), UserState.ToBeActivated.getState()))

View File

@ -7,13 +7,14 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.mobilebroken.common.constant.AppUserApplyForState;
import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.constant.UserState;
import com.nflg.mobilebroken.common.exception.NflgException;
import com.nflg.mobilebroken.common.pojo.PageData;
import com.nflg.mobilebroken.common.pojo.request.*;
import com.nflg.mobilebroken.common.pojo.vo.AppUserForAdminVO;
import com.nflg.mobilebroken.common.pojo.vo.AppUserVO;
import com.nflg.mobilebroken.common.pojo.vo.CompanyVO;
import com.nflg.mobilebroken.common.util.AdminUserUtil;
import com.nflg.mobilebroken.common.util.AppUserUtil;
import com.nflg.mobilebroken.common.util.PageUtil;
import com.nflg.mobilebroken.common.util.VUtils;
@ -26,6 +27,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.chrono.ChronoLocalDate;
import java.util.*;
@ -156,7 +158,7 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
.setCompanyId(StrUtil.join(",", request.getCompanyIds()))
.setIsPrimary(true)
.setSalesUserName(request.getSalesUserName())
.setCreateBy(AdminUserUtil.getUserId())
// .setCreateBy(AdminUserUtil.getUserId())
.setCreateTime(LocalDateTime.now())
.setState(UserState.ToBeActivated.getState())
.setExpireTime(LocalDateTime.of(LocalDateTime.now().getYear(), 12, 31, 0, 0, 0).toLocalDate());
@ -170,6 +172,23 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
.ne(AppUser::getId, request.getId())
.exists())
.throwMessage("登录名已存在");
List<Integer> companyIds = lambdaQuery()
.select(AppUser::getCompanyId)
.eq(AppUser::getIsPrimary, true)
.list()
.stream()
.map(AppUser::getCompanyId)
.flatMap(s -> Arrays.stream(s.split(",")))
.map(Integer::parseInt)
.collect(Collectors.toList());
List<Integer> cIds = request.getCompanyIds().stream()
.filter(companyIds::contains)
.collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(cIds)) {
VUtils.trueThrowBusinessError(true)
.throwMessage("以下公司已设置主账号:" + StrUtil.join(",", customerService.listByIds(cIds).stream()
.map(TBaseCustomer::getAgencyCompanyName).collect(Collectors.toList())));
}
AppUser user = new AppUser()
.setId(request.getId())
.setLoginName(request.getLoginName())
@ -179,7 +198,7 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
.setAreaId(request.getAreaId())
.setCompanyId(StrUtil.join(",", request.getCompanyIds()))
.setIsPrimary(true)
.setUpdateBy(AdminUserUtil.getUserId())
// .setUpdateBy(AdminUserUtil.getUserId())
.setUpdateTime(LocalDateTime.now())
.setState(request.getEnable() ? UserState.Activated.getState() : UserState.Disabled.getState());
updateById(user);
@ -357,7 +376,7 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
VUtils.trueThrowBusinessError(!Objects.equals(appUser.getState(), UserState.Activated.getState())).throwMessage(id + "非启用状态");
VUtils.trueThrowBusinessError(Objects.equals(appUser.getIsPrimary(), false)).throwMessage(id + "不是主账号");
appUser.setExpireTime(appUser.getExpireTime().plusMonths(request.getMonth()));
appUser.setUpdateBy(AdminUserUtil.getUserId());
// appUser.setUpdateBy(AdminUserUtil.getUserId());
appUser.setUpdateTime(now);
updateById(appUser);
// List<String> companys = StrUtil.split(",", appUser.getCompanyId());
@ -418,8 +437,15 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
@Override
public void activateUser(UserActivateRequest request) {
String email="";
try {
email=StrUtil.str(Base64.getUrlDecoder().decode(request.getCode()), Charset.defaultCharset());
}catch (IllegalArgumentException ex){
log.error("无效的code:"+request.getCode());
throw new NflgException(STATE.ParamErr,"无效的code:"+request.getCode());
}
AppUser appUser = lambdaQuery()
.eq(AppUser::getLoginName, request.getEmail())
.eq(AppUser::getLoginName, email)
.one();
VUtils.trueThrowBusinessError(Objects.isNull(appUser)).throwMessage("用户不存在或随机码不正确");
VUtils.trueThrowBusinessError(!Objects.equals(appUser.getState(), UserState.ToBeActivated.getState()))

View File

@ -48,7 +48,18 @@ public class DictionaryItemTranslateServiceImpl extends ServiceImpl<DictionaryIt
@Override
public List<DictionaryItemTranslateVO> getListByDictionaryItemId(Integer id) {
return baseMapper.getListByDictionaryItemId(id);
List<DictionaryItemTranslateVO> datas=baseMapper.getListByDictionaryItemId(id);
List<Language> languages=languageService.getLanguages();
languages.forEach(l->{
DictionaryItemTranslateVO vo=datas.stream().filter(d->StrUtil.equals(l.getCode(),d.getCode())).findFirst().orElse(null);
if (Objects.isNull(vo)){
vo=new DictionaryItemTranslateVO()
.setCode(l.getCode())
.setName(l.getName());
datas.add(vo);
}
});
return datas;
}
@Override

View File

@ -6,7 +6,7 @@
SELECT m.id,m.no,m.source,m.source_id AS 'sourceId',m.type,m.sub_type AS 'subType',m.create_time AS 'createTime',
u.user_name AS 'userName',m.is_read AS 'isRead'
FROM admin_message m
INNER JOIN admin_user u ON t.user_id=u.id
INNER JOIN admin_user u ON m.user_id=u.id
WHERE m.user_id=#{userId}
<if test="request.type != null">
AND m.type=#{request.type}

View File

@ -7,6 +7,7 @@ import com.nflg.mobilebroken.common.exception.NflgException;
import com.nflg.mobilebroken.common.pojo.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ -30,9 +31,14 @@ public class GlobalRestControllerAdvice {
}
@ExceptionHandler(NflgException.class)
public ApiResult<Void> handleNflgException(NflgException ex) {
log.error("业务错误: ", ex);
return ApiResult.error(ex.getState(), ex.getMessage());
public ResponseEntity<Object> handleNflgException(NflgException ex) {
if (ex.getState() == STATE.LoginError) {
log.error("登录失效: ", ex);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ex.getMessage());
} else {
log.error("业务错误: ", ex);
return ResponseEntity.ok().body(ApiResult.error(ex.getState(), ex.getMessage()));
}
}
@ExceptionHandler(ConstraintViolationException.class)

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.pojo.ApiResult;
import com.nflg.mobilebroken.common.util.AdminUserUtil;
import com.nflg.mobilebroken.common.util.SaTokenAdminUtil;
import com.nflg.mobilebroken.repository.entity.TBaseRequestLog;
import com.nflg.mobilebroken.repository.entity.TBaseRequestLogDetail;
import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
@ -56,7 +57,9 @@ public class LoggingAspect {
logRecord.setRequestIp(request.getRemoteAddr());
logRecord.setRequestType(request.getMethod());
logRecord.setRequestResult(true);
logRecord.setDataCreateUserName(AdminUserUtil.getUserName());
if (SaTokenAdminUtil.isLogin()) {
logRecord.setDataCreateUserName(AdminUserUtil.getUserName());
}
logRecord.setDataCreateTime(LocalDateTime.now());
logRecord.setMethodName(apiOperation.value());
@ -74,7 +77,7 @@ public class LoggingAspect {
logRecord.setRequestResult(false);
logDetail.setRequestErrMsg(stackTraceElements.length > 0 ? ex.getMessage() + ":" + stackTraceElements[0].toString() : "");
logger.error("未捕获的异常", ex);
return ApiResult.error(STATE.Error,"操作出现错误"+ex.getMessage());
return ApiResult.error(STATE.Error,ex.getMessage());
}
finally {
requestLog.addLog(logRecord,logDetail);

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.nflg.mobilebroken.starter.handler.UTCLocalDateTimeTypeHandler;
import com.nflg.mobilebroken.starter.handler.UTCLocalDateTypeHandler;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.mybatis.spring.annotation.MapperScan;
@ -20,6 +21,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Configuration
@ -89,6 +91,7 @@ public class MysqlDataSourceConfig {
configuration.setCallSettersOnNulls(true);
TypeHandlerRegistry typeHandlerRegistry =configuration.getTypeHandlerRegistry();
typeHandlerRegistry.register(LocalDateTime.class, new UTCLocalDateTimeTypeHandler());
typeHandlerRegistry.register(LocalDate.class, new UTCLocalDateTypeHandler());
sqlSessionFactoryBean.setConfiguration(configuration);
sqlSessionFactoryBean.setDataSource(masterDataSource);
// 配置拦截器

View File

@ -0,0 +1,61 @@
package com.nflg.mobilebroken.starter.handler;
import com.nflg.mobilebroken.common.util.MultilingualUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Objects;
@MappedTypes(LocalDate.class)
public class UTCLocalDateTypeHandler extends BaseTypeHandler<LocalDate> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, LocalDate parameter, JdbcType jdbcType) throws SQLException {
// 将本地时间转换为 UTC 时间
LocalDateTime utcTime = parameter.atStartOfDay(ZoneId.systemDefault())
.withZoneSameInstant(ZoneOffset.UTC)
.toLocalDateTime();
ps.setObject(i, utcTime);
}
@Override
public LocalDate getNullableResult(ResultSet rs, String columnName) throws SQLException {
LocalDate utcTime = rs.getObject(columnName, LocalDate.class);
// UTC 时间转换为本地时间
return convertToLocalDate(utcTime);
}
@Override
public LocalDate getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
LocalDate utcTime = rs.getObject(columnIndex, LocalDate.class);
// UTC 时间转换为本地时间
return convertToLocalDate(utcTime);
}
@Override
public LocalDate getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
LocalDate utcTime = cs.getObject(columnIndex, LocalDate.class);
// UTC 时间转换为本地时间
return convertToLocalDate(utcTime);
}
private LocalDate convertToLocalDate(LocalDate utcTime) {
if (utcTime == null) {
return null;
}
String zone = MultilingualUtil.getZone();
return utcTime
.atStartOfDay(ZoneOffset.UTC)
.withZoneSameInstant(ZoneId.of(Objects.isNull(zone) ? "Asia/Shanghai" : zone))
.toLocalDate();
}
}