【登录】安眼统一认证

This commit is contained in:
2025-10-30 10:14:51 +08:00
parent 4356433ee0
commit 051905a6f2
17 changed files with 1301 additions and 432 deletions
@@ -18,10 +18,18 @@ import java.util.List;
public interface AnYanClient {
/**
* 获取服务访问令牌
*
* @return
*/
String getAuthToken();
/**
* 获取服务访问令牌(密码模式)
*
* @return
*/
AuthResult getAuthTokenByPassword(String username, String password);
/**
* 刷新口令
*/
@@ -29,6 +37,7 @@ public interface AnYanClient {
/**
* 体检医院人数统计查询
*
* @param medicalYear 体检年份
* @return
*/
@@ -36,6 +45,7 @@ public interface AnYanClient {
/**
* 健康打卡数据统计查询(血压,减重,血糖)
*
* @param beginDate
* @param endDate
* @return
@@ -43,21 +53,24 @@ public interface AnYanClient {
HealthSignStatVO healthCheckStatistics(Date beginDate, Date endDate);
/**
*健康打卡异常数据详细查询(血压)
* 健康打卡异常数据详细查询(血压)
*
* @param healthSignListParam
* @return
*/
IPage<BloodPressureList> bloodPressureList(HealthSignListParam healthSignListParam);
/**
*健康打卡异常数据详细查询(减重)
* 健康打卡异常数据详细查询(减重)
*
* @param healthSignListParam
* @return
*/
IPage<WeightPressureList> weightPressureList(HealthSignListParam healthSignListParam);
/**
*健康打卡异常数据详细查询(血糖)
* 健康打卡异常数据详细查询(血糖)
*
* @param healthSignListParam
* @return
*/
@@ -65,18 +78,21 @@ public interface AnYanClient {
/**
* 油田医院数据查询
*
* @return
*/
List<HospitalListVO> hospitalList();
/**
* 健康小屋基础数据查询
*
* @return
*/
List<HealthRoomBaseVO> healthPlaceHomList();
/**
* 健康小屋详细数据查询
*
* @param healthRoomDTO
* @return
*/
@@ -84,6 +100,7 @@ public interface AnYanClient {
/**
* 当年体检异常人数统计
*
* @param medicalYear 年份
* @return
*/
@@ -91,6 +108,7 @@ public interface AnYanClient {
/**
* 当年体检异常人员列表
*
* @param param
* @return
*/
@@ -98,13 +116,23 @@ public interface AnYanClient {
/**
* 公网环境获取服务访问token (目前仅用于访问安眼大屏)
*
* @return
*/
String publicNetworkToken();
/**
* 公网环境获取服务访问token (目前仅用于访问安眼大屏, 不走缓存, 每次用现取)
*
* @return
*/
AuthResult publicNetworkTokenNoCache();
/**
* 获取用户信息
*
* @param token
* @return
*/
AnYanUserInfoResult getAnYanUserInfo(String token);
}
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -20,6 +21,7 @@ import com.renkang.anyan.utils.PageResultToBeanUtil;
import com.renkang.anyan.utils.SM4Utils;
import com.renkang.anyan.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.jeecg.common.exception.ExceptionAssertsUtil;
import org.jeecg.util.RedisClientUtil;
@@ -31,9 +33,13 @@ import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -43,6 +49,7 @@ import java.util.stream.Collectors;
* @Date: 2025-8-1
* @Version: V1.0
*/
@Slf4j
@Service
@EnableRetry
@RequiredArgsConstructor
@@ -54,43 +61,79 @@ public class AnYanClientExecutor implements AnYanClient {
@Override
public String getAuthToken() {
String token = redisClientUtil.get(new RedisKeyPrefix(AnYanConstants.AN_YAN_API_TOKEN_PREFIX) ,"token",String.class);
if(StrUtil.isEmpty(token)){
String token = redisClientUtil.get(new RedisKeyPrefix(AnYanConstants.AN_YAN_API_TOKEN_PREFIX), "token", String.class);
if (StrUtil.isEmpty(token)) {
AuthResult authResult = getAuthTokenExecutor();
if(ObjectUtil.isNotEmpty(authResult) && StrUtil.isNotEmpty(authResult.getAccess_token())){
if (ObjectUtil.isNotEmpty(authResult) && StrUtil.isNotEmpty(authResult.getAccess_token())) {
token = authResult.getAccess_token();
int expireSeconds = ObjectUtil.isNotEmpty(authResult.getExpires_in())? authResult.getExpires_in() : 7200;
redisClientUtil.set(new RedisKeyPrefix(expireSeconds,AnYanConstants.AN_YAN_API_TOKEN_PREFIX),"token", token);
int expireSeconds = ObjectUtil.isNotEmpty(authResult.getExpires_in()) ? authResult.getExpires_in() : 7200;
redisClientUtil.set(new RedisKeyPrefix(expireSeconds, AnYanConstants.AN_YAN_API_TOKEN_PREFIX), "token", token);
}
}
return token;
}
private AuthResult getAuthTokenExecutor(){
private AuthResult getAuthTokenExecutor() {
AuthParam authParam = new AuthParam();
authParam.setClient_id(anYanProperties.getClientId());
authParam.setClient_secret(anYanProperties.getClientSecret());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
ResponseEntity<AuthResult> responseEntity = RestTemplateUtil.postExchange(AnYanApiEnum.QUERY_AUTH_TOKEN,headers,authParam,AuthResult.class);
if(HttpStatus.OK.equals(responseEntity.getStatusCode()) && ObjectUtils.isNotEmpty(responseEntity.getBody())){
ResponseEntity<AuthResult> responseEntity = RestTemplateUtil.postExchange(AnYanApiEnum.QUERY_AUTH_TOKEN, headers, authParam, AuthResult.class);
if (HttpStatus.OK.equals(responseEntity.getStatusCode()) && ObjectUtils.isNotEmpty(responseEntity.getBody())) {
return responseEntity.getBody();
}else {
} else {
ExceptionAssertsUtil.fail("------安眼系统获取token失败------" + responseEntity.getBody());
}
return new AuthResult();
}
/**
* @description: 通过密码获取令牌
* @author PengJ
* @date 2025/10/24 11:15
*/
@Override
public AuthResult getAuthTokenByPassword(String username, String password) {
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("grant_type", "password");
formData.add("username", username);
formData.add("password", password);
formData.add("client_id", anYanProperties.getClientId());
formData.add("client_secret", anYanProperties.getClientSecret());
ResponseEntity<AuthResult> authResult = RestTemplateUtil.postExchangeForGetTokenByPassword(AnYanApiEnum.QUERY_AUTH_TOKEN, formData, headers, AuthResult.class);
if (HttpStatus.OK.equals(authResult.getStatusCode())
&& ObjectUtils.isNotEmpty(authResult.getBody())) {
return authResult.getBody();
} else {
log.error("------安眼系统获取token失败(密码模式){}------", authResult.getBody());
ExceptionAssertsUtil.fail("------安眼系统获取token失败------" + authResult.getBody());
return null;
}
} catch (HttpClientErrorException e) {
String replace = Objects.requireNonNull(e.getMessage()).replace("401 Unauthorized: ", "");
replace = replace.replace("\"", "");
AuthResult bean = JSONUtil.toBean(replace, AuthResult.class);
ExceptionAssertsUtil.fail(bean.getMessage());
} catch (Exception e) {
ExceptionAssertsUtil.fail(e.getMessage());
}
return null;
}
@Override
public void refreshToken() {
AuthResult authResult = getAuthTokenExecutor();
if(ObjectUtil.isNotEmpty(authResult) && StrUtil.isNotEmpty(authResult.getAccess_token())){
int expireSeconds = ObjectUtil.isNotEmpty(authResult.getExpires_in())? authResult.getExpires_in() : 7200;
redisClientUtil.set(new RedisKeyPrefix(expireSeconds,AnYanConstants.AN_YAN_API_TOKEN_PREFIX),"token", authResult.getAccess_token());
if (ObjectUtil.isNotEmpty(authResult) && StrUtil.isNotEmpty(authResult.getAccess_token())) {
int expireSeconds = ObjectUtil.isNotEmpty(authResult.getExpires_in()) ? authResult.getExpires_in() : 7200;
redisClientUtil.set(new RedisKeyPrefix(expireSeconds, AnYanConstants.AN_YAN_API_TOKEN_PREFIX), "token", authResult.getAccess_token());
}
}
private HttpHeaders buildTokenHeader(){
private HttpHeaders buildTokenHeader() {
HttpHeaders headers = new HttpHeaders();
headers.add(AnYanConstants.AUTHORIZATION, AnYanConstants.TOKEN_TYPE + getAuthToken());
return headers;
@@ -99,9 +142,11 @@ public class AnYanClientExecutor implements AnYanClient {
@Override
@Retryable(maxAttempts = 2)
public List<MedicalPeopleNumStatisticsVO> examinationStatistics(Integer medicalYear) {
if(null == medicalYear){ medicalYear = DateUtil.year(new Date()); }
if (null == medicalYear) {
medicalYear = DateUtil.year(new Date());
}
JSONObject param = new JSONObject();
param.put("medicalYear",String.valueOf(medicalYear));
param.put("medicalYear", String.valueOf(medicalYear));
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.HEALTH_EXAMINATION_STATISTICS, buildTokenHeader(), param);
List<Object> listMaps = (List<Object>) result.getData();
return listMaps.stream().map(lMap -> BeanUtil.toBean(lMap, MedicalPeopleNumStatisticsVO.class)).collect(Collectors.toList());
@@ -111,31 +156,31 @@ public class AnYanClientExecutor implements AnYanClient {
@Retryable(maxAttempts = 2)
public HealthSignStatVO healthCheckStatistics(Date beginDate, Date endDate) {
JSONObject param = new JSONObject();
param.put("inputDateBegin",ObjectUtil.isEmpty(beginDate)? DateUtil.today() : DateUtil.formatDate(beginDate));
param.put("inputDateEnd",ObjectUtil.isEmpty(endDate)? DateUtil.today() : DateUtil.formatDate(endDate));
param.put("inputDateBegin", ObjectUtil.isEmpty(beginDate) ? DateUtil.today() : DateUtil.formatDate(beginDate));
param.put("inputDateEnd", ObjectUtil.isEmpty(endDate) ? DateUtil.today() : DateUtil.formatDate(endDate));
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.HEALTH_CHECK_STATISTICS, buildTokenHeader(), param);
return BeanUtil.toBean(result.getData(),HealthSignStatVO.class);
return BeanUtil.toBean(result.getData(), HealthSignStatVO.class);
}
@Override
@Retryable(maxAttempts = 2)
public IPage<BloodPressureList> bloodPressureList(HealthSignListParam healthSignListParam) {
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.BLOOD_PRESSURE_LIST, buildTokenHeader(), healthSignListParam);
return new PageResultToBeanUtil<BloodPressureList>().transform(result,BloodPressureList.class);
return new PageResultToBeanUtil<BloodPressureList>().transform(result, BloodPressureList.class);
}
@Override
@Retryable(maxAttempts = 2)
public IPage<WeightPressureList> weightPressureList(HealthSignListParam healthSignListParam) {
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.WEIGHT_PRESSURE_LIST, buildTokenHeader(), healthSignListParam);
return new PageResultToBeanUtil<WeightPressureList>().transform(result,WeightPressureList.class);
return new PageResultToBeanUtil<WeightPressureList>().transform(result, WeightPressureList.class);
}
@Override
@Retryable(maxAttempts = 2)
public IPage<BloodSugarClockSList> bloodSugarClockSList(HealthSignListParam healthSignListParam) {
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.BLOOD_SUGAR_CLOCKS_LIST, buildTokenHeader(), healthSignListParam);
return new PageResultToBeanUtil<BloodSugarClockSList>().transform(result,BloodSugarClockSList.class);
return new PageResultToBeanUtil<BloodSugarClockSList>().transform(result, BloodSugarClockSList.class);
}
@Override
@@ -149,7 +194,7 @@ public class AnYanClientExecutor implements AnYanClient {
@Override
@Retryable(maxAttempts = 2)
public List<HealthRoomBaseVO> healthPlaceHomList() {
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.HEALTH_PLACE_ROOM_LIST, buildTokenHeader(),null);
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.HEALTH_PLACE_ROOM_LIST, buildTokenHeader(), null);
List<Object> listMaps = (List<Object>) result.getData();
return listMaps.stream().map(lMap -> BeanUtil.toBean(lMap, HealthRoomBaseVO.class)).collect(Collectors.toList());
}
@@ -158,61 +203,63 @@ public class AnYanClientExecutor implements AnYanClient {
@Retryable(maxAttempts = 2)
public IPage<HealthPlaceHomDetailsVO> healthPlaceHomDetailList(HealthRoomDTO healthRoomDTO) {
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.HEALTH_PLACE_ROOM_INFO_LIST, buildTokenHeader(), healthRoomDTO);
return new PageResultToBeanUtil<HealthPlaceHomDetailsVO>().transform(result,HealthPlaceHomDetailsVO.class);
return new PageResultToBeanUtil<HealthPlaceHomDetailsVO>().transform(result, HealthPlaceHomDetailsVO.class);
}
@Override
@Retryable(maxAttempts = 2)
public MedicalAbnormalStatisticsVO medicalAbnormalStatistics(Integer medicalYear) {
if(null == medicalYear){ medicalYear = DateUtil.year(new Date()); }
if (null == medicalYear) {
medicalYear = DateUtil.year(new Date());
}
JSONObject param = new JSONObject();
param.put("medicalYear",medicalYear);
param.put("medicalYear", medicalYear);
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.MEDICAL_ABNORMAL_STATISTICS, buildTokenHeader(), param);
return BeanUtil.toBean(result.getData(),MedicalAbnormalStatisticsVO.class);
return BeanUtil.toBean(result.getData(), MedicalAbnormalStatisticsVO.class);
}
@Override
@Retryable(maxAttempts = 2)
public IPage<MedicalAbnormalVO> medicalAbnormalList(MedicalAbnormalDTO param) {
AnYanResult<Object> result = RestTemplateUtil.postExchange(AnYanApiEnum.MEDICAL_ABNORMAL_LIST, buildTokenHeader(), param);
return new PageResultToBeanUtil<MedicalAbnormalVO>().transform(result,MedicalAbnormalVO.class);
return new PageResultToBeanUtil<MedicalAbnormalVO>().transform(result, MedicalAbnormalVO.class);
}
@Override
public String publicNetworkToken(){
String token = redisClientUtil.get(new RedisKeyPrefix(AnYanConstants.AN_YAN_API_TOKEN_PREFIX) ,"publicToken",String.class);
if(StrUtil.isEmpty(token)){
public String publicNetworkToken() {
String token = redisClientUtil.get(new RedisKeyPrefix(AnYanConstants.AN_YAN_API_TOKEN_PREFIX), "publicToken", String.class);
if (StrUtil.isEmpty(token)) {
AuthResult authResult = publicNetworkTokenNoCache();
if(null != authResult){
if (null != authResult) {
token = authResult.getAccess_token();
int expireSeconds = ObjectUtil.isNotEmpty(authResult.getExpires_in())? authResult.getExpires_in() : 7200;
redisClientUtil.set(new RedisKeyPrefix(expireSeconds,AnYanConstants.AN_YAN_API_TOKEN_PREFIX),"publicToken", token);
int expireSeconds = ObjectUtil.isNotEmpty(authResult.getExpires_in()) ? authResult.getExpires_in() : 7200;
redisClientUtil.set(new RedisKeyPrefix(expireSeconds, AnYanConstants.AN_YAN_API_TOKEN_PREFIX), "publicToken", token);
}
}
return token;
}
@Override
public AuthResult publicNetworkTokenNoCache(){
public AuthResult publicNetworkTokenNoCache() {
JSONObject param = new JSONObject();
String password = anYanProperties.getPublicPassWrod();
String userName = anYanProperties.getPublicUserNmae();
try {
String sm4Password = SM4Utils.encryptSM4(password);
String encryptPassword = StringUtils.encryptByPublicKey(publicKey, password);
param.put("password",encryptPassword);
param.put("selfPassword",sm4Password);
param.put("loginName",userName);
param.put("password", encryptPassword);
param.put("selfPassword", sm4Password);
param.put("loginName", userName);
param.put("timeStamp", UUID.randomUUID().toString());
ResponseEntity<AnYanResult> responseEntity = RestTemplateUtil.postExchangeForGetToken(AnYanApiEnum.PUBLIC_NETWORK_AUTH_TOKEN, param,AnYanResult.class);
ResponseEntity<AnYanResult> responseEntity = RestTemplateUtil.postExchangeForGetToken(AnYanApiEnum.PUBLIC_NETWORK_AUTH_TOKEN, param, AnYanResult.class);
//安眼提供的接口包过深 ,先从AnYanResult对象中取出加密的密文,后在解密密文拿出 AuthResult对象 , 再从AuthResult对象中拿出 access_token
AnYanResult anYanResult = responseEntity.getBody();
if(ObjectUtil.isNotEmpty(anYanResult) && ObjectUtil.isNotEmpty(anYanResult.getData())){
if (ObjectUtil.isNotEmpty(anYanResult) && ObjectUtil.isNotEmpty(anYanResult.getData())) {
String decryptAuthResult = SM4Utils.decryptSM4((String) anYanResult.getData());
AuthResult authResult = JSON.parseObject(decryptAuthResult).toJavaObject(AuthResult.class);
if(null != authResult && null != authResult.getAccess_token()){
if (null != authResult && null != authResult.getAccess_token()) {
return authResult;
}else {
} else {
ExceptionAssertsUtil.fail("获取安眼系统token失败");
}
}
@@ -223,4 +270,17 @@ public class AnYanClientExecutor implements AnYanClient {
return null;
}
/**
* @description: 根据token获取用户信息
* @author PengJ
* @date 2025/10/24 17:00
*/
@Override
public AnYanUserInfoResult getAnYanUserInfo(String token) {
HttpHeaders headers = new HttpHeaders();
headers.add(AnYanConstants.AUTHORIZATION, AnYanConstants.TOKEN_TYPE + token);
ResponseEntity<AnYanUserInfoResult> exchange = RestTemplateUtil.getExchange(AnYanApiEnum.USER_INFO_UNIT_V2, headers, AnYanUserInfoResult.class);
return BeanUtil.toBean(exchange.getBody(), AnYanUserInfoResult.class);
}
}
@@ -2,6 +2,7 @@ package com.renkang.restaurant.config;
import com.renkang.anyan.client.AnYanClient;
import com.renkang.anyan.config.AnYanProperties;
import com.renkang.anyan.enums.AnYanApiEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.ExceptionAssertsUtil;
@@ -12,6 +13,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
@@ -20,6 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Description: AnYanClient xj安眼系统接口调用客户端
@@ -39,7 +42,11 @@ public class AnYanRestTemplateConfig {
return new RestTemplateBuilder()
.setConnectTimeout(Duration.of(properties.getTimeout(), ChronoUnit.MILLIS))
.setReadTimeout(Duration.of(properties.getReadTimeout(), ChronoUnit.MILLIS))
.additionalMessageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8), new MappingJackson2HttpMessageConverter())
.additionalMessageConverters(
new StringHttpMessageConverter(StandardCharsets.UTF_8),
new MappingJackson2HttpMessageConverter(),
new FormHttpMessageConverter()
)
.additionalInterceptors(authInterceptor)
.build();
}
@@ -47,17 +54,28 @@ public class AnYanRestTemplateConfig {
/**
* 自定义拦截器处理接口鉴权失败, 配合spring retry使用从而避免因token失效导致的接口调用失败
*/
public ClientHttpRequestInterceptor authInterceptor(){
public ClientHttpRequestInterceptor authInterceptor() {
// 添加重试次数限制
AtomicInteger retryCount = new AtomicInteger(0);
int maxRetries = 5;
return (httpRequest, bytes, clientHttpRequestExecution) -> {
ClientHttpResponse execute;
try {
// 获取请求URL
String url = httpRequest.getURI().toString();
// 排除特定接口不执行拦截逻辑
boolean shouldSkip = url.contains(AnYanApiEnum.QUERY_AUTH_TOKEN.getMethodPath());
execute = clientHttpRequestExecution.execute(httpRequest, bytes);
HttpStatus httpStatus =execute.getStatusCode();
if (Arrays.asList(HttpStatus.UNAUTHORIZED,HttpStatus.FORBIDDEN).contains(httpStatus)) {
if (shouldSkip) {
return execute;
}
HttpStatus httpStatus = execute.getStatusCode();
if (Arrays.asList(HttpStatus.UNAUTHORIZED, HttpStatus.FORBIDDEN).contains(httpStatus)
&& retryCount.getAndIncrement() < maxRetries) {
SpringContextUtils.getBean("anYanClientExecutor", AnYanClient.class).refreshToken();
}
} catch (Exception e) {
log.error("---------安眼平台API调用异常-------e{}",e.getMessage(),e);
log.error("---------安眼平台API调用异常-------e{}", e.getMessage(), e);
ExceptionAssertsUtil.fail("安眼平台API调用失败");
throw e;
}
@@ -9,6 +9,7 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.Objects;
@@ -40,50 +41,83 @@ public class RestTemplateUtil {
/**
* 请求接口访问 token
* @param api 接口
*
* @param api 接口
* @param requestBody 参数
* @return ResponseEntity
*/
public static <T> ResponseEntity<T> postExchange(AnYanApiEnum api, HttpHeaders headers ,Object requestBody,Class<T> responseType) {
String url = getProperties().getHost() + api.getMethodPath() + api.getMethodParam();
public static <T> ResponseEntity<T> postExchange(AnYanApiEnum api, HttpHeaders headers, Object requestBody, Class<T> responseType) {
String url = getProperties().getHost() + api.getMethodPath() + api.getMethodParam();
HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody);
return getRestTemplate().exchange(url, api.getHttpMethod(), requestEntity, responseType);
}
/**
* 公网请求接口访问 token(密码模式)
*
* @param api 接口
* @param formData 参数
* @return ResponseEntity
*/
public static <T> ResponseEntity<T> postExchangeForGetTokenByPassword(AnYanApiEnum api, MultiValueMap<String, String> formData, HttpHeaders headers, Class<T> responseType) {
String url = getProperties().getPublicHost() + api.getMethodPath();
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
log.info("开始发送请求到: {}", url);
ResponseEntity<T> response = getRestTemplate().exchange(url, api.getHttpMethod(), requestEntity, responseType);
log.info("收到响应: {}", response);
return response;
}
/**
* 公网请求接口访问 token
* @param api 接口
*
* @param api 接口
* @param requestBody 参数
* @return ResponseEntity
*/
public static <T> ResponseEntity<T> postExchangeForGetToken(AnYanApiEnum api,Object requestBody,Class<T> responseType) {
String url = getProperties().getPublicHost() + api.getMethodPath() + api.getMethodParam();
public static <T> ResponseEntity<T> postExchangeForGetToken(AnYanApiEnum api, Object requestBody, Class<T> responseType) {
String url = getProperties().getPublicHost() + api.getMethodPath() + api.getMethodParam();
HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody);
return getRestTemplate().exchange(url, api.getHttpMethod(), requestEntity, responseType);
}
/**
* 通用调用方法
* @param api 请求接口
* @param headers 请求
*
* @param api 请求接口
* @param headers 请求头
* @param requestBody body参数
* @return Result对象
* @return Result对象
*/
public static AnYanResult<Object> postExchange(AnYanApiEnum api, HttpHeaders headers, Object requestBody) {
String url = getProperties().getHost() + api.getMethodPath() +api.getMethodParam();
HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody,headers);
String url = getProperties().getHost() + api.getMethodPath() + api.getMethodParam();
HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, headers);
return responseHandler(getRestTemplate().exchange(url, api.getHttpMethod(), requestEntity, AnYanResult.class));
}
/**
* 通用调用方法
*
* @param api 请求接口
* @param headers 请求头
* @return Result对象
*/
public static <T> ResponseEntity<T> getExchange(AnYanApiEnum api, HttpHeaders headers, Class<T> responseType) {
String url = getProperties().getHost() + api.getMethodPath() + api.getMethodParam();
HttpEntity<Object> requestEntity = new HttpEntity<>(headers);
return getRestTemplate().exchange(url, api.getHttpMethod(), requestEntity, responseType);
}
/**
* ResponseEntity 转 Result
*
* @param entity
* @return
*/
private static <T extends AnYanResult<Object>> AnYanResult<Object> responseHandler(ResponseEntity<T> entity) {
if(HttpStatus.OK.equals(entity.getStatusCode()) && ObjectUtils.isNotEmpty(entity.getBody())){
if (HttpStatus.OK.equals(entity.getStatusCode()) && ObjectUtils.isNotEmpty(entity.getBody())) {
return entity.getBody();
}else{
} else {
return AnYanResult.error("天眼系统API调用失败");
}
}
@@ -2,6 +2,7 @@ package com.renkang.anyan.enums;
import lombok.Getter;
import org.springframework.http.HttpMethod;
/**
* @Description: AnYanApiEnum xj安眼系统接口枚举类
* @Author: feng
@@ -13,62 +14,68 @@ public enum AnYanApiEnum {
/**
* 1.获取token接口
*/
QUERY_AUTH_TOKEN("/oauth/oauth/token","", HttpMethod.POST),
QUERY_AUTH_TOKEN("/oauth/oauth/token", "", HttpMethod.POST),
/**
* 2.体检人数统计查询
*/
HEALTH_EXAMINATION_STATISTICS("/aygc-znhpt-sys/0/aystatistics/peopleHealthExaminationStatistics","", HttpMethod.POST),
HEALTH_EXAMINATION_STATISTICS("/aygc-znhpt-sys/0/aystatistics/peopleHealthExaminationStatistics", "", HttpMethod.POST),
/**
*3.健康打卡数据统计查询(血压,减重,血糖)
* 3.健康打卡数据统计查询(血压,减重,血糖)
*/
HEALTH_CHECK_STATISTICS("/aygc-znhpt-sys/0/aystatistics/healthCheckStatistics","", HttpMethod.POST),
HEALTH_CHECK_STATISTICS("/aygc-znhpt-sys/0/aystatistics/healthCheckStatistics", "", HttpMethod.POST),
/**
*4.健康打卡异常数据详细查询(血压)
* 4.健康打卡异常数据详细查询(血压)
*/
BLOOD_PRESSURE_LIST("/aygc-znhpt-sys/0/aystatistics/bloodPressureList","", HttpMethod.POST),
BLOOD_PRESSURE_LIST("/aygc-znhpt-sys/0/aystatistics/bloodPressureList", "", HttpMethod.POST),
/**
*5.健康打卡异常数据详细查询(减重)
* 5.健康打卡异常数据详细查询(减重)
*/
WEIGHT_PRESSURE_LIST("/aygc-znhpt-sys/0/aystatistics/weightPressureList","", HttpMethod.POST),
WEIGHT_PRESSURE_LIST("/aygc-znhpt-sys/0/aystatistics/weightPressureList", "", HttpMethod.POST),
/**
*6.健康打卡异常数据详细查询(血糖)
* 6.健康打卡异常数据详细查询(血糖)
*/
BLOOD_SUGAR_CLOCKS_LIST("/aygc-znhpt-sys/0/aystatistics/bloodSugarClockSList","", HttpMethod.POST),
BLOOD_SUGAR_CLOCKS_LIST("/aygc-znhpt-sys/0/aystatistics/bloodSugarClockSList", "", HttpMethod.POST),
/**
*7.体检异常数据统计查询(暂定)
* 7.体检异常数据统计查询(暂定)
*/
MEDICAL_ABNORMAL_STATISTICS("/aygc-znhpt-sys/0/aystatistics/checkstatistics","", HttpMethod.POST),
MEDICAL_ABNORMAL_STATISTICS("/aygc-znhpt-sys/0/aystatistics/checkstatistics", "", HttpMethod.POST),
/**
*8.体检异常数据清单(暂定)
* 8.体检异常数据清单(暂定)
*/
MEDICAL_ABNORMAL_LIST("/aygc-znhpt-sys/0/aystatistics/checkList","", HttpMethod.POST),
MEDICAL_ABNORMAL_LIST("/aygc-znhpt-sys/0/aystatistics/checkList", "", HttpMethod.POST),
/**
*9.油田医院数据查询
* 9.油田医院数据查询
*/
HOSPITAL_LIST("/aygc-znhpt-sys/0/aystatistics/HospitalList","", HttpMethod.POST),
HOSPITAL_LIST("/aygc-znhpt-sys/0/aystatistics/HospitalList", "", HttpMethod.POST),
/**
*10.健康小屋基础数据查询
* 10.健康小屋基础数据查询
*/
HEALTH_PLACE_ROOM_LIST("/aygc-znhpt-sys/0/aystatistics/HealthPlaceHomList","", HttpMethod.POST),
HEALTH_PLACE_ROOM_LIST("/aygc-znhpt-sys/0/aystatistics/HealthPlaceHomList", "", HttpMethod.POST),
/**
*11.健康小屋详细数据查询
* 11.健康小屋详细数据查询
*/
HEALTH_PLACE_ROOM_INFO_LIST("/aygc-znhpt-sys/0/aystatistics/initEmpHealthRoomCheckinInfoPages","", HttpMethod.POST),
HEALTH_PLACE_ROOM_INFO_LIST("/aygc-znhpt-sys/0/aystatistics/initEmpHealthRoomCheckinInfoPages", "", HttpMethod.POST),
/**
* 12.从外网地址获取安眼token接口
*/
PUBLIC_NETWORK_AUTH_TOKEN("/aygc-service-sys/0/api/xj/outside/getToken","", HttpMethod.POST);
PUBLIC_NETWORK_AUTH_TOKEN("/aygc-service-sys/0/api/xj/outside/getToken", "", HttpMethod.POST),
/**
* 13.获取员工信息及单位-V2
*/
USER_INFO_UNIT_V2("/iosp-iam/v2/users/self", "?containsUnit=true", HttpMethod.GET),
;
/**
* 接口路径
@@ -0,0 +1,32 @@
package com.renkang.anyan.model.dto;
import lombok.Data;
/**
* @author PengJ
* @description: 密码鉴权入参
* @date 2025/10/24 11:04
*/
@Data
public class AuthByPasswordParam {
/**
* grant_type
*/
private String grant_type = "password";
/**
* username
*/
private String username;
/**
* password
*/
private String password;
/**
* client_id
*/
private String client_id;
/**
* client_secret
*/
private String client_secret;
}
@@ -0,0 +1,149 @@
package com.renkang.anyan.model.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Huawei
* @version 1.0
* @description: TODO
* @date 2025/10/24 16:59
*/
@NoArgsConstructor
@Data
public class AnYanUserInfoResult {
@JsonProperty("id")
private String id;
@JsonProperty("loginName")
private String loginName;
@JsonProperty("email")
private String email;
@JsonProperty("organizationId")
private Integer organizationId;
@JsonProperty("realName")
private String realName;
@JsonProperty("phone")
private String phone;
@JsonProperty("gender")
private Integer gender;
@JsonProperty("tenantName")
private String tenantName;
@JsonProperty("tenantNum")
private String tenantNum;
@JsonProperty("roleMergeFlag")
private Integer roleMergeFlag;
@JsonProperty("tenantId")
private Integer tenantId;
@JsonProperty("currentRoleId")
private String currentRoleId;
@JsonProperty("currentRoleCode")
private String currentRoleCode;
@JsonProperty("currentRoleName")
private String currentRoleName;
@JsonProperty("currentRoleLevel")
private String currentRoleLevel;
@JsonProperty("employeeUnitDTO")
private EmployeeUnitDTO employeeUnitDTO;
@NoArgsConstructor
@Data
public static class EmployeeUnitDTO {
/**
* 职工编号
*/
@JsonProperty("employeeNum")
private String employeeNum;
/**
* 姓名
*/
@JsonProperty("name")
private String name;
/**
* 邮箱
*/
@JsonProperty("email")
private String email;
/**
* 手机
*/
@JsonProperty("mobile")
private String mobile;
/**
* 性别
*/
@JsonProperty("gender")
private Integer gender;
@JsonProperty("status")
private Object status;
/**
* 启用状态
*/
@JsonProperty("enabledFlag")
private String enabledFlag;
@JsonProperty("unitName")
private String unitName;
/**
* 所属二级单位unitCode
*/
@JsonProperty("unitCode")
private String unitCode;
/**
* 科级单位名称
*/
@JsonProperty("sectionUnitName")
private String sectionUnitName;
/**
* 科级单位unitCode
*/
@JsonProperty("sectionUnitCode")
private String sectionUnitCode;
@JsonProperty("directDepartmentName")
private String directDepartmentName;
/**
* 直属部门unitCode
*/
@JsonProperty("directDepartmentCode")
private String directDepartmentCode;
/**
* 层级路径(unitCode拼接)
*/
@JsonProperty("levelPath")
private String levelPath;
/**
* 完整组织机构路径(unitName拼接)
*/
@JsonProperty("unitNamePath")
private String unitNamePath;
/**
* 固定电话
*/
@JsonProperty("attribute1")
private String attribute1;
/**
* 职务
*/
@JsonProperty("attribute2")
private String attribute2;
/**
* 生日或年龄
*/
@JsonProperty("attribute3")
private Object attribute3;
}
}
@@ -28,4 +28,12 @@ public class AuthResult {
* satoken
*/
private String satoken;
/**
* message
*/
private String message;
/**
* success
*/
private boolean success;
}
@@ -87,9 +87,11 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除
filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除
filterChainDefinitionMap.put("/sys/login", "anon"); //登录接口排除
filterChainDefinitionMap.put("/sys/loginAnYan", "anon"); //登录接口排除(三方授权)
filterChainDefinitionMap.put("/sys/loginDoctor", "anon"); //登录接口排除
filterChainDefinitionMap.put("/conDoctor/loginDoctor", "anon"); //登录接口排除
filterChainDefinitionMap.put("/sys/mLogin", "anon"); //登录接口排除
filterChainDefinitionMap.put("/sys/mLoginAnYan", "anon"); //登录接口排除(三方授权)
filterChainDefinitionMap.put("/sys/logout", "anon"); //登出接口排除
filterChainDefinitionMap.put("/sys/thirdLogin/**", "anon"); //第三方登录
filterChainDefinitionMap.put("/sys/exchangeToken", "anon"); // 食堂token置换
+4
View File
@@ -80,6 +80,10 @@
<groupId>com.renkang</groupId>
<artifactId>health-watch-api</artifactId>
</dependency>
<dependency>
<groupId>com.renkang</groupId>
<artifactId>xj-anyan-api</artifactId>
</dependency>
</dependencies>
@@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import com.xkcoding.http.util.StringUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -40,15 +39,16 @@ import org.jeecg.modules.system.bean.request.QueryWeightMaxParam;
import org.jeecg.modules.system.bean.request.QueryqueryGroupAParam;
import org.jeecg.modules.system.bean.request.UserFilter;
import org.jeecg.modules.system.entity.HealthUserEmployeeEx;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepartChangeApply;
import org.jeecg.modules.system.manager.DictCacheManager;
import org.jeecg.modules.system.manager.UserCacheManager;
import org.jeecg.modules.system.service.IHealthUserEmployeeExService;
import org.jeecg.modules.system.service.ISysUserDepartChangeApplyService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.*;
import org.jeecg.modules.system.vo.ItemVo;
import org.jeecg.modules.system.vo.NoSelfManagerUser;
import org.jeecg.modules.system.vo.SysDepartVo;
import org.jeecg.modules.system.vo.UserEmployeeImportVo;
import org.jeecg.redis.RedisStreamKeyEnum;
import org.jeecg.redis.RedisStreamUtil;
import org.jeecg.util.AsyncUtils;
@@ -101,7 +101,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
private ImportsUtilService importsUtilService;
@Autowired
private ICommonImportsService commonImportsService;
@Resource(name="commonImportsOptionLocal")
@Resource(name = "commonImportsOptionLocal")
private CommonImportsOption commonImportsOption;
/**
@@ -111,7 +111,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
* @param pageNo
* @param pageSize
* @param req
* @param idStatus 是否需要脱敏标识 idStatus=1说明身份证号需要脱敏处理
* @param idStatus 是否需要脱敏标识 idStatus=1说明身份证号需要脱敏处理
* @return
*/
//@AutoLog(value = "员工-分页列表查询")
@@ -124,7 +124,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
HttpServletRequest req) {
Page<UserEmployee> page = new Page<>(pageNo, pageSize);
IPage<UserEmployee> pageList = healthUserEmployeeExService.selectHealthUserEmployeeExList(page, userFilter,idStatus);
IPage<UserEmployee> pageList = healthUserEmployeeExService.selectHealthUserEmployeeExList(page, userFilter, idStatus);
return Result.OK(pageList);
}
@@ -154,18 +154,19 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
* 1.因feign调用无法接收IPage接口类修饰的数据此接口换成实现类Page
* 2.更明确的传参方式声明,所有参数统一使用RequestParam传参(feign调用须指明传参方式)
* 3.该接口不支持获取员工信息中的家庭成员数量
*
* @return 带分页的员工列表
*/
@Operation(summary = "feign服务间调用员工分页列表", description = "feign服务间调用员工分页列表", hidden = true)
@GetMapping(value = "/feign-list")
public Result<Page<UserEmployee>> feignQueryPageList(@RequestParam(name = "realname", required = false) String realname,
@RequestParam(name = "idCord", required = false) String idCord,
@RequestParam(name = "orgCode", required = false) String orgCode,
@RequestParam(name = "threeOrgCode", required = false) String threeOrgCode,
@RequestParam(name = "idCord", required = false) String idCord,
@RequestParam(name = "orgCode", required = false) String orgCode,
@RequestParam(name = "threeOrgCode", required = false) String threeOrgCode,
@RequestParam(name = "sex", required = false) Integer sex,
@RequestParam(name = "workNo", required = false) String workNo,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
return Result.OK(healthUserEmployeeExService.feignQueryPageList(realname, idCord, orgCode, threeOrgCode, pageNo, pageSize, sex, workNo));
}
@@ -174,19 +175,19 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
public Result<Page<UserEmployee>> getUserListByOrgCodeList(@RequestParam(name = "realname", required = false) String realname,
@RequestParam(name = "orgCode", required = false) String orgCode,
@RequestParam(name = "workNo", required = false) String workNo,
@RequestParam(name = "orgCodeList",required = false) List<String> orgCodeList,
@RequestParam(name = "userIdList",required = false) List<String> userIdList,
@RequestParam(name = "orgCodeList", required = false) List<String> orgCodeList,
@RequestParam(name = "userIdList", required = false) List<String> userIdList,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
return Result.OK(healthUserEmployeeExService.getUserListByOrgCodeList(realname,orgCode,workNo,orgCodeList, userIdList,pageNo, pageSize));
return Result.OK(healthUserEmployeeExService.getUserListByOrgCodeList(realname, orgCode, workNo, orgCodeList, userIdList, pageNo, pageSize));
}
@Operation(summary = "员工(手表)-分页列表查询", description = "员工(手表)-分页列表查询")
@GetMapping(value = "/listByWatch")
public Result<IPage<UserEmployee>> listByWatch(UserFilter userFilter,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
Page<UserEmployee> page = new Page<>(pageNo, pageSize);
IPage<UserEmployee> pageList = healthUserEmployeeExService.selectUserListByWatch(page, userFilter);
@@ -204,25 +205,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@RequiresPermissions("system:health_user_employee_ex:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody @Validated UserEmployee userEmployee) {
// 密码解密
String key = RSAEncryptUtils.decrypt1(userEmployee.getPassword(), CommonConstant.PRIVATE_KEY);
String s = CheckPasswordUtil.checkPasswordRule(key);
if (StrUtil.isNotBlank(s)) {
return Result.error(s);
}
userEmployee.setPassword(key);
boolean success = healthUserEmployeeExService.saveAndUser(userEmployee);
if (success) {
if (!GlobalUtils.isQh()) {
redisStreamUtil.add(RedisStreamKeyEnum.EMPLOYEE_ASYNC_ADD, userEmployee);
}
// 添加缓存
AsyncUtils.execute(asyncTaskExecutor, ClientSignThreadLocal.getClientSignThreadLocal(),
() -> userCacheManager.addUser(empConvertUser(userEmployee)));
return Result.ok("添加成功");
} else {
return Result.error("添加失败");
}
return healthUserEmployeeExService.addUserInfo(userEmployee);
}
/**
@@ -261,47 +244,14 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@RequiresPermissions("system:health_user_employee_ex:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody UserEmployee userEmployee) {
//通过userId获取用户修改前的部门信息
SysUser sysUser = sysUserService.getUserById(userEmployee.getId());
userEmployee.setPassword(null);
//获取登录人信息
LoginUser loginUser = GlobalUtils.getLoginUser();
boolean success = healthUserEmployeeExService.updateByIdAndUser(userEmployee);
if (success) {
//编辑成功之后新增部门迁移列表
//若原有的部门跟编辑不一样则新增迁移列表,反之不用
if (Objects.nonNull(sysUser) && Objects.nonNull(sysUser.getDepart())
&&!sysUser.getDepart().getOrgCode().equals(userEmployee.getOrgCode())){
SysUserDepartChangeApply departChangeApply = healthUserEmployeeExService.addUserDepartChange(sysUser, loginUser);
SysDepart sysDepart = sysCache.getDepartByOrgCode(userEmployee.getOrgCode());
departChangeApply.setToDepartId(sysDepart.getId());//迁入部门id
departChangeApply.setToDepartCode(userEmployee.getOrgCode());//迁入部门code
departChangeApply.setMemo("用户编辑数据");
sysUserDepartChangeApplyService.save(departChangeApply);
}
if (!GlobalUtils.isQh()) {
redisStreamUtil.add(RedisStreamKeyEnum.EMPLOYEE_ASYNC_EDIT, userEmployee);
}
// 编辑缓存
AsyncUtils.execute(asyncTaskExecutor, ClientSignThreadLocal.getClientSignThreadLocal(), () -> {
userCacheManager.updateUser(empConvertUser(userEmployee));
// 刷新用户缓存信息
userCacheManager.updateUserCache(userEmployee.getId());
});
String orgCode = userEmployee.getOrgCode();
if(StringUtil.isNotEmpty(orgCode)){
sendUpdateMsgToRedisStream(userEmployee.getId(),orgCode);
}
return Result.ok("编辑成功");
} else {
return Result.error("编辑失败");
}
return healthUserEmployeeExService.updateUserInfo(userEmployee, loginUser);
}
private void sendUpdateMsgToRedisStream(String userId,String orgCode) {
private void sendUpdateMsgToRedisStream(String userId, String orgCode) {
if(sysCache.getDepartByOrgCode(orgCode) == null){
if (sysCache.getDepartByOrgCode(orgCode) == null) {
return;
}
SysUserModel userModel = new SysUserModel();
@@ -400,18 +350,18 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
// public ModelAndView exportXls(HttpServletRequest request, HealthUserEmployeeEx healthUserEmployeeEx) {
// return super.exportXls(request, healthUserEmployeeEx, HealthUserEmployeeEx.class, "员工");
// }
public Result<?> exportXls(HttpServletRequest request,UserFilter userFilter){
public Result<?> exportXls(HttpServletRequest request, UserFilter userFilter) {
return healthUserEmployeeExService.exportXls(userFilter);
}
@GetMapping("/exportTemp")
public ModelAndView exportTemp(){
public ModelAndView exportTemp() {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<Map<String, Object>> mapList = Lists.newArrayList();
//主体sheet
Map<String, Object> map = Maps.newHashMap();
ExportParams exportParams = new ExportParams("员工信息导入模版", "员工信息导入模版");
exportParams.setSecondTitle("导出人:"+sysUser.getRealname()+" ["+ DateUtils.formatDateTime() +"]");
exportParams.setSecondTitle("导出人:" + sysUser.getRealname() + " [" + DateUtils.formatDateTime() + "]");
map.put(NormalExcelConstants.PARAMS, exportParams);
//表格对应实体
map.put(NormalExcelConstants.CLASS, UserEmployeeImportVo.class);
@@ -427,7 +377,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
map.put(NormalExcelConstants.CLASS, ItemVo.class);
List<DictModel> nations = dictCacheManager.queryDictItemsByCode("nation");
List<ItemVo> itemVos = Lists.newArrayList();
if(!CollectionUtils.isEmpty(nations)){
if (!CollectionUtils.isEmpty(nations)) {
for (int i = 0; i < nations.size(); i++) {
ItemVo itemVo = new ItemVo();
itemVo.setId(i + 1);
@@ -446,7 +396,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
map.put(NormalExcelConstants.CLASS, ItemVo.class);
List<DictModel> eJobs = dictCacheManager.queryDictItemsByCode("e_job");
itemVos = Lists.newArrayList();
if(!CollectionUtils.isEmpty(eJobs)) {
if (!CollectionUtils.isEmpty(eJobs)) {
for (int i = 0; i < eJobs.size(); i++) {
ItemVo itemVo = new ItemVo();
itemVo.setId(i + 1);
@@ -465,7 +415,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
map.put(NormalExcelConstants.CLASS, ItemVo.class);
List<DictModel> mrStates = dictCacheManager.queryDictItemsByCode("mr_state");
itemVos = Lists.newArrayList();
if(!CollectionUtils.isEmpty(mrStates)) {
if (!CollectionUtils.isEmpty(mrStates)) {
for (int i = 0; i < mrStates.size(); i++) {
ItemVo itemVo = new ItemVo();
itemVo.setId(i + 1);
@@ -484,7 +434,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
map.put(NormalExcelConstants.CLASS, ItemVo.class);
List<DictModel> empEducations = dictCacheManager.queryDictItemsByCode("emp_education");
itemVos = Lists.newArrayList();
if(!CollectionUtils.isEmpty(empEducations)) {
if (!CollectionUtils.isEmpty(empEducations)) {
for (int i = 0; i < empEducations.size(); i++) {
ItemVo itemVo = new ItemVo();
itemVo.setId(i + 1);
@@ -499,8 +449,9 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
//此处设置的filename无效 ,前端会重更新设置一下
mv.addObject(NormalExcelConstants.FILE_NAME, "员工信息导入模版");
mv.addObject(NormalExcelConstants.MAP_LIST, mapList);
return mv;
return mv;
}
/**
* 通过excel导入数据
*
@@ -528,7 +479,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
try {
String taskCode = SystemConstant.TASK_IMPORT_USER_EMP_INFO;
String importTitle = "员工信息导入";
return importsUtilService.importExcelReflectDetail(file,params, UserEmployeeImportVo.class,taskCode,importTitle, commonImportsOption);
return importsUtilService.importExcelReflectDetail(file, params, UserEmployeeImportVo.class, taskCode, importTitle, commonImportsOption);
} catch (Exception e) {
log.error("员工信息导入失败!" + e.getMessage(), e);
return Result.error("员工信息数据导入失败!");
@@ -540,11 +491,11 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@RequiresPermissions("system:health_user_employee_ex:importExcel")
@RequestMapping(value = "/checkUser", method = RequestMethod.POST)
public Result<?> checkUserData(@RequestParam String infoId) {
CommonImports imports = commonImportsService.getById(infoId);
if(imports == null){
CommonImports imports = commonImportsService.getById(infoId);
if (imports == null) {
return Result.error("未导入数据,请先检查");
}
if(!ImportConstant.SAVE.equals(imports.getImportStatus())){
if (!ImportConstant.SAVE.equals(imports.getImportStatus())) {
return Result.error("未导入成功,不能启动数据校验");
}
healthUserEmployeeExService.checkUserItem(infoId);
@@ -554,28 +505,30 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@RequiresPermissions("system:health_user_employee_ex:importExcel")
@RequestMapping(value = "/updateUser", method = RequestMethod.POST)
public Result<?> updateUserData(@RequestParam String infoId) {
CommonImports imports = commonImportsService.getById(infoId);
if(imports == null){
CommonImports imports = commonImportsService.getById(infoId);
if (imports == null) {
return Result.error("未导入数据,请先检查");
}
if(!ImportConstant.CHECK_SUCCEED.equals(imports.getImportStatus())){
if (!ImportConstant.CHECK_SUCCEED.equals(imports.getImportStatus())) {
return Result.error("未校验成功,不能更新及导入数据");
}
healthUserEmployeeExService.updateUserItem(infoId);
return Result.OK("开始更新数据并导入数据");
}
/**
* 员工更新单位模版下载
*
* @return
*/
@GetMapping("/departTemp")
public ModelAndView departTemp(){
public ModelAndView departTemp() {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<Map<String, Object>> mapList = Lists.newArrayList();
//主体sheet
Map<String, Object> map = Maps.newHashMap();
ExportParams exportParams = new ExportParams("员工部门更新导入模版", "员工部门更新导入模版");
exportParams.setSecondTitle("导出人:"+sysUser.getRealname()+" ["+ DateUtils.formatDateTime() +"]");
exportParams.setSecondTitle("导出人:" + sysUser.getRealname() + " [" + DateUtils.formatDateTime() + "]");
map.put(NormalExcelConstants.PARAMS, exportParams);
//表格对应实体
map.put(NormalExcelConstants.CLASS, SysDepartVo.class);
@@ -586,7 +539,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
//此处设置的filename无效 ,前端会重更新设置一下
mv.addObject(NormalExcelConstants.FILE_NAME, "员工部门更新导入模版");
mv.addObject(NormalExcelConstants.MAP_LIST, mapList);
return mv;
return mv;
}
@RequiresPermissions("system:health_user_employee_ex:importDepartExcel")
@@ -609,7 +562,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
try {
String taskCode = SystemConstant.TASK_IMPORT_USER_DEPART_INFO;
String importTitle = "员工部门更新信息导入";
return importsUtilService.importExcelReflectDetail(file,params, SysDepartVo.class,taskCode,importTitle, commonImportsOption);
return importsUtilService.importExcelReflectDetail(file, params, SysDepartVo.class, taskCode, importTitle, commonImportsOption);
} catch (Exception e) {
log.error("员工部门更新信息数据导入失败!" + e.getMessage(), e);
return Result.error("员工部门更新信息数据导入失败!");
@@ -621,11 +574,11 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@RequiresPermissions("system:health_user_employee_ex:importDepartExcel")
@RequestMapping(value = "/checkDepart", method = RequestMethod.POST)
public Result<?> checkDepartData(@RequestParam String infoId) {
CommonImports imports = commonImportsService.getById(infoId);
if(imports == null){
CommonImports imports = commonImportsService.getById(infoId);
if (imports == null) {
return Result.error("未导入数据,请先检查");
}
if(!ImportConstant.SAVE.equals(imports.getImportStatus())){
if (!ImportConstant.SAVE.equals(imports.getImportStatus())) {
return Result.error("未导入成功,不能启动数据校验");
}
healthUserEmployeeExService.checkUserDepart(infoId);
@@ -635,21 +588,22 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@RequiresPermissions("system:health_user_employee_ex:importDepartExcel")
@RequestMapping(value = "/updateDepart", method = RequestMethod.POST)
public Result<?> updateDepartData(@RequestParam String infoId) {
CommonImports imports = commonImportsService.getById(infoId);
if(imports == null){
CommonImports imports = commonImportsService.getById(infoId);
if (imports == null) {
return Result.error("未导入数据,请先检查");
}
if(!ImportConstant.CHECK_SUCCEED.equals(imports.getImportStatus())){
if (!ImportConstant.CHECK_SUCCEED.equals(imports.getImportStatus())) {
return Result.error("未校验成功,不能更新及导入数据");
}
healthUserEmployeeExService.updateUserDepart(infoId);
return Result.OK("开始更新数据并导入数据");
}
private void delCacheBatch(List<SysUser> users) {
if (CollectionUtil.isEmpty(users)) {
return;
}
users.forEach(user -> userCacheManager.delUser(user.getId(),user.getOrgCode()));
users.forEach(user -> userCacheManager.delUser(user.getId(), user.getOrgCode()));
}
private LoginUser empConvertUser(UserEmployee employee) {
@@ -672,27 +626,6 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@Operation(summary = "员工-分页列表查询(医疗点业务使用)", description = "员工-分页列表查询(医疗点业务使用)")
@GetMapping(value = "/listUserBack")
public Result<IPage<UserEmployee>> listUserBack(UserFilter userFilter,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
Page<UserEmployee> page = new Page<>(pageNo, pageSize);
IPage<UserEmployee> pageList = healthUserEmployeeExService.selectHealthUserEmployeeExListBack(page, userFilter);
return Result.OK(pageList);
}
/**
* 员工-分页列表查询 筛选用
* @param userFilter
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@Operation(summary = "员工-分页列表查询筛选用(医疗点业务使用)", description = "员工-分页列表查询筛选用(医疗点业务使用)")
@GetMapping(value = "/listUserBackByOrg")
public Result<IPage<UserEmployee>> listUserBackByOrg(UserFilter userFilter,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
@@ -702,12 +635,35 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
return Result.OK(pageList);
}
/**
* 员工-分页列表查询 筛选用
*
* @param userFilter
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@Operation(summary = "员工-分页列表查询筛选用(医疗点业务使用)", description = "员工-分页列表查询筛选用(医疗点业务使用)")
@GetMapping(value = "/listUserBackByOrg")
public Result<IPage<UserEmployee>> listUserBackByOrg(UserFilter userFilter,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
Page<UserEmployee> page = new Page<>(pageNo, pageSize);
IPage<UserEmployee> pageList = healthUserEmployeeExService.selectHealthUserEmployeeExListBack(page, userFilter);
return Result.OK(pageList);
}
/**
* 医疗点业务员工分页列表(目前用于服务间调用)
* ps: 获取未分配医疗点的员工列表 , 调用方需处理数据权限的问题
*
* @return 带分页的员工列表
*/
@Operation(summary = "医疗点业务员工分页列表(目前用于服务间调用)", description = "医疗点业务员工分页列表(目前用于服务间调用)",hidden = true)
@Operation(summary = "医疗点业务员工分页列表(目前用于服务间调用)", description = "医疗点业务员工分页列表(目前用于服务间调用)", hidden = true)
@PostMapping(value = "/listUserBack/feign")
public Result<Page<UserEmployee>> listUserBackByFeign(@RequestBody UserFilter userFilter) {
return Result.OK(healthUserEmployeeExService.listUserBackByFeign(userFilter));
@@ -715,10 +671,11 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
/**
* 通过ID获取员工常用的基本信息(适合业务服务种员工信息补全) 目前适用于业务服务种feign调用
*
* @param ids
* @return
*/
@Operation(summary = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)", description = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)",hidden = true)
@Operation(summary = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)", description = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)", hidden = true)
@PostMapping(value = "/queryBaseEmployeeInfo")
public List<BaseEmployeeInfo> queryBaseEmployeeInfo(@RequestBody Set<String> ids) {
return healthUserEmployeeExService.queryBaseEmployeeInfo(ids);
@@ -726,10 +683,11 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
/**
* 通过民族、政治面貌、岗位层级、婚姻状况、健康现状查询员工基本信息 (适合业务服务种员工信息补全) 目前适用于业务服务种feign调用
*
* @param healthUserEmployeeEx
* @return
*/
@Operation(summary = "通过民族、政治面貌、岗位层级、婚姻状况、健康现状查询员工基本信息(适合业务服务种员工信息补全)", description = "通过民族、政治面貌、岗位层级、婚姻状况、健康现状查询员工基本信息(适合业务服务种员工信息补全)",hidden = true)
@Operation(summary = "通过民族、政治面貌、岗位层级、婚姻状况、健康现状查询员工基本信息(适合业务服务种员工信息补全)", description = "通过民族、政治面貌、岗位层级、婚姻状况、健康现状查询员工基本信息(适合业务服务种员工信息补全)", hidden = true)
@PostMapping(value = "/queryBaseEmployeeInfoByCondition")
public List<BaseEmployeeInfo> queryBaseEmployeeInfoByCondition(@RequestBody HealthUserEmployeeEx healthUserEmployeeEx) {
return healthUserEmployeeExService.queryBaseEmployeeInfoByCondition(healthUserEmployeeEx);
@@ -738,10 +696,11 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
/**
* 通过ID获取员工常用的基本信息(适合业务服务种员工信息补全) 目前适用于业务服务种feign调用
*
* @param ids
* @return
*/
@Operation(summary = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)", description = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)",hidden = true)
@Operation(summary = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)", description = "通过ID获取员工常用的基本信息(适合业务服务种员工信息补全)", hidden = true)
@PostMapping(value = "/queryBaseEmployeeInfoSimple")
public List<BaseEmployeeInfo> queryBaseEmployeeInfoSimple(@RequestBody Set<String> ids) {
return healthUserEmployeeExService.queryBaseEmployeeInfoSimple(ids);
@@ -755,6 +714,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
/**
* 移动端用户获取身高体重
*
* @param userFlag 不传从token中取ID, 传了就用用户标识,可传身份证和ID(适用于食堂接口的用户身高体重数据补全)
* @return
*/
@@ -764,7 +724,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
return Result.OK(healthUserEmployeeExService.appUserFindUserHeightWeight(userFlag));
}
@Operation(summary = "批量更新用户的身高体重等体征信息(档案服务种定时任务调用)", description = "批量更新用户的身高体重等体征信息(档案服务种定时任务调用)",hidden = true)
@Operation(summary = "批量更新用户的身高体重等体征信息(档案服务种定时任务调用)", description = "批量更新用户的身高体重等体征信息(档案服务种定时任务调用)", hidden = true)
@PutMapping(value = "/put/heightWeight")
public Result<Void> updateUserHeightWeight(@RequestBody List<EmployeeHeightWeight> employeeHeightWeights) {
healthUserEmployeeExService.updateUserHeightWeight(employeeHeightWeights);
@@ -780,28 +740,28 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
@Operation(summary = "查询用户特定数据来源的最新体格数据", description = "查询用户特定数据来源的最新体格数据")
@GetMapping(value = "/byDataSource")
public Result<String> queryTargetByDataSource(@RequestParam(name = "target")
@Parameter(name = "target",description = "数据类型:weight,fat,height,waist,bmi") String target,
@Parameter(name = "target", description = "数据类型:weight,fat,height,waist,bmi") String target,
@RequestParam(name = "dataSource", required = false)
@Parameter(name = "dataSource",description = "数据来源(参考字典:data_source_dict)") String dataSource) {
return Result.OK(healthUserEmployeeExService.queryTargetByDataSource(target,dataSource));
@Parameter(name = "dataSource", description = "数据来源(参考字典:data_source_dict)") String dataSource) {
return Result.OK(healthUserEmployeeExService.queryTargetByDataSource(target, dataSource));
}
@Operation(summary = "批量获取用户bmi", description = "批量获取用户bmi")
@PostMapping(value = "/getBmiByUserList")
public Result<Map<String,Double>> getBmiByUserList(@RequestBody List<String> userIdList) {
public Result<Map<String, Double>> getBmiByUserList(@RequestBody List<String> userIdList) {
return Result.OK(healthUserEmployeeExService.getBmiByUserList(userIdList));
}
@Operation(summary = "根据干预膳食体重管理的条件查询用户List", description = "根据干预膳食体重管理的条件查询用户List")
@PostMapping(value = "/getUsersByMealsWeight")
public Result<Page<BaseUser>> getUsersByMealsWeight(@RequestBody HealthMealsWeightQueryVO queryVO) {
return Result.OK(healthUserEmployeeExService.getUsersByMealsWeight(queryVO.getPageNo(),queryVO.getPageSize(),queryVO));
return Result.OK(healthUserEmployeeExService.getUsersByMealsWeight(queryVO.getPageNo(), queryVO.getPageSize(), queryVO));
}
@Operation(summary = "根据干预膳食体重管理的条件查询统计数据", description = "根据干预膳食体重管理的条件查询统计数据")
@PostMapping(value = "/getStatisticsByMealsWeight")
public Result<WeightStatisticsVO> getStatisticsByMealsWeight(@RequestBody HealthMealsWeightQueryVO queryVO) {
return Result.OK(healthUserEmployeeExService.getStatisticsByMealsWeight(queryVO.getPageNo(),queryVO.getPageSize(),queryVO));
return Result.OK(healthUserEmployeeExService.getStatisticsByMealsWeight(queryVO.getPageNo(), queryVO.getPageSize(), queryVO));
}
@Operation(summary = "查询指定范围内最胖的员工", description = "查询指定范围内最胖的员工")
@@ -827,7 +787,7 @@ public class HealthUserEmployeeExController extends JeecgController<HealthUserEm
public Result<IPage<NoSelfManagerUser>> noSelfManagerUsers(NoSelfManagerUser filter,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
return Result.OK(healthUserEmployeeExService.noSelfManagerUsers(filter,pageNo,pageSize));
return Result.OK(healthUserEmployeeExService.noSelfManagerUsers(filter, pageNo, pageSize));
}
/**
@@ -1,6 +1,5 @@
package org.jeecg.modules.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
@@ -13,7 +12,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.base.UserBase;
@@ -28,9 +26,10 @@ import org.jeecg.common.util.encryption.EncryptedString;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.global.GlobalUtils;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.manager.ISysCache;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysRoleIndex;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserPost;
import org.jeecg.modules.system.model.SysLoginModel;
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
@@ -49,7 +48,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author scott
@@ -74,26 +72,24 @@ public class LoginController {
@Autowired
private ISysDepartService sysDepartService;
@Autowired
private ISysTenantService sysTenantService;
@Autowired
private ISysDictService sysDictService;
@Resource
private BaseCommonService baseCommonService;
@Autowired
private JeecgBaseConfig jeecgBaseConfig;
@Autowired
private SysUserRoleMapper sysUserRoleMapper;
@Autowired
private CacheManager cacheManager;
@Autowired
private ISysCache sysCache;
@Autowired
private ISysUserDeviceService sysUserDeviceService;
@Autowired
private ISysUserPostService sysUserPostService;
@Autowired
private TaskExecutor taskExecutor;
@Autowired
private ILoginAnYanService iLoginService;
@Autowired
private LoginService loginService;
@Operation(summary = "登录接口")
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel) {
@@ -144,7 +140,7 @@ public class LoginController {
boolean qh = GlobalUtils.isQh();
SysUser sysUser = sysUserService.getUserByNameOrWorkNoOrMobile(username, password, null);
if (sysUser == null) {
addLoginFailOvertimes(username);
loginService.addLoginFailOvertimes(username);
result.error500("账号或密码错误");
return result;
}
@@ -161,7 +157,7 @@ public class LoginController {
}
// 用户角色信息
handleUserRoles(sysUser);
loginService.handleUserRoles(sysUser);
// 用户岗位信息
if (!qh) {
SysUserPost sysUserPost = sysUserPostService.getById(sysUser.getId());
@@ -170,7 +166,7 @@ public class LoginController {
}
}
// 用户管理部门
handleUserDepartCodes(sysUser);
loginService.handleUserDepartCodes(sysUser);
//用户登录信息
userInfo(sysUser, result);
//update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码
@@ -188,6 +184,27 @@ public class LoginController {
return result;
}
/**
* @description: 安眼统一认证(pc端)
* @author PengJ
* @date 2025/10/24 13:39
*/
@Operation(summary = "安眼统一认证(pc端)")
@RequestMapping(value = "/loginAnYan", method = RequestMethod.POST)
public Result<JSONObject> loginAnYan(@RequestBody SysLoginModel sysLoginModel) {
return iLoginService.loginAnYan(sysLoginModel);
}
/**
* @description: 安眼统一认证(移动端)
* @author PengJ
* @date 2025/10/24 13:39
*/
@Operation(summary = "安眼统一认证(移动端)")
@RequestMapping(value = "/mLoginAnYan", method = RequestMethod.POST)
public Result<JSONObject> mLoginAnYan(@RequestBody SysLoginModel sysLoginModel) {
return iLoginService.mLoginAnYan(sysLoginModel);
}
/**
* 医护人员登录接口
@@ -198,7 +215,7 @@ public class LoginController {
@PostMapping(value = "medicalStaffLogin")
public Result<JSONObject> medicalStaffLogin(@RequestBody SysLoginModel sysLoginModel) {
// 验证码校验
boolean checkCode = checkVerificationCode(sysLoginModel.getCaptcha(), sysLoginModel.getCheckKey());
boolean checkCode = loginService.checkVerificationCode(sysLoginModel.getCaptcha(), sysLoginModel.getCheckKey());
if (!checkCode) {
// 改成特殊的code 便于前端判断
return Result.error(HttpStatus.PRECONDITION_FAILED.value(), "验证码错误");
@@ -230,16 +247,16 @@ public class LoginController {
}
// 角色信息
handleUserRoles(sysUser);
loginService.handleUserRoles(sysUser);
// 管理部门
handleUserDepartCodes(sysUser);
loginService.handleUserDepartCodes(sysUser);
// 生成token
String token = JwtUtil.sign(sysUser);
// 缓存redis以及设置token过去时间
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
cacheLoginUserInfo(username, sysUser, "登录成功[医护人员]");
loginService.cacheLoginUserInfo(username, sysUser, "登录成功[医护人员]");
JSONObject obj = new JSONObject();
obj.put("token", token);
@@ -247,53 +264,6 @@ public class LoginController {
return Result.OK("登录成功", obj);
}
private boolean checkVerificationCode(String captcha, String checkKey) {
// 验证码校验
if (StrUtil.isBlank(captcha) || StrUtil.isBlank(checkKey)) {
return false;
}
String lowerCaseCaptcha = captcha.toLowerCase();
String origin = lowerCaseCaptcha + checkKey + jeecgBaseConfig.getSignatureSecret();
String realKey = Md5Util.md5Encode(origin, "utf-8");
Object checkCode = redisUtil.get(realKey);
if (checkCode == null || !checkCode.toString().equals(lowerCaseCaptcha)) {
log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", checkKey, lowerCaseCaptcha, checkCode);
return false;
}
return true;
}
private void cacheLoginUserInfo(String username, SysUser sysUser, String loginSuccessTips) {
if (StrUtil.isBlank(username) || sysUser == null) {
return;
}
redisUtil.del(CommonConstant.LOGIN_FAIL + username);
LoginUser loginUser = new LoginUser();
sysUser.setClient(GlobalUtils.loginClient());
BeanUtils.copyProperties(sysUser, loginUser);
baseCommonService.addLog("用户名: " + username + "," + loginSuccessTips, CommonConstant.LOG_TYPE_1, null, loginUser);
Cache cache = cacheManager.getCache(CacheConstant.SYS_USERS_CACHE);
if (Objects.nonNull(cache)) {
cache.put(sysUser.getId(), loginUser);
}
}
private void handleUserRoles(SysUser user) {
if (ObjectUtil.isNull(user)) {
return;
}
List<SysRole> list = sysUserRoleMapper.getUserRolesByUserId(user.getId());
if (CollectionUtils.isEmpty(list)) {
return;
}
String roleCodes = list.stream().map(SysRole::getRoleCode)
.filter(StrUtil::isNotBlank)
.collect(Collectors.joining(","));
user.setRoleCodes(roleCodes);
}
/**
* 【vue3专用】获取用户信息
*/
@@ -321,7 +291,7 @@ public class LoginController {
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
//update-end---author:scott ---date::2022-06-20 forvue3前端,支持自定义首页--------------
// 用户角色
handleUserRoles(sysUser);
loginService.handleUserRoles(sysUser);
sysUser.setClient(GlobalUtils.loginClient());
obj.put("userInfo", sysUser);
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
@@ -578,7 +548,7 @@ public class LoginController {
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
if (!smscode.equals(code)) {
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
addLoginFailOvertimes(phone);
loginService.addLoginFailOvertimes(phone);
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
result.setMessage("手机验证码错误");
return result;
@@ -742,7 +712,7 @@ public class LoginController {
// personType=1 员工
SysUser sysUser = sysUserService.getUserByNameOrWorkNoOrMobile(username, password, null);
if (sysUser == null) {
addLoginFailOvertimes(username);
loginService.addLoginFailOvertimes(username);
result.error500("账号或密码错误");
return result;
}
@@ -800,9 +770,9 @@ public class LoginController {
//5. 设置登录用户信息
obj.put("userInfo", sysUser);
// 用户角色
handleUserRoles(sysUser);
loginService.handleUserRoles(sysUser);
// 用户管理部门
handleUserDepartCodes(sysUser);
loginService.handleUserDepartCodes(sysUser);
//6. 生成token
String token = JwtUtil.sign(sysUser);
// 设置超时时间
@@ -824,52 +794,12 @@ public class LoginController {
//录入登录用户的设备型号
if (StringUtils.isNotBlank(sysLoginModel.getDeviceType()) && StringUtils.isNotBlank(sysLoginModel.getDeviceSystem())) {
taskExecutor.execute(() ->
insertUserDeviceType(sysUser.getId(), sysLoginModel.getDeviceType(), sysLoginModel.getDeviceSystem()));
loginService.insertUserDeviceType(sysUser.getId(), sysLoginModel.getDeviceType(), sysLoginModel.getDeviceSystem()));
}
return result;
}
public void insertUserDeviceType(String userId, String deviceType, String deviceSystem) {
LambdaQueryWrapper<SysUserDevice> wrapper = Wrappers.lambdaQuery(SysUserDevice.class)
.eq(SysUserDevice::getUserId, userId)
.eq(SysUserDevice::getDeviceType, deviceType)
.eq(SysUserDevice::getDeviceSystem, deviceSystem);
Optional<SysUserDevice> findOptional = sysUserDeviceService.getOneOpt(wrapper);
Date now = new Date();
if (findOptional.isPresent()) {
SysUserDevice sysUserDevice = findOptional.get();
sysUserDevice.setLastLoginTime(now);
sysUserDeviceService.updateById(sysUserDevice);
} else {
SysUserDevice sysUserDevice = new SysUserDevice();
sysUserDevice.setUserId(userId);
sysUserDevice.setDeviceSystem(deviceSystem);
sysUserDevice.setDeviceType(deviceType);
sysUserDevice.setCreateTime(now);
sysUserDevice.setLastLoginTime(now);
sysUserDeviceService.save(sysUserDevice);
}
}
private void handleUserDepartCodes(SysUser sysUser) {
if (sysUser == null || StrUtil.isBlank(sysUser.getDepartIds())) {
return;
}
String[] split = sysUser.getDepartIds().split(",");
List<String> codes = new ArrayList<>();
for (String departId : split) {
SysDepart departById = sysCache.getDepartById(departId);
if (departById != null) {
codes.add(departById.getOrgCode());
}
}
if (CollectionUtil.isNotEmpty(codes)) {
sysUser.setDepartCodes(String.join(",", codes));
}
}
/**
* 第三方登录获取token
*
@@ -893,7 +823,7 @@ public class LoginController {
// username 泛指账号 包含(username/工号/电话)
SysUser sysUser = sysUserService.getUserByNameOrWorkNoOrMobile(username, password, null);
if (sysUser == null) {
addLoginFailOvertimes(username);
loginService.addLoginFailOvertimes(username);
result.error500("账号或密码错误");
return result;
}
@@ -903,7 +833,7 @@ public class LoginController {
}
// 用户角色
handleUserRoles(sysUser);
loginService.handleUserRoles(sysUser);
//6. 生成token
String token = JwtUtil.sign(sysUser);
// 设置超时时间
@@ -996,41 +926,6 @@ public class LoginController {
return Result.OK(result);
}
/**
* 登录失败超出次数5 返回true
*
* @param username
* @return
*/
private boolean isLoginFailOvertimes(String username) {
String key = CommonConstant.LOGIN_FAIL + username;
Object failTime = redisUtil.get(key);
if (failTime != null) {
Integer val = Integer.parseInt(failTime.toString());
if (val > 5) {
return true;
}
}
return false;
}
/**
* 记录登录失败次数
*
* @param username
*/
private void addLoginFailOvertimes(String username) {
String key = CommonConstant.LOGIN_FAIL + username;
Object failTime = redisUtil.get(key);
Integer val = 0;
if (failTime != null) {
val = Integer.parseInt(failTime.toString());
}
// 1小时
redisUtil.set(key, ++val, 3600);
}
@Operation(summary = "登录接口专家端专用")
@RequestMapping(value = "/loginDoctor", method = RequestMethod.POST)
public Result<JSONObject> loginDoctor(@RequestBody SysLoginModel sysLoginModel) {
@@ -1060,7 +955,7 @@ public class LoginController {
break;
}
if (Objects.isNull(sysUser)) {
addLoginFailOvertimes(username);
loginService.addLoginFailOvertimes(username);
result.error500("用户名或密码错误");
return result;
}
@@ -1128,9 +1023,9 @@ public class LoginController {
LoginUser cacheUser = cache.get(sysUser.getId(), LoginUser.class);
if (cacheUser == null) {
// 用户角色
handleUserRoles(sysUser);
loginService.handleUserRoles(sysUser);
// 用户管理部门
handleUserDepartCodes(sysUser);
loginService.handleUserDepartCodes(sysUser);
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(sysUser, loginUser);
cache.put(sysUser.getId(), loginUser);
@@ -59,9 +59,11 @@ public interface IHealthUserEmployeeExService extends IService<HealthUserEmploye
UserEmployee selectArchivesById(String id);
Result<String> addUserInfo(UserEmployee userEmployee);
boolean saveAndUser(UserEmployee userEmployee);
boolean updateByIdAndUser(UserEmployee userEmployee);
Result<String> updateUserInfo(UserEmployee userEmployee, LoginUser loginUser);
boolean saveAndUserDepartManager(UserEmployee userEmployee);
@@ -0,0 +1,29 @@
package org.jeecg.modules.system.service;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.system.model.SysLoginModel;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author PengJ
* @description: 登录Service
* @date 2025/10/24 18:10
*/
public interface ILoginAnYanService {
/**
* @description: 安眼统一认证(pc端)
* @author PengJ
* @date 2025/10/24 18:11
*/
Result<JSONObject> loginAnYan(@RequestBody SysLoginModel sysLoginModel);
/**
* @description: 安眼统一认证(移动端)
* @author PengJ
* @date 2025/10/24 18:11
*/
Result<JSONObject> mLoginAnYan(@RequestBody SysLoginModel sysLoginModel);
}
@@ -0,0 +1,210 @@
package org.jeecg.modules.system.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.Md5Util;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.global.GlobalUtils;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.manager.ISysCache;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.SysUserRoleMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Huawei
* @version 1.0
* @description: TODO
* @date 2025/10/29 16:01
*/
@Slf4j
@Service
public class LoginService {
@Autowired
private RedisUtil redisUtil;
@Autowired
private ISysUserPostService sysUserPostService;
@Autowired
private ISysCache sysCache;
@Autowired
private SysUserRoleMapper sysUserRoleMapper;
@Autowired
private ISysUserDeviceService sysUserDeviceService;
@Autowired
private JeecgBaseConfig jeecgBaseConfig;
@Resource
private BaseCommonService baseCommonService;
@Autowired
private CacheManager cacheManager;
/**
* 记录登录失败次数
*
* @param username
*/
public void addLoginFailOvertimes(String username) {
String key = CommonConstant.LOGIN_FAIL + username;
Object failTime = redisUtil.get(key);
Integer val = 0;
if (failTime != null) {
val = Integer.parseInt(failTime.toString());
}
// 1小时
redisUtil.set(key, ++val, 3600);
}
/**
* 登录失败超出次数5 返回true
*
* @param username
* @return
*/
public boolean isLoginFailOvertimes(String username) {
String key = CommonConstant.LOGIN_FAIL + username;
Object failTime = redisUtil.get(key);
if (failTime != null) {
Integer val = Integer.parseInt(failTime.toString());
if (val > 5) {
return true;
}
}
return false;
}
/**
* 处理用户相关信息(角色、岗位、管理部门)
*/
public void processUserInfo(SysUser sysUser) {
// 用户角色信息
handleUserRoles(sysUser);
// 用户岗位信息
if (!GlobalUtils.isQh()) {
SysUserPost sysUserPost = sysUserPostService.getById(sysUser.getId());
if (ObjectUtil.isNotNull(sysUserPost)) {
sysUser.setPostId(sysUserPost.getPostId());
}
}
// 用户管理部门
handleUserDepartCodes(sysUser);
}
/**
* 校验验证码
*/
public boolean checkVerificationCode(String captcha, String checkKey) {
// 验证码校验
if (StrUtil.isBlank(captcha) || StrUtil.isBlank(checkKey)) {
return false;
}
String lowerCaseCaptcha = captcha.toLowerCase();
String origin = lowerCaseCaptcha + checkKey + jeecgBaseConfig.getSignatureSecret();
String realKey = Md5Util.md5Encode(origin, "utf-8");
Object checkCode = redisUtil.get(realKey);
if (checkCode == null || !checkCode.toString().equals(lowerCaseCaptcha)) {
log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", checkKey, lowerCaseCaptcha, checkCode);
return false;
}
return true;
}
/**
* 缓存用户信息
*/
public void cacheLoginUserInfo(String username, SysUser sysUser, String loginSuccessTips) {
if (StrUtil.isBlank(username) || sysUser == null) {
return;
}
redisUtil.del(CommonConstant.LOGIN_FAIL + username);
LoginUser loginUser = new LoginUser();
sysUser.setClient(GlobalUtils.loginClient());
BeanUtils.copyProperties(sysUser, loginUser);
baseCommonService.addLog("用户名: " + username + "," + loginSuccessTips, CommonConstant.LOG_TYPE_1, null, loginUser);
Cache cache = cacheManager.getCache(CacheConstant.SYS_USERS_CACHE);
if (Objects.nonNull(cache)) {
cache.put(sysUser.getId(), loginUser);
}
}
/**
* @description: 用户角色信息
* @author PengJ
* @date 2025/10/27 15:21
*/
public void handleUserRoles(SysUser user) {
if (ObjectUtil.isNull(user)) {
return;
}
List<SysRole> list = sysUserRoleMapper.getUserRolesByUserId(user.getId());
if (CollectionUtils.isEmpty(list)) {
return;
}
String roleCodes = list.stream().map(SysRole::getRoleCode)
.filter(StrUtil::isNotBlank)
.collect(Collectors.joining(","));
user.setRoleCodes(roleCodes);
}
/**
* @description: 用户部门信息处理
*/
public void handleUserDepartCodes(SysUser sysUser) {
if (sysUser == null || StrUtil.isBlank(sysUser.getDepartIds())) {
return;
}
String[] split = sysUser.getDepartIds().split(",");
List<String> codes = new ArrayList<>();
for (String departId : split) {
SysDepart departById = sysCache.getDepartById(departId);
if (departById != null) {
codes.add(departById.getOrgCode());
}
}
if (CollectionUtil.isNotEmpty(codes)) {
sysUser.setDepartCodes(String.join(",", codes));
}
}
/**
* @description: 插入用户设备信息
*/
public void insertUserDeviceType(String userId, String deviceType, String deviceSystem) {
LambdaQueryWrapper<SysUserDevice> wrapper = Wrappers.lambdaQuery(SysUserDevice.class)
.eq(SysUserDevice::getUserId, userId)
.eq(SysUserDevice::getDeviceType, deviceType)
.eq(SysUserDevice::getDeviceSystem, deviceSystem);
Optional<SysUserDevice> findOptional = sysUserDeviceService.getOneOpt(wrapper);
Date now = new Date();
if (findOptional.isPresent()) {
SysUserDevice sysUserDevice = findOptional.get();
sysUserDevice.setLastLoginTime(now);
sysUserDeviceService.updateById(sysUserDevice);
} else {
SysUserDevice sysUserDevice = new SysUserDevice();
sysUserDevice.setUserId(userId);
sysUserDevice.setDeviceSystem(deviceSystem);
sysUserDevice.setDeviceType(deviceType);
sysUserDevice.setCreateTime(now);
sysUserDevice.setLastLoginTime(now);
sysUserDeviceService.save(sysUserDevice);
}
}
}
@@ -32,7 +32,6 @@ import org.jeecg.common.exception.ExceptionAssertsUtil;
import org.jeecg.common.export.PoiExportHandler;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.DictUtil;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysUserModel;
import org.jeecg.common.util.*;
@@ -82,6 +81,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -164,6 +165,8 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
private UserDataRecordBloodAboMapper aboMapper;
@Autowired
RedisTemplate<String, Object> redisTemplate;
@Autowired
private AsyncTaskExecutor asyncTaskExecutor;
// 档案模块数据导出code
private final String exportCode = "sysDataUserExportCode";
@@ -182,7 +185,7 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
}
@Override
public IPage<UserEmployee> selectHealthUserEmployeeExList(Page page, UserFilter filter,Integer idStatus) {
public IPage<UserEmployee> selectHealthUserEmployeeExList(Page page, UserFilter filter, Integer idStatus) {
//四级单位判断
if (StringUtil.isNotBlank(filter.getDeptCode())) {
filter.setOrgCode(filter.getDeptCode());
@@ -227,8 +230,8 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
userEmployee.setAge(IdcardUtil.getAgeByIdCard(userEmployee.getIdCard()));
}
//新疆项目需要身份证脱敏处理
if(null != idStatus && idStatus == 1){
userEmployee.setIdCard(DesensitizedUtil.idCardNum(userEmployee.getIdCard(),3,3));
if (null != idStatus && idStatus == 1) {
userEmployee.setIdCard(DesensitizedUtil.idCardNum(userEmployee.getIdCard(), 3, 3));
}
});
return userEmployeeIPage;
@@ -372,33 +375,33 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
if (ObjectUtil.isNotEmpty(employeeHeightWeights)) {
employeeHeightWeights.parallelStream().forEach(ehw -> {
//日期不明的数据不入库 ,次判断逻辑可根据业务调整
if(ObjectUtil.isNotEmpty(ehw.getDataDate())){
if (ObjectUtil.isNotEmpty(ehw.getDataDate())) {
try {
//新增身高体重记录
String height = doStandardization(ehw.getHeight());
String weight = doStandardization(ehw.getWeight());
if(StrUtil.isNotEmpty(height) || StrUtil.isNotEmpty(weight)){
UserDataRecordBmi bmi = new UserDataRecordBmi(ehw.getUserFlag(),UserDataSourceEnum.MEDICAL);
bmi.setWeight(StrUtil.isNotEmpty(weight)? new BigDecimal(weight) : null);
bmi.setHeight(StrUtil.isNotEmpty(height)? new BigDecimal(height) : null);
if (StrUtil.isNotEmpty(height) || StrUtil.isNotEmpty(weight)) {
UserDataRecordBmi bmi = new UserDataRecordBmi(ehw.getUserFlag(), UserDataSourceEnum.MEDICAL);
bmi.setWeight(StrUtil.isNotEmpty(weight) ? new BigDecimal(weight) : null);
bmi.setHeight(StrUtil.isNotEmpty(height) ? new BigDecimal(height) : null);
bmi.setDataDate(ehw.getDataDate());
if(StrUtil.isNotEmpty(weight) && StrUtil.isNotEmpty(height)){
bmi.setBmi(computeBmi(weight,height));
if (StrUtil.isNotEmpty(weight) && StrUtil.isNotEmpty(height)) {
bmi.setBmi(computeBmi(weight, height));
}
recordBmiMapper.insert(bmi);
}
//新增血压信息记录
String sbp = doStandardization(ehw.getSbp());
String dbp = doStandardization(ehw.getDbp());
if(StrUtil.isNotEmpty(sbp) || StrUtil.isNotEmpty(sbp)){
if (StrUtil.isNotEmpty(sbp) || StrUtil.isNotEmpty(sbp)) {
UserDataRecordBloodPressure bloodPressure = new UserDataRecordBloodPressure(ehw.getUserFlag());
bloodPressure.setCreateTime(ehw.getDataDate());
bloodPressure.setSbp(StrUtil.isNotEmpty(sbp)? TypeConversionUtil.toDoubleOfNull(sbp) : null);
bloodPressure.setDbp(StrUtil.isNotEmpty(dbp)?TypeConversionUtil.toDoubleOfNull(dbp) : null);
bloodPressure.setSbp(StrUtil.isNotEmpty(sbp) ? TypeConversionUtil.toDoubleOfNull(sbp) : null);
bloodPressure.setDbp(StrUtil.isNotEmpty(dbp) ? TypeConversionUtil.toDoubleOfNull(dbp) : null);
recordBloodMapper.insert(bloodPressure);
}
//新增血型记录
if(StrUtil.isNotEmpty(ehw.getBlood())){
if (StrUtil.isNotEmpty(ehw.getBlood())) {
UserDataRecordBloodAbo abo = new UserDataRecordBloodAbo(ehw.getUserFlag());
abo.setCreateTime(ehw.getDataDate());
abo.setAbo(ehw.getBlood());
@@ -407,13 +410,13 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
//新增三维数据记录
String waist = doStandardization(ehw.getWaist());
String hip = doStandardization(ehw.getHip());
if(StrUtil.isNotEmpty(waist) || StrUtil.isNotEmpty(hip)){
if (StrUtil.isNotEmpty(waist) || StrUtil.isNotEmpty(hip)) {
UserDataRecordBWH bwh = new UserDataRecordBWH();
bwh.setUserId(ehw.getUserFlag());
bwh.setWaist(StrUtil.isNotEmpty(waist)? TypeConversionUtil.toDoubleOfNull(waist) : null);
bwh.setHip(StrUtil.isNotEmpty(hip)? TypeConversionUtil.toDoubleOfNull(hip) : null);
if(StrUtil.isNotEmpty(waist) && StrUtil.isNotEmpty(hip)){
bwh.setWaistHipRatio(new BigDecimal(waist).divide(new BigDecimal(hip),2, RoundingMode.HALF_UP).doubleValue());
bwh.setWaist(StrUtil.isNotEmpty(waist) ? TypeConversionUtil.toDoubleOfNull(waist) : null);
bwh.setHip(StrUtil.isNotEmpty(hip) ? TypeConversionUtil.toDoubleOfNull(hip) : null);
if (StrUtil.isNotEmpty(waist) && StrUtil.isNotEmpty(hip)) {
bwh.setWaistHipRatio(new BigDecimal(waist).divide(new BigDecimal(hip), 2, RoundingMode.HALF_UP).doubleValue());
}
bwh.setDataSource(UserDataSourceEnum.MEDICAL.source);
bwh.setCreateTime(ehw.getDataDate());
@@ -430,14 +433,15 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
/**
* 脏数据处理
*
* @param value
* @return
*/
private String doStandardization(String value){
if(StrUtil.isNotEmpty(value)){
private String doStandardization(String value) {
if (StrUtil.isNotEmpty(value)) {
//去除目标值中的汉字和字母, 处理后仍不是数字就认为是脏数据
value = value.replaceAll("[a-zA-Z]", "").replaceAll("[\u4e00-\u9fa5]", "");
if(!value.matches(numMatch)){
if (!value.matches(numMatch)) {
return null;
}
}
@@ -447,7 +451,7 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
private BigDecimal computeBmi(String weight, String height) {
try {
double bmi = Double.parseDouble(weight) / Math.pow(Double.parseDouble(height)/100, 2);
double bmi = Double.parseDouble(weight) / Math.pow(Double.parseDouble(height) / 100, 2);
return new BigDecimal(bmi).setScale(1, RoundingMode.HALF_UP);
} catch (Exception e) {
log.error("计算BMI失败, 身高: {}, 体重: {}", height, weight, e);
@@ -553,7 +557,7 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
LambdaQueryWrapper<UserDataRecordBmi> wrapper1 = getWrapper(userId);
wrapper1.isNotNull(UserDataRecordBmi::getFatRate);
UserDataRecordBmi userDataRecordBmi = recordBmiMapper.selectOne(wrapper1);
if (ObjUtil.isNotEmpty(userDataRecordBmi)){
if (ObjUtil.isNotEmpty(userDataRecordBmi)) {
result.setFatRate(Optional.ofNullable(userDataRecordBmi.getFatRate()).map(Object::toString).orElse(null));
}
}
@@ -607,16 +611,16 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
MPJLambdaWrapper<UserDataRecordBmi> wrapper = new MPJLambdaWrapper<>();
Date date = StrUtil.isNotEmpty(signUserParam.getDateStr()) ? DateUtil.parseDate(signUserParam.getDateStr()) : DateUtil.date();
wrapper.between(UserDataRecordBmi::getDataDate, DateUtil.beginOfDay(date), DateUtil.endOfDay(date));
wrapper.in(ObjectUtil.isNotEmpty(signUserParam.getUserIds()),UserDataRecordBmi::getUserId,signUserParam.getUserIds());
wrapper.notIn(UserDataRecordBmi::getDataSource,Arrays.asList(1,3)); //体检数据和管理员维护的数据不算打卡
wrapper.in(ObjectUtil.isNotEmpty(signUserParam.getUserIds()), UserDataRecordBmi::getUserId, signUserParam.getUserIds());
wrapper.notIn(UserDataRecordBmi::getDataSource, Arrays.asList(1, 3)); //体检数据和管理员维护的数据不算打卡
List<UserDataRecordBmi> signUser = recordBmiMapper.selectList(wrapper);
if (CollUtil.isEmpty(signUser)) {
return Collections.emptyList();
}
Map<String,List<UserDataRecordBmi>> groupByUserMap = signUser.stream().collect(Collectors.groupingBy(UserDataRecordBmi::getUserId));
Set<String> userIds = groupByUserMap.keySet();
//查询用户腰围数据 (查询当天最新的腰围数据)
List<EmployeeHeightWeight> userBwhList = recordBWHMapper.userBodyInfo(new ArrayList<>(userIds),DateUtil.formatDate(date));
Map<String, List<UserDataRecordBmi>> groupByUserMap = signUser.stream().collect(Collectors.groupingBy(UserDataRecordBmi::getUserId));
Set<String> userIds = groupByUserMap.keySet();
//查询用户腰围数据 (查询当天最新的腰围数据)
List<EmployeeHeightWeight> userBwhList = recordBWHMapper.userBodyInfo(new ArrayList<>(userIds), DateUtil.formatDate(date));
if (userBwhList == null) {
userBwhList = new ArrayList<>();
}
@@ -644,12 +648,12 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
@Override
public List<BaseUser> queryWeightMaxUser(QueryWeightMaxParam param) {
return healthUserEmployeeExMapper.queryWeightMaxUser(param.getDeptScope(),param.getUserScope());
return healthUserEmployeeExMapper.queryWeightMaxUser(param.getDeptScope(), param.getUserScope());
}
@Override
public List<BaseUser> queryGroupUserA(QueryqueryGroupAParam param) {
return healthUserEmployeeExMapper.queryGroupUserA(param.getDeptScope(),param.getUserScope());
return healthUserEmployeeExMapper.queryGroupUserA(param.getDeptScope(), param.getUserScope());
}
@Override
@@ -714,40 +718,41 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
String value = null;
String userId = GlobalUtils.getLoginUser().getId();
MPJLambdaWrapper<UserDataRecordBmi> bmiMPJLambdaWrapper = new MPJLambdaWrapper<>();
bmiMPJLambdaWrapper.eq(UserDataRecordBmi::getUserId,userId);
bmiMPJLambdaWrapper.eq(StrUtil.isNotEmpty(dataSource),UserDataRecordBmi::getDataSource,dataSource);
bmiMPJLambdaWrapper.eq(UserDataRecordBmi::getUserId, userId);
bmiMPJLambdaWrapper.eq(StrUtil.isNotEmpty(dataSource), UserDataRecordBmi::getDataSource, dataSource);
bmiMPJLambdaWrapper.orderByDesc(UserDataRecordBmi::getDataDate);
switch (target){
switch (target) {
case "weight":
bmiMPJLambdaWrapper.select(UserDataRecordBmi::getWeight);
bmiMPJLambdaWrapper.isNotNull(UserDataRecordBmi::getWeight);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper,false)).map(o -> String.valueOf(o.getWeight())).orElse(null);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper, false)).map(o -> String.valueOf(o.getWeight())).orElse(null);
break;
case "fat":
bmiMPJLambdaWrapper.select(UserDataRecordBmi::getFatRate);
bmiMPJLambdaWrapper.isNotNull(UserDataRecordBmi::getFatRate);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper,false)).map(o -> String.valueOf(o.getFatRate())).orElse(null);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper, false)).map(o -> String.valueOf(o.getFatRate())).orElse(null);
break;
case "height":
bmiMPJLambdaWrapper.select(UserDataRecordBmi::getHeight);
bmiMPJLambdaWrapper.isNotNull(UserDataRecordBmi::getHeight);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper,false)).map(o -> String.valueOf(o.getHeight())).orElse(null);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper, false)).map(o -> String.valueOf(o.getHeight())).orElse(null);
break;
case "bmi":
bmiMPJLambdaWrapper.select(UserDataRecordBmi::getBmi);
bmiMPJLambdaWrapper.isNotNull(UserDataRecordBmi::getBmi);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper,false)).map(o -> String.valueOf(o.getBmi())).orElse(null);
value = Optional.ofNullable(recordBmiMapper.selectOne(bmiMPJLambdaWrapper, false)).map(o -> String.valueOf(o.getBmi())).orElse(null);
break;
case "waist":
MPJLambdaWrapper<UserDataRecordBWH> bwhWrapper = new MPJLambdaWrapper<>();
bwhWrapper.eq(UserDataRecordBWH::getUserId,userId);
bwhWrapper.eq(StrUtil.isNotEmpty(dataSource),UserDataRecordBWH::getDataSource,dataSource);
bwhWrapper.eq(UserDataRecordBWH::getUserId, userId);
bwhWrapper.eq(StrUtil.isNotEmpty(dataSource), UserDataRecordBWH::getDataSource, dataSource);
bwhWrapper.orderByDesc(UserDataRecordBWH::getCreateTime);
bwhWrapper.select(UserDataRecordBWH::getWaist);
bwhWrapper.isNotNull(UserDataRecordBWH::getWaist);
value = Optional.ofNullable(recordBWHMapper.selectOne(bwhWrapper,false)).map(o -> String.valueOf(o.getWaist())).orElse(null);
value = Optional.ofNullable(recordBWHMapper.selectOne(bwhWrapper, false)).map(o -> String.valueOf(o.getWaist())).orElse(null);
break;
default:
break;
default:break;
}
return value;
}
@@ -805,7 +810,7 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
if (userEmployee == null) {
return new UserEmployee();
}
if(StrUtil.isNotEmpty(userEmployee.getIdCard())){
if (StrUtil.isNotEmpty(userEmployee.getIdCard())) {
userEmployee.setAge(IdcardUtil.getAgeByIdCard(userEmployee.getIdCard()));
}
return userEmployee;
@@ -824,6 +829,30 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
return userEmployee;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Result<String> addUserInfo(UserEmployee userEmployee) {
// 密码解密
String key = RSAEncryptUtils.decrypt1(userEmployee.getPassword(), CommonConstant.PRIVATE_KEY);
String s = CheckPasswordUtil.checkPasswordRule(key);
if (StrUtil.isNotBlank(s)) {
return Result.error(s);
}
userEmployee.setPassword(key);
boolean success = saveAndUser(userEmployee);
if (success) {
if (!GlobalUtils.isQh()) {
redisStreamUtil.add(RedisStreamKeyEnum.EMPLOYEE_ASYNC_ADD, userEmployee);
}
// 添加缓存
AsyncUtils.execute(asyncTaskExecutor, ClientSignThreadLocal.getClientSignThreadLocal(),
() -> userCacheManager.addUser(empConvertUser(userEmployee)));
return Result.ok("添加成功");
} else {
return Result.error("添加失败");
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveAndUser(UserEmployee userEmployee) {
@@ -850,7 +879,7 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
extension.setId(userId);
extension.setCreatedon(new Date());
// 添加当前年龄
if(StrUtil.isNotEmpty(userEmployee.getIdCard())){
if (StrUtil.isNotEmpty(userEmployee.getIdCard())) {
extension.setCurrentAge(GlobalUtils.getAgeByIdCard(userEmployee.getIdCard()));
}
int i = healthUserEmployeeExMapper.insert(extension);
@@ -883,6 +912,55 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
@Override
@Transactional(rollbackFor = Exception.class)
public Result<String> updateUserInfo(UserEmployee userEmployee, LoginUser loginUser) {
//将原来编辑用户逻辑迁移到service层
//通过userId获取用户修改前的部门信息
SysUser sysUser = sysUserService.getUserById(userEmployee.getId());
userEmployee.setPassword(null);
boolean success = updateByIdAndUser(userEmployee);
if (success) {
//编辑成功之后新增部门迁移列表
//若原有的部门跟编辑不一样则新增迁移列表,反之不用
if (Objects.nonNull(sysUser) && Objects.nonNull(sysUser.getDepart())
&& !sysUser.getDepart().getOrgCode().equals(userEmployee.getOrgCode())) {
SysUserDepartChangeApply departChangeApply = addUserDepartChange(sysUser, loginUser);
SysDepart sysDepart = sysCache.getDepartByOrgCode(userEmployee.getOrgCode());
departChangeApply.setToDepartId(sysDepart.getId());//迁入部门id
departChangeApply.setToDepartCode(userEmployee.getOrgCode());//迁入部门code
departChangeApply.setMemo("用户编辑数据");
sysUserDepartChangeApplyService.save(departChangeApply);
}
if (!GlobalUtils.isQh()) {
redisStreamUtil.add(RedisStreamKeyEnum.EMPLOYEE_ASYNC_EDIT, userEmployee);
}
// 编辑缓存
AsyncUtils.execute(asyncTaskExecutor, ClientSignThreadLocal.getClientSignThreadLocal(), () -> {
userCacheManager.updateUser(empConvertUser(userEmployee));
// 刷新用户缓存信息
userCacheManager.updateUserCache(userEmployee.getId());
});
String orgCode = userEmployee.getOrgCode();
if (com.xkcoding.http.util.StringUtil.isNotEmpty(orgCode)) {
sendUpdateMsgToRedisStream(userEmployee.getId(), orgCode);
}
return Result.ok("编辑成功");
} else {
return Result.error("编辑失败");
}
}
private void sendUpdateMsgToRedisStream(String userId, String orgCode) {
if (sysCache.getDepartByOrgCode(orgCode) == null) {
return;
}
SysUserModel userModel = new SysUserModel();
userModel.setId(userId);
userModel.setDepartIds(sysCache.getDepartByOrgCode(orgCode).getId());
userModel.setOrgCode(orgCode);
redisStreamUtil.add(RedisStreamKeyEnum.CHANGE_USER_DEPART, userModel);
}
public boolean updateByIdAndUser(UserEmployee userEmployee) {
// 添加账号 电话 身份证号校验
/* List<String> checkExistUser = sysBaseAPI.checkExistUser(userEmployee.getId(), userEmployee.getUsername(), userEmployee.getPhone(), userEmployee.getIdCard());
@@ -1244,8 +1322,8 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
}
}
//校验账号是否存在(登录账号为非必填, 若不填使用工号作为员工登录账号)
String userName = StrUtil.isEmpty(userEmployeeVo.getUsername())? userEmployeeVo.getEmpSysno() : userEmployeeVo.getUsername();
boolean noExists = sysUserService.lambdaQuery().eq(SysUser::getUsername,userName).or().eq(SysUser::getWorkNo,userEmployeeVo.getEmpSysno()).exists();
String userName = StrUtil.isEmpty(userEmployeeVo.getUsername()) ? userEmployeeVo.getEmpSysno() : userEmployeeVo.getUsername();
boolean noExists = sysUserService.lambdaQuery().eq(SysUser::getUsername, userName).or().eq(SysUser::getWorkNo, userEmployeeVo.getEmpSysno()).exists();
if (noExists) {
sd.append("该登录账号或工号已存在!");
}
@@ -1367,7 +1445,7 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
BeanUtils.copyProperties(userEmployeeVo, userEmployeeEx);
userEmployee.setExtension(userEmployeeEx);
//如果不传登录用户名 ,使用工号作为登录用户名
if(StrUtil.isEmpty(userEmployee.getUsername())){
if (StrUtil.isEmpty(userEmployee.getUsername())) {
userEmployee.setUsername(userEmployeeVo.getEmpSysno());
}
//新增随机密码
@@ -1377,7 +1455,7 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
userEmployee.setSex(Integer.parseInt(userEmployeeVo.getSex()));
}
//根据身份证号获取年龄
if(StrUtil.isNotEmpty(userEmployee.getIdCard())){
if (StrUtil.isNotEmpty(userEmployee.getIdCard())) {
userEmployee.setAge(IdcardUtil.getAgeByIdCard(userEmployee.getIdCard()));
}
//调用新增service
@@ -2099,10 +2177,10 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
public List<BaseEmployeeInfo> queryBaseEmployeeInfo(Set<String> ids) {
List<BaseEmployeeInfo> employeeInfoList = sysUserMapper.queryBaseEmployeeInfo(new ArrayList<>(ids));
//赋值员工部门信息 (单位,部门,当前部门), 只查库一次
if(ObjectUtil.isNotEmpty(employeeInfoList)){
if (ObjectUtil.isNotEmpty(employeeInfoList)) {
Set<String> orgCodes = Collections.synchronizedSet(new HashSet<>());
employeeInfoList.parallelStream().forEach(em ->{
if(StrUtil.isNotEmpty(em.getThisDeptCode())){
employeeInfoList.parallelStream().forEach(em -> {
if (StrUtil.isNotEmpty(em.getThisDeptCode())) {
String thirdDeptCode = GlobalUtils.getThirdDepartOrgCode(em.getThisDeptCode());
String secondDeptCode = GlobalUtils.getSecondDepartOrgCode(em.getThisDeptCode());
orgCodes.add(em.getThisDeptCode());
@@ -2112,9 +2190,9 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
em.setThirdDeptCode(thirdDeptCode);
}
});
Map<String,String> orgMap = sysDepartService.queryDepartNameByOrgCodes(orgCodes);
employeeInfoList.parallelStream().forEach(em ->{
if(StrUtil.isNotEmpty(em.getThisDeptCode())){
Map<String, String> orgMap = sysDepartService.queryDepartNameByOrgCodes(orgCodes);
employeeInfoList.parallelStream().forEach(em -> {
if (StrUtil.isNotEmpty(em.getThisDeptCode())) {
em.setThisDeptName(orgMap.get(em.getThisDeptCode()));
em.setThirdDeptName(orgMap.get(em.getThirdDeptCode()));
em.setSecondDeptName(orgMap.get(em.getSecondDeptCode()));
@@ -2128,10 +2206,10 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
public List<BaseEmployeeInfo> queryBaseEmployeeInfoByCondition(HealthUserEmployeeEx healthUserEmployeeEx) {
List<BaseEmployeeInfo> employeeInfoList = sysUserMapper.queryBaseEmployeeInfoByCondition(healthUserEmployeeEx);
//赋值员工部门信息 (单位,部门,当前部门), 只查库一次
if(ObjectUtil.isNotEmpty(employeeInfoList)){
if (ObjectUtil.isNotEmpty(employeeInfoList)) {
Set<String> orgCodes = Collections.synchronizedSet(new HashSet<>());
employeeInfoList.parallelStream().forEach(em ->{
if(StrUtil.isNotEmpty(em.getThisDeptCode())){
employeeInfoList.parallelStream().forEach(em -> {
if (StrUtil.isNotEmpty(em.getThisDeptCode())) {
String thirdDeptCode = GlobalUtils.getThirdDepartOrgCode(em.getThisDeptCode());
String secondDeptCode = GlobalUtils.getSecondDepartOrgCode(em.getThisDeptCode());
orgCodes.add(em.getThisDeptCode());
@@ -2141,9 +2219,9 @@ public class HealthUserEmployeeExServiceImpl extends ServiceImpl<HealthUserEmplo
em.setThirdDeptCode(thirdDeptCode);
}
});
Map<String,String> orgMap = sysDepartService.queryDepartNameByOrgCodes(orgCodes);
employeeInfoList.parallelStream().forEach(em ->{
if(StrUtil.isNotEmpty(em.getThisDeptCode())){
Map<String, String> orgMap = sysDepartService.queryDepartNameByOrgCodes(orgCodes);
employeeInfoList.parallelStream().forEach(em -> {
if (StrUtil.isNotEmpty(em.getThisDeptCode())) {
em.setThisDeptName(orgMap.get(em.getThisDeptCode()));
em.setThirdDeptName(orgMap.get(em.getThirdDeptCode()));
em.setSecondDeptName(orgMap.get(em.getSecondDeptCode()));
@@ -0,0 +1,353 @@
package org.jeecg.modules.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.renkang.anyan.client.AnYanClient;
import com.renkang.anyan.model.vo.AnYanUserInfoResult;
import com.renkang.anyan.model.vo.AuthResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.FillRuleConstant;
import org.jeecg.common.exception.ExceptionAssertsUtil;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CheckPasswordUtil;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.bean.UserEmployee;
import org.jeecg.modules.system.entity.HealthUserEmployeeEx;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysLoginModel;
import org.jeecg.modules.system.service.*;
import org.jeecg.util.RSAEncryptUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
/**
* @author Huawei
* @version 1.0
* @description: TODO
* @date 2025/10/24 18:06
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class LoginAnYanServiceImpl implements ILoginAnYanService {
private final ISysUserService sysUserService;
private final IHealthUserEmployeeExService healthUserEmployeeExService;
private final ISysDepartService sysDepartService;
private final ISysDictService sysDictService;
private final AnYanClient anYanClient;
private final RedisUtil redisUtil;
private final TaskExecutor taskExecutor;
private final LoginService loginService;
private static final String CLIENT_TYPE_PC = "pc";
private static final String CLIENT_TYPE_APP = "app";
/**
* @description: 安眼登录(pc
* @author PengJ
* @date 2025/10/27 13:31
*/
@Override
public Result<JSONObject> loginAnYan(SysLoginModel sysLoginModel) {
Result<JSONObject> result;
String username = sysLoginModel.getUsername();
try {
result = loginBusiness(sysLoginModel, username, CLIENT_TYPE_PC);
} catch (Exception e) {
log.error("安眼登录异常(pc: ", e);
return Result.error(e.getMessage());
}
return result;
}
/**
* @description: 安眼app登录
* @author PengJ
* @date 2025/10/27 15:35
*/
@Override
public Result<JSONObject> mLoginAnYan(SysLoginModel sysLoginModel) {
Result<JSONObject> result;
String username = sysLoginModel.getUsername();
try {
result = loginBusiness(sysLoginModel, username, CLIENT_TYPE_APP);
} catch (Exception e) {
log.error("安眼登录异常(app: ", e);
return Result.error(e.getMessage());
}
return result;
}
/**
* @description: 登录业务处理
* @author PengJ
* @date 2025/10/27 13:31
*/
public Result<JSONObject> loginBusiness(SysLoginModel sysLoginModel, String username, String clientType) {
// 密码解密
String decryptedPassword = RSAEncryptUtils.decrypt1(sysLoginModel.getPassword(), CommonConstant.PRIVATE_KEY);
if (StrUtil.isBlank(decryptedPassword)) {
return Result.error("密码解密失败");
}
// 获取安眼token
AuthResult anYanAuthResult = anYanClient.getAuthTokenByPassword(username, decryptedPassword);
if (anYanAuthResult == null || StringUtils.isBlank(anYanAuthResult.getAccess_token())) {
return Result.error(anYanAuthResult != null ? anYanAuthResult.getMessage() : "认证服务器无响应");
}
// 授权成功获取用户信息
AnYanUserInfoResult anYanUserInfo = anYanClient.getAnYanUserInfo(anYanAuthResult.getAccess_token());
if (anYanUserInfo == null) {
return Result.error("无法获取用户信息");
}
// 检查并更新用户信息
checkUserAndUpdate(anYanUserInfo, decryptedPassword);
// 获取本地用户信息
SysUser sysUser = sysUserService.getUserByNameOrWorkNoOrMobile(username, decryptedPassword, null);
if (sysUser == null) {
loginService.addLoginFailOvertimes(username);
return Result.error("账号或密码错误");
}
// 校验用户有效性
Result<JSONObject> result = sysUserService.checkUserIsEffective(sysUser);
if (!result.isSuccess()) {
return result;
}
// 弱密码校验
String checkMsg = CheckPasswordUtil.checkPasswordRule(decryptedPassword);
if (StrUtil.isNotBlank(checkMsg)) {
return Result.error(checkMsg);
}
// 处理用户相关信息(角色、岗位、管理部门)
loginService.processUserInfo(sysUser);
// 用户登录信息处理
userInfo(sysUser, result, clientType);
// 清除登录失败记录
redisUtil.del(CommonConstant.LOGIN_FAIL + username);
// 缓存登录用户信息
if (CLIENT_TYPE_PC.equals(clientType)) {
loginService.cacheLoginUserInfo(username, sysUser, "登录成功!");
} else if (CLIENT_TYPE_APP.equals(clientType)) {
loginService.cacheLoginUserInfo(username, sysUser, "登录成功[移动端]");
}
if (clientType.equals(CLIENT_TYPE_APP)) {
//录入登录用户的设备型号
if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(sysLoginModel.getDeviceType()) && com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(sysLoginModel.getDeviceSystem())) {
taskExecutor.execute(() ->
loginService.insertUserDeviceType(sysUser.getId(), sysLoginModel.getDeviceType(), sysLoginModel.getDeviceSystem()));
}
}
return result;
}
/**
* @description: 检查并更新用户信息
* @author PengJ
* @date 2025/10/27 9:50
*/
private void checkUserAndUpdate(AnYanUserInfoResult anYanUserInfo, String password) {
List<SysUser> list = sysUserService.list(new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getWorkNo, anYanUserInfo.getEmployeeUnitDTO().getEmployeeNum())
);
AnYanUserInfoResult.EmployeeUnitDTO employeeUnitDTO = anYanUserInfo.getEmployeeUnitDTO();
String departId = checkDepartAndUpdate(employeeUnitDTO);
if (list.isEmpty()) {
UserEmployee user = getUserEmployee(anYanUserInfo, password, employeeUnitDTO);
user.setPassword(password);
user.setOrgCode(departId);
user.setPersonType("1");
user.setStatus(1);
healthUserEmployeeExService.saveAndUser(user);
} else if (list.size() == 1) {
SysUser sysUser = list.get(0);
UserEmployee user = getUserEmployee(anYanUserInfo, password, employeeUnitDTO);
HealthUserEmployeeEx extension = user.getExtension();
extension.setId(sysUser.getId());
user.setExtension(extension);
user.setId(sysUser.getId());
user.setPassword(null);
user.setOrgCode(departId);
LoginUser loginUser = new LoginUser();
BeanUtil.copyProperties(user, loginUser);
healthUserEmployeeExService.updateUserInfo(user, loginUser);
} else {
ExceptionAssertsUtil.fail("用户工号重复");
}
}
/**
* @description: 用户信息赋值
* @author PengJ
* @date 2025/10/27 11:29
*/
@NotNull
private static UserEmployee getUserEmployee(AnYanUserInfoResult anYanUserInfo, String password, AnYanUserInfoResult.EmployeeUnitDTO employeeUnitDTO) {
HealthUserEmployeeEx healthUserEmployeeEx = new HealthUserEmployeeEx();
healthUserEmployeeEx.setEmpSysno(employeeUnitDTO.getEmployeeNum());
UserEmployee user = new UserEmployee();
user.setExtension(healthUserEmployeeEx);
user.setWorkNo(employeeUnitDTO.getEmployeeNum());
user.setUsername(anYanUserInfo.getLoginName());
user.setRealname(employeeUnitDTO.getName());
user.setEmail(employeeUnitDTO.getEmail());
user.setPhone(employeeUnitDTO.getMobile());
user.setSex(anYanUserInfo.getGender());
return user;
}
/**
* @description: 获取用户信息
* @author PengJ
* @date 2025/10/27 15:22
*/
private void userInfo(SysUser sysUser, Result<JSONObject> result, String clientType) {
String userId = sysUser.getId();
String username = sysUser.getUsername();
// 获取用户部门信息
JSONObject obj = new JSONObject(new LinkedHashMap<>());
//1.生成token
String token = JwtUtil.sign(sysUser);
// 设置token缓存有效时间
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
obj.put("token", token);
//2.设置登录租户
Result<JSONObject> loginTenantError = sysUserService.setLoginTenant(sysUser, obj, username, result);
if (loginTenantError != null) {
return;
}
if (clientType.equals(CLIENT_TYPE_PC)) {
//设置登录部门
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
obj.put("departs", departs);
if (departs == null || departs.isEmpty()) {
obj.put("multi_depart", 0);
} else if (departs.size() == 1) {
sysUserService.updateUserDepart(userId, departs.get(0).getOrgCode(), null);
obj.put("multi_depart", 1);
} else {
//查询当前是否有登录部门
// update-begin--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
SysUser sysUserById = sysUserService.getById(sysUser.getId());
if (oConvertUtils.isEmpty(sysUserById.getOrgCode())) {
sysUserService.updateUserDepart(userId, departs.get(0).getOrgCode(), null);
}
// update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
obj.put("multi_depart", 2);
}
//获取字典数据
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
} else if (clientType.equals(CLIENT_TYPE_APP)) {
String orgCode = sysUser.getOrgCode();
if (oConvertUtils.isEmpty(orgCode)) {
//如果当前用户无选择部门 查看部门关联信息
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
if (!departs.isEmpty()) {
orgCode = departs.get(0).getOrgCode();
sysUser.setOrgCode(orgCode);
this.sysUserService.updateUserDepart(sysUser.getId(), orgCode, null);
}
}
}
//设置登录用户信息
obj.put("userInfo", sysUser);
result.setResult(obj);
result.success("登录成功");
}
/**
* @description: 检查并更新部门信息(返回所属orgId)
* @author PengJ
* @date 2025/10/29 9:37
*/
private String checkDepartAndUpdate(AnYanUserInfoResult.EmployeeUnitDTO employeeUnitDTO) {
String levelPath = employeeUnitDTO.getLevelPath();
String orgId = "";
if (StringUtils.isNotBlank(levelPath)) {
String parentId = "";
String[] unitCodes = levelPath.split("\\|");
for (String unitCode : unitCodes) {
if (StringUtils.isBlank(unitCode) || "00000100".equals(unitCode)) {
parentId = sysDepartService.getOne(new LambdaQueryWrapper<SysDepart>()
.and(wrapper ->
wrapper.isNull(SysDepart::getParentId)
.or().eq(SysDepart::getParentId, "")
).eq(SysDepart::getOrgCategory, "1")
.eq(SysDepart::getOrgCode, "A01")
).getId();
continue;
}
SysDepart depart = sysDepartService.getOne(new LambdaQueryWrapper<SysDepart>()
.eq(SysDepart::getId, unitCode)
);
String orgName = "";
if (unitCode.equals(employeeUnitDTO.getUnitCode())) {
orgName = employeeUnitDTO.getUnitName();
} else if (unitCode.equals(employeeUnitDTO.getSectionUnitCode())) {
orgName = employeeUnitDTO.getSectionUnitName();
}
boolean save;
// 部门不存在
if (depart == null) {
depart = new SysDepart();
depart.setId(unitCode);
depart.setParentId(parentId);
JSONObject formData = new JSONObject();
formData.put("parentId", parentId);
String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData);
depart.setOrgCode(codeArray[0]);
String orgType = codeArray[1];
depart.setOrgType(String.valueOf(orgType));
depart.setDepartName(orgName);
depart.setCreateTime(new Date());
depart.setStatus("1");
depart.setDelFlag("0");
depart.setOrgCategory("2");
save = sysDepartService.save(depart);
} else {
save = sysDepartService.update(new LambdaUpdateWrapper<SysDepart>()
.eq(SysDepart::getId, depart.getId())
.set(SysDepart::getDepartName, orgName)
.set(SysDepart::getUpdateTime, new Date())
);
}
if (save) {
// 仅在父节点为叶子节点时更新为非叶子节点
SysDepart parentDepart = sysDepartService.getOne(new LambdaQueryWrapper<SysDepart>()
.eq(SysDepart::getId, parentId)
);
if (parentDepart != null && !parentDepart.getIzLeaf().equals(1)) {
sysDepartService.update(new LambdaUpdateWrapper<SysDepart>()
.eq(SysDepart::getId, parentId)
.set(SysDepart::getIzLeaf, "1")
);
}
}
parentId = depart.getId();
orgId = depart.getId();
}
}
return orgId;
}
}