Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
de2c84eeff
33 files changed
+826
-203
No files matched your search
+95
-93
@@ -59,115 +59,117 @@ import java.util.concurrent.TimeUnit;
|
||||
@RequiredArgsConstructor
|
||||
public class PjcloudAuthenticationFailureEventHandler implements AuthenticationFailureHandler {
|
||||
|
||||
private static final MappingJackson2HttpMessageConverter errorHttpResponseConverter = new MappingJackson2HttpMessageConverter();
|
||||
private static final MappingJackson2HttpMessageConverter errorHttpResponseConverter = new MappingJackson2HttpMessageConverter();
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
private final ApplicationEventPublisher publisher;
|
||||
private final ApplicationEventPublisher publisher;
|
||||
|
||||
private final KeyStrResolver tenantKeyStrResolver;
|
||||
private final KeyStrResolver tenantKeyStrResolver;
|
||||
|
||||
private final RemoteUserService userService;
|
||||
private final RemoteUserService userService;
|
||||
|
||||
/**
|
||||
* Called when an authentication attempt fails.
|
||||
* @param request the request during which the authentication attempt occurred.
|
||||
* @param response the response.
|
||||
* @param exception the exception which was thrown to reject the authentication
|
||||
* request.
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
||||
exception.printStackTrace();
|
||||
log.info("登录失败,异常:{}", exception.getLocalizedMessage());
|
||||
/**
|
||||
* Called when an authentication attempt fails.
|
||||
*
|
||||
* @param request the request during which the authentication attempt occurred.
|
||||
* @param response the response.
|
||||
* @param exception the exception which was thrown to reject the authentication
|
||||
* request.
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) {
|
||||
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
|
||||
exception.printStackTrace();
|
||||
log.info("登录失败,异常:|{}|stack:|{}|", exception.getLocalizedMessage(), exception.getStackTrace());
|
||||
|
||||
// 密码模式记录错误信息
|
||||
if (OAuth2ParameterNames.PASSWORD.equals(grantType)) {
|
||||
String username = request.getParameter(OAuth2ParameterNames.USERNAME);
|
||||
// 密码模式记录错误信息
|
||||
if (OAuth2ParameterNames.PASSWORD.equals(grantType)) {
|
||||
String username = request.getParameter(OAuth2ParameterNames.USERNAME);
|
||||
|
||||
// 密码错误记录错误次数 (TOC用户不记录)
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
if (exception instanceof OAuth2AuthenticationException
|
||||
&& !SecurityConstants.HEADER_TOC_YES.equals(header)) {
|
||||
recordLoginFailureTimes(username);
|
||||
}
|
||||
// 密码错误记录错误次数 (TOC用户不记录)
|
||||
String header = WebUtils.getRequest().getHeader(SecurityConstants.HEADER_TOC);
|
||||
if (exception instanceof OAuth2AuthenticationException
|
||||
&& !SecurityConstants.HEADER_TOC_YES.equals(header)) {
|
||||
recordLoginFailureTimes(username);
|
||||
}
|
||||
|
||||
// 记录登录失败错误信息
|
||||
sendFailureEventLog(request, exception, username);
|
||||
}
|
||||
// 记录登录失败错误信息
|
||||
sendFailureEventLog(request, exception, username);
|
||||
}
|
||||
|
||||
// 写出错误信息
|
||||
sendErrorResponse(request, response, exception);
|
||||
}
|
||||
// 写出错误信息
|
||||
sendErrorResponse(request, response, exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录失败日志
|
||||
* @param request HttpServletRequest
|
||||
* @param exception 错误日志
|
||||
* @param username 用户名
|
||||
*/
|
||||
private void sendFailureEventLog(HttpServletRequest request, AuthenticationException exception, String username) {
|
||||
SysLogDTO logVo = SysLogUtils.getSysLog();
|
||||
logVo.setTitle("登录失败");
|
||||
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
||||
logVo.setException(exception.getLocalizedMessage());
|
||||
// 发送异步日志事件
|
||||
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
||||
if (StrUtil.isNotBlank(startTimeStr)) {
|
||||
Long startTime = Long.parseLong(startTimeStr);
|
||||
Long endTime = System.currentTimeMillis();
|
||||
logVo.setTime(endTime - startTime);
|
||||
}
|
||||
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
String clientId = WebUtils.extractClientId(header).orElse(null);
|
||||
logVo.setServiceId(clientId);
|
||||
logVo.setCreateBy(username);
|
||||
logVo.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
|
||||
publisher.publishEvent(new SysLogEvent(logVo));
|
||||
}
|
||||
/**
|
||||
* 记录失败日志
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @param exception 错误日志
|
||||
* @param username 用户名
|
||||
*/
|
||||
private void sendFailureEventLog(HttpServletRequest request, AuthenticationException exception, String username) {
|
||||
SysLogDTO logVo = SysLogUtils.getSysLog();
|
||||
logVo.setTitle("登录失败");
|
||||
logVo.setLogType(LogTypeEnum.ERROR.getType());
|
||||
logVo.setException(exception.getLocalizedMessage());
|
||||
// 发送异步日志事件
|
||||
String startTimeStr = request.getHeader(CommonConstants.REQUEST_START_TIME);
|
||||
if (StrUtil.isNotBlank(startTimeStr)) {
|
||||
Long startTime = Long.parseLong(startTimeStr);
|
||||
Long endTime = System.currentTimeMillis();
|
||||
logVo.setTime(endTime - startTime);
|
||||
}
|
||||
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
String clientId = WebUtils.extractClientId(header).orElse(null);
|
||||
logVo.setServiceId(clientId);
|
||||
logVo.setCreateBy(username);
|
||||
logVo.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
|
||||
publisher.publishEvent(new SysLogEvent(logVo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录失败此处,如果操作阈值 调用接口锁定用户
|
||||
* @param username username
|
||||
*/
|
||||
private void recordLoginFailureTimes(String username) {
|
||||
String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, username);
|
||||
Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L);
|
||||
Long times = redisTemplate.opsForValue().increment(key);
|
||||
/**
|
||||
* 记录登录失败此处,如果操作阈值 调用接口锁定用户
|
||||
*
|
||||
* @param username username
|
||||
*/
|
||||
private void recordLoginFailureTimes(String username) {
|
||||
String key = String.format("%s:%s:%s", tenantKeyStrResolver.key(), CacheConstants.LOGIN_ERROR_TIMES, username);
|
||||
Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L);
|
||||
Long times = redisTemplate.opsForValue().increment(key);
|
||||
|
||||
// 自动过期时间
|
||||
Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L);
|
||||
redisTemplate.expire(key, deltaTime, TimeUnit.HOURS);
|
||||
// 自动过期时间
|
||||
Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L);
|
||||
redisTemplate.expire(key, deltaTime, TimeUnit.HOURS);
|
||||
|
||||
if (deltaTimes <= times) {
|
||||
userService.lockUser(username);
|
||||
}
|
||||
}
|
||||
if (deltaTimes <= times) {
|
||||
userService.lockUser(username);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
String errorMessage;
|
||||
private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
|
||||
httpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||
String errorMessage;
|
||||
|
||||
if (exception instanceof OAuth2AuthenticationException) {
|
||||
OAuth2AuthenticationException authorizationException = (OAuth2AuthenticationException) exception;
|
||||
errorMessage = StrUtil.isBlank(authorizationException.getError().getDescription())
|
||||
? authorizationException.getError().getErrorCode()
|
||||
: authorizationException.getError().getDescription();
|
||||
if (exception instanceof OAuth2AuthenticationException) {
|
||||
OAuth2AuthenticationException authorizationException = (OAuth2AuthenticationException) exception;
|
||||
errorMessage = StrUtil.isBlank(authorizationException.getError().getDescription())
|
||||
? authorizationException.getError().getErrorCode()
|
||||
: authorizationException.getError().getDescription();
|
||||
|
||||
this.errorHttpResponseConverter.write(
|
||||
R.failed(authorizationException.getError().getErrorCode(), errorMessage),
|
||||
MediaType.APPLICATION_JSON, httpResponse);
|
||||
this.errorHttpResponseConverter.write(
|
||||
R.failed(authorizationException.getError().getErrorCode(), errorMessage),
|
||||
MediaType.APPLICATION_JSON, httpResponse);
|
||||
|
||||
}
|
||||
else {
|
||||
errorMessage = exception.getLocalizedMessage();
|
||||
this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errorMessage = exception.getLocalizedMessage();
|
||||
this.errorHttpResponseConverter.write(R.failed(errorMessage), MediaType.APPLICATION_JSON, httpResponse);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -138,5 +138,7 @@ public interface CacheConstants {
|
||||
|
||||
String THIRDPARTY_ZY_MER_TOKEN = "thirdparty:zy:mer_token";
|
||||
|
||||
String THIRDPARTY_ZY_SELF_TOKEN = "thirdparty:zy:self_token:";
|
||||
|
||||
/* ************************************* end 第三方对接相关 end ************************************* */
|
||||
}
|
||||
+6
@@ -38,4 +38,10 @@ public enum HardOrderTypeEnum {
|
||||
return refundList.contains(type);
|
||||
}
|
||||
|
||||
public static List<String> getExternalCodes() {
|
||||
return List.of(
|
||||
HardOrderTypeEnum.FOREIGN_TICKET.type,
|
||||
HardOrderTypeEnum.STRIDE_DEPT.type
|
||||
);
|
||||
}
|
||||
}
|
||||
+2
@@ -31,6 +31,8 @@ public class HardOrderDto extends HardOrderEntity implements BaseIsIncludeTreeIn
|
||||
|
||||
private LocalDateTime[] payTimeList;
|
||||
|
||||
private List<String> orderTypeCodes;
|
||||
|
||||
/**
|
||||
* 是否查询购物车列表
|
||||
*/
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.bsd.pjcloud.hard.api.vo.order;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class HardZyCardSyncVo {
|
||||
|
||||
/**
|
||||
* 总人数
|
||||
*/
|
||||
private Long totalNum;
|
||||
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
private Long totalMoney;
|
||||
|
||||
/**
|
||||
* 年总人数
|
||||
*/
|
||||
private Long totalNumYear;
|
||||
|
||||
/**
|
||||
* 年总金额
|
||||
*/
|
||||
private Long totalMoneyYear;
|
||||
|
||||
/**
|
||||
* 月总人数
|
||||
*/
|
||||
private Long totalNumMonth;
|
||||
|
||||
/**
|
||||
* 月总金额
|
||||
*/
|
||||
private Long totalMoneyMonth;
|
||||
|
||||
/**
|
||||
* 月总人数
|
||||
*/
|
||||
private Long totalNumDay;
|
||||
|
||||
/**
|
||||
* 月总金额
|
||||
*/
|
||||
private Long totalMoneyDay;
|
||||
|
||||
}
|
||||
+15
@@ -13,11 +13,13 @@ import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import com.bsd.pjcloud.hard.api.constant.HardTypeEnum;
|
||||
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
|
||||
import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.HardDeptTotalDto;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardDeptTotalVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderSbVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardZyCardSyncVo;
|
||||
import com.bsd.pjcloud.hard.service.HardOrderTotalService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
@@ -45,6 +47,19 @@ public class HardOrderTotalController {
|
||||
|
||||
private final HardOrderTotalService HardOrderTotalService;
|
||||
|
||||
/* ************************************* start 远程调用 start ************************************* */
|
||||
|
||||
@PostMapping("/zy-card-sync")
|
||||
@Operation(summary = "正元本地一卡通交易数据同步")
|
||||
public R<HardZyCardSyncVo> zyCardSync() {
|
||||
HardOrderDto dto = new HardOrderDto();
|
||||
dto.setOrderStatusCodes(HardOrderStatusEnum.getPayPrice());
|
||||
dto.setOrderTypeCodes(HardOrderTypeEnum.getExternalCodes());
|
||||
return R.ok(HardOrderTotalService.totalYearMonthDay(dto));
|
||||
}
|
||||
|
||||
/* ************************************* end 远程调用 end ************************************* */
|
||||
|
||||
@PostMapping("/page-list-sb")
|
||||
@Operation(summary = "设备交易记录")
|
||||
public R<Page<HardOrderSbVo>> pageListSb(@ParameterObject Page page, @RequestBody HardOrderDto dto) {
|
||||
|
||||
+3
-4
@@ -11,10 +11,7 @@ import com.bsd.pjcloud.hard.api.dto.order.HardOrderSumAndCountDto;
|
||||
import com.bsd.pjcloud.hard.api.entity.HardManagerEntity;
|
||||
import com.bsd.pjcloud.hard.api.entity.order.HardAfterSaleEntity;
|
||||
import com.bsd.pjcloud.hard.api.entity.order.HardOrderEntity;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderSbVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderSumAndCountVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.*;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@@ -98,4 +95,6 @@ public interface HardOrderMapper extends PjcloudBaseMapper<HardOrderEntity> {
|
||||
List<HardOrderCsVo> listCs(@Param("dto") HardOrderDto dto);
|
||||
|
||||
List<HardOrderSumAndCountVo> sumAndCount(@Param("dto") HardOrderSumAndCountDto dto);
|
||||
|
||||
HardZyCardSyncVo totalYearMonthDay(@Param("dto") HardOrderDto hardOrderDto);
|
||||
}
|
||||
+3
@@ -6,6 +6,7 @@ import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardDeptTotalVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderSbVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardZyCardSyncVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -20,4 +21,6 @@ public interface HardOrderTotalService {
|
||||
List<HardOrderCsVo> listCs(HardOrderDto dto);
|
||||
|
||||
List<HardDeptTotalVo> pageListDept(HardDeptTotalDto dto);
|
||||
|
||||
HardZyCardSyncVo totalYearMonthDay(HardOrderDto dto);
|
||||
}
|
||||
+7
-4
@@ -8,16 +8,14 @@ import com.bsd.pjcloud.admin.api.entity.SysDept;
|
||||
import com.bsd.pjcloud.admin.api.feign.RemoteDeptService;
|
||||
import com.bsd.pjcloud.common.core.util.CollectionUtils;
|
||||
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
|
||||
import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum;
|
||||
import com.bsd.pjcloud.hard.api.dto.HardManagerDto;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.HardDeptTotalDto;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.HardOrderSumAndCountDto;
|
||||
import com.bsd.pjcloud.hard.api.entity.HardManagerEntity;
|
||||
import com.bsd.pjcloud.hard.api.utils.HardUtil;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardDeptTotalVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderSbVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.HardOrderSumAndCountVo;
|
||||
import com.bsd.pjcloud.hard.api.vo.order.*;
|
||||
import com.bsd.pjcloud.hard.mapper.HardManagerMapper;
|
||||
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
|
||||
import com.bsd.pjcloud.hard.service.HardOrderTotalService;
|
||||
@@ -291,4 +289,9 @@ public class HardOrderTotalServiceImpl implements HardOrderTotalService {
|
||||
});
|
||||
return resultListFuture.join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HardZyCardSyncVo totalYearMonthDay(HardOrderDto dto) {
|
||||
return hardOrderMapper.totalYearMonthDay(dto);
|
||||
}
|
||||
}
|
||||
+28
@@ -189,4 +189,32 @@
|
||||
group by a.dept_id
|
||||
</select>
|
||||
|
||||
<select id="totalYearMonthDay" resultType="com.bsd.pjcloud.hard.api.vo.order.HardZyCardSyncVo">
|
||||
SELECT
|
||||
COUNT(0) AS totalNum,
|
||||
SUM(a.pay_price) AS totalMoney,
|
||||
SUM(CASE WHEN YEAR(a.create_time) = YEAR(CURRENT_DATE()) THEN 1 ELSE 0 END) AS totalNumYear,
|
||||
SUM(CASE WHEN YEAR(a.create_time) = YEAR(CURRENT_DATE()) THEN a.pay_price ELSE 0 END) AS totalMoneyYear,
|
||||
SUM(CASE WHEN YEAR(a.create_time) = YEAR(CURRENT_DATE()) AND MONTH(a.create_time) = MONTH(CURRENT_DATE()) THEN 1 ELSE 0 END) AS totalNumMonth,
|
||||
SUM(CASE WHEN YEAR(a.create_time) = YEAR(CURRENT_DATE()) AND MONTH(a.create_time) = MONTH(CURRENT_DATE()) THEN a.pay_price ELSE 0 END) AS totalMoneyMonth,
|
||||
SUM(CASE WHEN YEAR(a.create_time) = YEAR(CURRENT_DATE()) AND MONTH(a.create_time) = MONTH(CURRENT_DATE()) AND DAY(a.create_time) = DAY(CURRENT_DATE()) THEN 1 ELSE 0 END) AS totalNumDay,
|
||||
SUM(CASE WHEN YEAR(a.create_time) = YEAR(CURRENT_DATE()) AND MONTH(a.create_time) = MONTH(CURRENT_DATE()) AND DAY(a.create_time) = DAY(CURRENT_DATE()) THEN a.pay_price ELSE 0 END) AS totalMoneyDay
|
||||
FROM
|
||||
hard_order a
|
||||
<where>
|
||||
a.del_flag = 0
|
||||
<if test="dto.orderStatusCodes != null and dto.orderStatusCodes.size() != 0">
|
||||
and a.order_status in
|
||||
<foreach collection="dto.orderStatusCodes" item="v" open="(" close=")" separator=",">
|
||||
#{v}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="dto.orderTypeCodes != null and dto.orderTypeCodes.size() != 0">
|
||||
and a.order_type in
|
||||
<foreach collection="dto.orderTypeCodes" item="v" open="(" close=")" separator=",">
|
||||
#{v}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
-3
@@ -8,9 +8,6 @@ import lombok.NoArgsConstructor;
|
||||
/**
|
||||
* 获取区域编码
|
||||
*/
|
||||
//@Builder
|
||||
//@AllArgsConstructor
|
||||
//@NoArgsConstructor
|
||||
@Data
|
||||
public class ZyForeignGetRegionIdByTokenDto {
|
||||
}
|
||||
+10
-7
@@ -14,15 +14,17 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class ZyMerSyncDealerInfoDto {
|
||||
|
||||
/**
|
||||
* 所属记账单位编号
|
||||
*/
|
||||
private String EPID;
|
||||
|
||||
/**
|
||||
* 商户所在系统的键值
|
||||
*/
|
||||
private String DealerKeyObj;
|
||||
|
||||
/**
|
||||
* 商户名称
|
||||
*/
|
||||
private String DealerName;
|
||||
|
||||
/**
|
||||
* 商户是否有效0:禁用 1:有效
|
||||
@@ -30,9 +32,10 @@ public class ZyMerSyncDealerInfoDto {
|
||||
private Integer IsValid;
|
||||
|
||||
/**
|
||||
* 所属记账单位编号
|
||||
* 商户名称
|
||||
*/
|
||||
private String EPID;
|
||||
private String DealerName;
|
||||
|
||||
|
||||
/**
|
||||
* 每次推送版本号,格式化为14位字符串,如果是数字不足14位的,前面补0。
|
||||
@@ -42,5 +45,5 @@ public class ZyMerSyncDealerInfoDto {
|
||||
/**
|
||||
* 商户类型,0食堂餐厅,1超市,2普通商家,3其他;不传默认是食堂餐厅类型
|
||||
*/
|
||||
private String DealerType;
|
||||
private Integer DealerType;
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.bsd.pjcloud.thirdparty.dto.zy.self;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ZySelfTokenDto {
|
||||
/**
|
||||
* 第三方app用户id
|
||||
*/
|
||||
private String appid;
|
||||
|
||||
/**
|
||||
* 第三方app用户密钥
|
||||
*/
|
||||
private String appSecret;
|
||||
|
||||
/**
|
||||
* 用户唯一标识
|
||||
*/
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* 登录时间
|
||||
*/
|
||||
private Long loginTime;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
private Long expireTime;
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.bsd.pjcloud.thirdparty.vo.zy;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ZyBaseEncryptVo {
|
||||
// 请求成功
|
||||
public static String successCode = "0";
|
||||
|
||||
private String code;
|
||||
|
||||
private String data;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return successCode.equals(code);
|
||||
}
|
||||
}
|
||||
+37
-2
@@ -1,14 +1,49 @@
|
||||
package com.bsd.pjcloud.thirdparty.vo.zy;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
public class ZyBaseVo {
|
||||
|
||||
// 请求成功
|
||||
public static String successCode = "0";
|
||||
|
||||
private Integer code;
|
||||
// 系统繁忙,具体看错误消息msg
|
||||
public static String errorCode = "-1";
|
||||
|
||||
// 应用服务错误
|
||||
public static String serviceError = "10003";
|
||||
|
||||
// 无效卡,错误信息可查看msg
|
||||
public static String invalidCard = "10004";
|
||||
|
||||
// 记账单位数据不存在,请先同步
|
||||
public static String accountBookIsEmpty = "20001";
|
||||
|
||||
// 请同步最新数据
|
||||
public static String syncNewData = "20002";
|
||||
|
||||
// 缺少签名参数
|
||||
public static String signIsEmpty = "30001";
|
||||
|
||||
// 无效的appId
|
||||
public static String appIdError = "40001";
|
||||
|
||||
// 无效的appSecret
|
||||
public static String appSecretError = "40002";
|
||||
|
||||
// 数据加密认证失败!sign值验证失败
|
||||
public static String signError = "40003";
|
||||
|
||||
// 无效的access_token
|
||||
public static String accessTokenError = "40004";
|
||||
|
||||
public static String defaultErrorMsg = "服务异常,请重试或联系管理员";
|
||||
|
||||
private String code;
|
||||
|
||||
private String msg;
|
||||
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ public class ZyForeignGetRegionIdByTokenVo extends ZyBaseVo {
|
||||
private VoData data;
|
||||
|
||||
@Data
|
||||
static class VoData {
|
||||
public static class VoData {
|
||||
/**
|
||||
* 区域编码
|
||||
*/
|
||||
@@ -22,7 +22,7 @@ public class ZyForeignGetRegionIdByTokenVo extends ZyBaseVo {
|
||||
*/
|
||||
private String regionAllName;
|
||||
/**
|
||||
* 地市简称
|
||||
* 地市简称
|
||||
*/
|
||||
private String regionName;
|
||||
}
|
||||
|
||||
+39
@@ -1,13 +1,52 @@
|
||||
package com.bsd.pjcloud.thirdparty.vo.zy.self;
|
||||
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.ZyBaseVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统提供冲正接口
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ZySelfCorrectVo extends ZyBaseVo {
|
||||
|
||||
/**
|
||||
* 帐号
|
||||
*/
|
||||
private String accNum;
|
||||
|
||||
/**
|
||||
* 用户姓名
|
||||
*/
|
||||
private String accName;
|
||||
|
||||
/**
|
||||
* 人员编号
|
||||
*/
|
||||
private String perCode;
|
||||
|
||||
/**
|
||||
* 订单流水号,全局唯一,第三方流水号
|
||||
*/
|
||||
private String platformSerialNum;
|
||||
|
||||
/**
|
||||
* 智慧园区通刷服务平台扣费流水号
|
||||
*/
|
||||
private String serialNum;
|
||||
|
||||
/**
|
||||
* 消费金额,格式是XX.XX元
|
||||
*/
|
||||
private String amount;
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统返回正常扣费的时间点 统一为yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
private String recDate;
|
||||
}
|
||||
+6
@@ -1,12 +1,18 @@
|
||||
package com.bsd.pjcloud.thirdparty.vo.zy.self;
|
||||
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.ZyBaseVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 第三方提供获取token
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ZySelfGetTokenVo extends ZyBaseVo {
|
||||
|
||||
private String access_token;
|
||||
|
||||
+41
@@ -1,11 +1,52 @@
|
||||
package com.bsd.pjcloud.thirdparty.vo.zy.self;
|
||||
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.ZyBaseVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统提供扣费接口
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ZySelfPayVo extends ZyBaseVo {
|
||||
|
||||
/**
|
||||
* 帐号
|
||||
*/
|
||||
private String accNum;
|
||||
|
||||
/**
|
||||
* 用户姓名
|
||||
*/
|
||||
private String accName;
|
||||
|
||||
/**
|
||||
* 人员编号
|
||||
*/
|
||||
private String perCode;
|
||||
|
||||
/**
|
||||
* 订单流水号,全局唯一,第三方流水号
|
||||
*/
|
||||
private String platformSerialNum;
|
||||
|
||||
/**
|
||||
* 智慧园区通刷服务平台扣费流水号
|
||||
*/
|
||||
private String serialNum;
|
||||
|
||||
/**
|
||||
* 消费金额,格式是XX.XX元
|
||||
*/
|
||||
private String amount;
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统返回正常扣费的时间点 统一为yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
private String recDate;
|
||||
}
|
||||
@@ -104,6 +104,17 @@
|
||||
<groupId>com.bsd</groupId>
|
||||
<artifactId>pjcloud-common-seata</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.15</version>
|
||||
</dependency>
|
||||
<!-- Token生成与解析-->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
|
||||
+6
@@ -22,4 +22,10 @@ public class ZyConfig {
|
||||
|
||||
private String selfAppSecret;
|
||||
|
||||
private Long selfExpiresIn;
|
||||
|
||||
private String selfTokenKey;
|
||||
|
||||
private String selfTokenSecret;
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.bsd.pjcloud.thirdparty.controller.zy;
|
||||
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfCorrectDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfGetTokenDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfPayDto;
|
||||
import com.bsd.pjcloud.thirdparty.service.impl.ZySelfService;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfCorrectVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfGetTokenVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfPayVo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/third/zy")
|
||||
@Tag(description = "thirdPartyDept", name = "正元接口对接")
|
||||
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
||||
public class ZySelfController {
|
||||
|
||||
private final ZySelfService zySelfService;
|
||||
|
||||
@GetMapping("/checkSystemStatus")
|
||||
@Operation(summary = "第三方url健康探测", description = "第三方url健康探测")
|
||||
public Map<String, Object> checkSystemStatus() {
|
||||
return zySelfService.checkSystemStatus();
|
||||
}
|
||||
|
||||
@GetMapping("/getToken")
|
||||
@Operation(summary = "第三方提供获取token", description = "第三方提供获取token")
|
||||
public ZySelfGetTokenVo getToken(ZySelfGetTokenDto params) {
|
||||
return zySelfService.getToken(params);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/correct")
|
||||
@Operation(summary = "第三方一卡通系统提供冲正接口", description = "第三方一卡通系统提供冲正接口")
|
||||
public ZySelfCorrectVo correct(@RequestBody ZySelfCorrectDto params, @RequestParam(value = "access_token", required = false) String accessToken) {
|
||||
return zySelfService.correct(params, accessToken);
|
||||
}
|
||||
|
||||
@PostMapping("/getToken")
|
||||
@Operation(summary = "第三方一卡通系统提供扣费接口", description = "第三方一卡通系统提供扣费接口")
|
||||
public ZySelfPayVo pay(@RequestBody ZySelfPayDto params, @RequestParam(value = "access_token", required = false) String accessToken) {
|
||||
return zySelfService.pay(params, accessToken);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.bsd.pjcloud.thirdparty.service;
|
||||
|
||||
public interface ZyDoForeignService {
|
||||
|
||||
// 本地一卡通交易数据同步
|
||||
void syncNativeCardTradeInfo();
|
||||
|
||||
}
|
||||
+1
-1
@@ -15,6 +15,6 @@ public interface ZyForeignService {
|
||||
/**
|
||||
* 获取区域编码
|
||||
*/
|
||||
ZyForeignGetRegionIdByTokenVo getRegionIdByToken(ZyForeignGetRegionIdByTokenDto dto);
|
||||
ZyForeignGetRegionIdByTokenVo.VoData getRegionIdByToken();
|
||||
|
||||
}
|
||||
+3
-1
@@ -6,12 +6,14 @@ import com.bsd.pjcloud.thirdparty.dto.zy.mer.ZyMerSyncDealerInfoDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.mer.ZyMerSyncEnterpriseInfoDto;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.mer.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ZyMerService {
|
||||
|
||||
/**
|
||||
* 商户信息同步
|
||||
*/
|
||||
ZyMerSyncDealerInfoVo syncDealerInfoApi(ZyMerSyncDealerInfoDto dto);
|
||||
ZyMerSyncDealerInfoVo syncDealerInfoApi(List<ZyMerSyncDealerInfoDto> dto);
|
||||
|
||||
/**
|
||||
* 记账单位同步
|
||||
|
||||
+29
@@ -1,4 +1,33 @@
|
||||
package com.bsd.pjcloud.thirdparty.service.impl;
|
||||
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfCorrectDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfGetTokenDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfPayDto;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfCorrectVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfGetTokenVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfPayVo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ZySelfService {
|
||||
|
||||
/**
|
||||
* 第三方url健康探测
|
||||
*/
|
||||
Map<String, Object> checkSystemStatus();
|
||||
|
||||
/**
|
||||
* 第三方提供获取token
|
||||
*/
|
||||
ZySelfGetTokenVo getToken(ZySelfGetTokenDto params);
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统提供冲正接口
|
||||
*/
|
||||
ZySelfCorrectVo correct(ZySelfCorrectDto params, String accessToken);
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统提供扣费接口
|
||||
*/
|
||||
ZySelfPayVo pay(ZySelfPayDto params, String accessToken);
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.bsd.pjcloud.thirdparty.service.impl.zy;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.foreign.ZyForeignSyncNativeCardTradeInfoDto;
|
||||
import com.bsd.pjcloud.thirdparty.service.ZyDoForeignService;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.foreign.ZyForeignGetRegionIdByTokenVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.foreign.ZyForeignSyncNativeCardTradeInfoVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ZyDoForeignServiceImpl implements ZyDoForeignService {
|
||||
|
||||
private final ZyForeignServiceImpl zyForeignServiceImpl;
|
||||
|
||||
@Override
|
||||
public void syncNativeCardTradeInfo() {
|
||||
ZyForeignGetRegionIdByTokenVo.VoData region = zyForeignServiceImpl.getRegionIdByToken();
|
||||
if (ObjectUtil.isEmpty(region)) {
|
||||
return;
|
||||
}
|
||||
ZyForeignSyncNativeCardTradeInfoDto asyncDto = new ZyForeignSyncNativeCardTradeInfoDto();
|
||||
asyncDto.setRegionCode(region.getRegionCode());
|
||||
ZyForeignSyncNativeCardTradeInfoVo vo = zyForeignServiceImpl.syncNativeCardTradeInfoApi(asyncDto);
|
||||
}
|
||||
}
|
||||
+12
-11
@@ -1,5 +1,6 @@
|
||||
package com.bsd.pjcloud.thirdparty.service.impl.zy;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -9,6 +10,7 @@ import com.bsd.pjcloud.thirdparty.dto.zy.foreign.ZyForeignSyncNativeCardTradeInf
|
||||
import com.bsd.pjcloud.thirdparty.service.impl.ZyForeignService;
|
||||
import com.bsd.pjcloud.thirdparty.utils.zy.api.ZyApi;
|
||||
import com.bsd.pjcloud.thirdparty.utils.zy.api.ZyApiTool;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.ZyBaseEncryptVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.foreign.ZyForeignGetRegionIdByTokenVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.foreign.ZyForeignSyncNativeCardTradeInfoVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -64,24 +66,23 @@ public class ZyForeignServiceImpl implements ZyForeignService {
|
||||
* 获取区域编码
|
||||
*/
|
||||
@Override
|
||||
public ZyForeignGetRegionIdByTokenVo getRegionIdByToken(ZyForeignGetRegionIdByTokenDto dto) {
|
||||
public ZyForeignGetRegionIdByTokenVo.VoData getRegionIdByToken() {
|
||||
String url = zyConfig.getBaseUrl() + ZyApi.Foreign.GET_REGION_ID_BY_TOKEN;
|
||||
try {
|
||||
url = String.format(url, zyApiTool.getToken());
|
||||
Map<String, Object> encryptionBody = new HashMap<>();
|
||||
encryptionBody.put("accClasses", dto);
|
||||
String body = zyApiTool.getEncryptionDto(encryptionBody);
|
||||
String res = HttpRequest.post(url)
|
||||
.body(body)
|
||||
.execute()
|
||||
.body();
|
||||
String res = HttpRequest.get(url).execute().body();
|
||||
if (ObjectUtil.isEmpty(res)) {
|
||||
throw new RuntimeException("response is empty");
|
||||
}
|
||||
ZyForeignGetRegionIdByTokenVo vo = JSONUtil.toBean(res, ZyForeignGetRegionIdByTokenVo.class);
|
||||
if (!vo.isSuccess()) {
|
||||
throw new RuntimeException(String.format("请求错误res|%s|url|%s|body|%s|", res, url, body));
|
||||
ZyBaseEncryptVo baseEncryptVo = JSONUtil.toBean(res, ZyBaseEncryptVo.class);
|
||||
if (ObjectUtil.isEmpty(baseEncryptVo)) {
|
||||
throw new RuntimeException(String.format("解密错误res|%s|url|%s|res|%s|", res, url, baseEncryptVo));
|
||||
}
|
||||
if (!baseEncryptVo.isSuccess()) {
|
||||
throw new RuntimeException(String.format("请求错误res|%s|url|%s|", res, url));
|
||||
}
|
||||
String json = Base64.decodeStr(baseEncryptVo.getData());
|
||||
ZyForeignGetRegionIdByTokenVo.VoData vo = JSONUtil.toBean(json, ZyForeignGetRegionIdByTokenVo.VoData.class);
|
||||
return vo;
|
||||
} catch (Exception e) {
|
||||
log.error("|{}||getRegionIdByToken|意外的错误error|{}|", TAG, e.getMessage());
|
||||
|
||||
+14
-2
@@ -1,5 +1,6 @@
|
||||
package com.bsd.pjcloud.thirdparty.service.impl.zy;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -17,7 +18,9 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@@ -36,14 +39,23 @@ public class ZyMerServiceImpl implements ZyMerService {
|
||||
* 商户信息同步
|
||||
*/
|
||||
@Override
|
||||
public ZyMerSyncDealerInfoVo syncDealerInfoApi(ZyMerSyncDealerInfoDto dto) {
|
||||
public ZyMerSyncDealerInfoVo syncDealerInfoApi(List<ZyMerSyncDealerInfoDto> dto) {
|
||||
if (ObjectUtil.isEmpty(dto)) {
|
||||
return null;
|
||||
}
|
||||
List<Map<String, Object>> listMap = new ArrayList<>();
|
||||
for (ZyMerSyncDealerInfoDto v : dto) {
|
||||
Map<String, Object> map = zyApiTool.removeEmptyMap(BeanUtil.beanToMap(v));
|
||||
listMap.add(map);
|
||||
}
|
||||
String url = zyConfig.getBaseUrl() + ZyApi.Mer.SYNC_DEALER_INFO;
|
||||
try {
|
||||
url = String.format(url, zyApiTool.getToken());
|
||||
Map<String, Object> encryptionBody = new HashMap<>();
|
||||
encryptionBody.put("dealers", dto);
|
||||
encryptionBody.put("dealers", listMap);
|
||||
String body = zyApiTool.getEncryptionDto(encryptionBody);
|
||||
String res = HttpRequest.post(url)
|
||||
.contentType("application/x-www-form-urlencoded")
|
||||
.body(body)
|
||||
.execute()
|
||||
.body();
|
||||
|
||||
+148
@@ -1,14 +1,162 @@
|
||||
package com.bsd.pjcloud.thirdparty.service.impl.zy;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.thirdparty.config.ZyConfig;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfCorrectDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfGetTokenDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfPayDto;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.self.ZySelfTokenDto;
|
||||
import com.bsd.pjcloud.thirdparty.service.impl.ZySelfService;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.ZyBaseVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfCorrectVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfGetTokenVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.self.ZySelfPayVo;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ZySelfServiceImpl implements ZySelfService {
|
||||
|
||||
private final String TAG = "第三方需提供的接口api";
|
||||
|
||||
private final ZyConfig zyConfig;
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 第三方url健康探测
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> checkSystemStatus() {
|
||||
String systemTime = DateUtil.formatDateTime(new Date());
|
||||
Map<String, Object> result = Map.of("systemTime", systemTime);
|
||||
log.info("|{}|checkSystemStatus res|{}|", TAG, JSONUtil.toJsonStr(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统提供冲正接口
|
||||
*/
|
||||
@Override
|
||||
public ZySelfCorrectVo correct(ZySelfCorrectDto params, String accessToken) {
|
||||
ZySelfCorrectVo result = new ZySelfCorrectVo();
|
||||
result.setCode(ZyBaseVo.errorCode);
|
||||
boolean isToken = checkIsToken(accessToken);
|
||||
if (!isToken) {
|
||||
result.setCode(ZyBaseVo.accessTokenError);
|
||||
result.setMsg("无效的access_token");
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方一卡通系统提供扣费接口
|
||||
*/
|
||||
@Override
|
||||
public ZySelfPayVo pay(ZySelfPayDto params, String accessToken) {
|
||||
ZySelfCorrectVo result = new ZySelfCorrectVo();
|
||||
result.setCode(ZyBaseVo.errorCode);
|
||||
boolean isToken = checkIsToken(accessToken);
|
||||
if (!isToken) {
|
||||
result.setCode(ZyBaseVo.accessTokenError);
|
||||
result.setMsg("无效的access_token");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方提供获取token
|
||||
*/
|
||||
@Override
|
||||
public ZySelfGetTokenVo getToken(ZySelfGetTokenDto params) {
|
||||
ZySelfGetTokenVo result = new ZySelfGetTokenVo();
|
||||
result.setCode(ZyBaseVo.errorCode);
|
||||
if (ObjectUtil.isEmpty(params.getAppid()) || ObjectUtil.equals(params.getAppid(), zyConfig.getSelfAppId())) {
|
||||
result.setMsg("appid 无效");
|
||||
return result;
|
||||
}
|
||||
if (ObjectUtil.isEmpty(params.getAppsecret()) || ObjectUtil.equals(params.getAppsecret(), zyConfig.getSelfAppSecret())) {
|
||||
result.setMsg("appSecret 无效");
|
||||
return result;
|
||||
}
|
||||
String redisKey = CacheConstants.THIRDPARTY_ZY_SELF_TOKEN;
|
||||
redisTemplate.opsForValue().getAndDelete(redisKey);
|
||||
try {
|
||||
// 生成token
|
||||
String token = generateToken(params);
|
||||
result.setCode(ZyBaseVo.successCode);
|
||||
result.setAccess_token(token);
|
||||
result.setExpires_in(zyConfig.getSelfExpiresIn().toString());
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error("|{}|getToken意外的错误dto|{}|error|{}|stack|{}|", TAG, JSONUtil.toJsonStr(params), e.getMessage(), e.getStackTrace());
|
||||
result.setMsg(ZyBaseVo.defaultErrorMsg);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkIsToken(String string) {
|
||||
if (ObjectUtil.isEmpty(string)) {
|
||||
log.info("|{}|checkIsToken校验错误,未传入token|{}|", TAG, string);
|
||||
return false;
|
||||
}
|
||||
Claims claims = Jwts.parser()
|
||||
.setSigningKey(zyConfig.getSelfAppSecret())
|
||||
.parseClaimsJws(string)
|
||||
.getBody();
|
||||
String token = (String) claims.get(zyConfig.getSelfTokenKey());
|
||||
String redisKey = CacheConstants.THIRDPARTY_ZY_SELF_TOKEN + token;
|
||||
String json = redisTemplate.opsForValue().get(redisKey);
|
||||
if (ObjectUtil.isEmpty(json)) {
|
||||
log.info("|{}|checkIsToken校验错误token|{}|", TAG, string);
|
||||
return false;
|
||||
}
|
||||
log.info("|{}|checkIsToken校验成功info|{}|", TAG, json);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 生成token
|
||||
private String generateToken(ZySelfGetTokenDto dto) {
|
||||
ZySelfTokenDto selfTokenDto = new ZySelfTokenDto();
|
||||
String token = IdUtil.fastUUID();
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put(zyConfig.getSelfTokenKey(), token);
|
||||
// 刷新token
|
||||
selfTokenDto.setToken(token);
|
||||
selfTokenDto.setAppid(dto.getAppid());
|
||||
selfTokenDto.setAppSecret(dto.getAppsecret());
|
||||
refreshToken(selfTokenDto);
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.signWith(SignatureAlgorithm.HS512, zyConfig.getSelfTokenSecret()).compact();
|
||||
}
|
||||
|
||||
/// 刷新token
|
||||
public void refreshToken(ZySelfTokenDto dto) {
|
||||
dto.setLoginTime(System.currentTimeMillis());
|
||||
dto.setExpireTime(dto.getLoginTime() + zyConfig.getSelfExpiresIn() + 100);
|
||||
String redisKey = CacheConstants.THIRDPARTY_ZY_SELF_TOKEN + dto.getToken();
|
||||
redisTemplate.opsForValue().set(redisKey, JSONUtil.toJsonStr(dto), zyConfig.getSelfExpiresIn(), TimeUnit.MINUTES);
|
||||
}
|
||||
}
|
||||
+71
-15
@@ -1,23 +1,27 @@
|
||||
package com.bsd.pjcloud.thirdparty.utils.zy.api;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.bsd.pjcloud.common.core.constant.CacheConstants;
|
||||
import com.bsd.pjcloud.thirdparty.config.ZyConfig;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.mer.ZyMerGetTokenVo;
|
||||
import io.undertow.security.idm.DigestAlgorithm;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.commons.codec.digest.DigestUtils.md5Hex;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@Validated
|
||||
@@ -25,13 +29,13 @@ import static org.apache.commons.codec.digest.DigestUtils.md5Hex;
|
||||
@RequiredArgsConstructor
|
||||
public class ZyApiTool {
|
||||
|
||||
private final String TAG = "正元请求工具类";
|
||||
static private final String TAG = "正元请求工具类";
|
||||
|
||||
private final ZyConfig zyConfig;
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
public ZyMerGetTokenVo getTokenApi() {
|
||||
public ZyMerGetTokenVo getTokenApi() throws Exception {
|
||||
String url = zyConfig.getBaseUrl() + ZyApi.Mer.GET_TOKEN;
|
||||
url = String.format(url, zyConfig.getAppId(), zyConfig.getAppSecret());
|
||||
try {
|
||||
@@ -43,12 +47,12 @@ public class ZyApiTool {
|
||||
throw new RuntimeException("response is empty");
|
||||
}
|
||||
ZyMerGetTokenVo vo = JSONUtil.toBean(res, ZyMerGetTokenVo.class);
|
||||
if (!vo.isSuccess()) {
|
||||
if (ObjectUtil.isEmpty(vo) || !ObjectUtil.isAllNotEmpty(vo.getAccess_token(), vo.getExpires_in())) {
|
||||
throw new RuntimeException(String.format("请求错误res|%s|url|%s|", res, url));
|
||||
}
|
||||
return vo;
|
||||
} catch (Exception e) {
|
||||
log.error("|{}||getTokenApi|意外的错误error|{}|", TAG, e.getMessage());
|
||||
log.error("|{}||getTokenApi|意外的错误error|{}|stack:|{}|", TAG, e.getMessage(), e.getStackTrace());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -61,7 +65,16 @@ public class ZyApiTool {
|
||||
ZyMerGetTokenVo vo = getTokenApi();
|
||||
if (ObjectUtil.isNotEmpty(vo)) {
|
||||
String accessToken = vo.getAccess_token();
|
||||
String expiresIn = vo.getExpires_in();
|
||||
redisTemplate.opsForValue().set(redisKey, accessToken);
|
||||
try {
|
||||
long expiresInNum = Long.parseLong(expiresIn);
|
||||
if (ObjectUtil.isNotEmpty(expiresInNum) && expiresInNum > 100) {
|
||||
redisTemplate.expire(redisKey, expiresInNum - 100, TimeUnit.SECONDS);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("|{}|意外的错误error|{}|stack|{}|", TAG, e.getMessage(), e.getStackTrace());
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
@@ -72,15 +85,58 @@ public class ZyApiTool {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> String getEncryptionDto(T params) {
|
||||
String json = JSONUtil.toJsonStr(params);
|
||||
String encodedData = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8));
|
||||
String stringToSign = String.format("data=%s&key=%s", json, zyConfig.getAppId());
|
||||
String sign = md5Hex(stringToSign);
|
||||
public String getEncryptionDto(Map<String, Object> params) {
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("data", encodedData);
|
||||
body.put("sign", sign);
|
||||
body.put("data", params);
|
||||
prePost(body);
|
||||
return JSONUtil.toJsonStr(body);
|
||||
}
|
||||
|
||||
public Map<String, Object> removeEmptyMap(Map<String, Object> params) {
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value == null) {
|
||||
params.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
private void prePost(Map<String, Object> params) {
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
entry.setValue(URLUtil.encode((String) value));
|
||||
} else {
|
||||
String json = JSONUtil.toJsonStr(value);
|
||||
entry.setValue(json);
|
||||
}
|
||||
}
|
||||
String sign = generateSign(params);
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
entry.setValue(Base64.encode((String) value));
|
||||
} else {
|
||||
entry.setValue(Base64.encode(value.toString()));
|
||||
}
|
||||
}
|
||||
params.put("sign", sign);
|
||||
}
|
||||
|
||||
private String generateSign(Map<String, Object> params) {
|
||||
// 将参数以参数名的字典升序排序
|
||||
Map<String, Object> sortParams = new TreeMap<String, Object>(params);
|
||||
Set<Map.Entry<String, Object>> entrys = sortParams.entrySet();
|
||||
StringBuilder baseString = new StringBuilder();
|
||||
for (Map.Entry<String, Object> entry : entrys) {
|
||||
baseString.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
|
||||
}
|
||||
baseString.append("key=").append(zyConfig.getAppId());
|
||||
String signStr = baseString.toString();
|
||||
String digestHex = DigestUtils.md5Hex(signStr);
|
||||
log.info("|{}|加密前的参数为|{}|加密后的参数为|{}|", TAG, signStr, digestHex);
|
||||
return digestHex;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-4
@@ -45,8 +45,15 @@ oauth2:
|
||||
# https://gwyc.zj.gov.cn/API/%E7%9C%81%E5%B9%B3%E5%8F%B0API%E5%AF%B9%E6%8E%A5%E6%8E%A5%E5%8F%A3.html
|
||||
zy:
|
||||
base-url: http://60.191.37.212:18079
|
||||
app-id: 03D9608D1735D424F984733BA71321C6
|
||||
app-secret: 65497A86DB1401B252FEA6DE0A080766
|
||||
app-id: 689C8D6F5059A6F85B8BE45A49001ACB
|
||||
app-secret: BD21DA0DEB8F0FC43246B0BD2FCAE6FF
|
||||
|
||||
self-base-url: http://60.191.37.212:18079
|
||||
self-app-id: 03D9608D1735D424F984733BA71321C6
|
||||
self-app-secret: 03D9608D1735D424F984733BA71321C6
|
||||
self-app-id: xA5jF2vX4zO5mQ8tR9yE7rC7iI0fK0kI
|
||||
self-app-secret: kE3hH5gF7zN0nH1yI5yX3vP0oP1hU0jE
|
||||
# 失效时间单位秒
|
||||
self-expires-in: 7200
|
||||
# token key
|
||||
self_token_key: zy_token
|
||||
# token
|
||||
self_token_secret: eV3dT0oD7iX8rK4eC3jS6fU8cU5cS6mJ
|
||||
+28
-54
@@ -1,5 +1,6 @@
|
||||
package com.bsd.pjcloud.admin;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.bsd.pjcloud.thirdparty.ThirdPartyApp;
|
||||
import com.bsd.pjcloud.thirdparty.dto.zy.foreign.ZyForeignGetRegionIdByTokenDto;
|
||||
@@ -21,13 +22,16 @@ import com.bsd.pjcloud.thirdparty.vo.zy.mer.*;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.stride.ZyStrideAuthenticationVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.stride.ZyStrideConsumptionVo;
|
||||
import com.bsd.pjcloud.thirdparty.vo.zy.stride.ZyStrideCorrectVo;
|
||||
import io.undertow.security.idm.DigestAlgorithm;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SpringBootTest(classes = ThirdPartyApp.class)
|
||||
@@ -49,9 +53,9 @@ public class ZyTest {
|
||||
* 获取token
|
||||
*/
|
||||
@Test
|
||||
public void merGetTokenApi() {
|
||||
ZyMerGetTokenVo vo = zyApiTool.getTokenApi();
|
||||
System.out.println(vo);
|
||||
public void merGetTokenApi() throws Exception {
|
||||
String token = zyApiTool.getToken();
|
||||
System.out.println(token);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,15 +63,17 @@ public class ZyTest {
|
||||
*/
|
||||
@Test
|
||||
public void merSyncDealerInfo() {
|
||||
String currentIndex = String.valueOf(DateUtil.current());
|
||||
ZyMerSyncDealerInfoDto dto = ZyMerSyncDealerInfoDto
|
||||
.builder()
|
||||
.DealerKeyObj("123")
|
||||
.DealerName("食堂")
|
||||
.DealerKeyObj(currentIndex)
|
||||
.DealerName("食堂" + currentIndex)
|
||||
.IsValid(1)
|
||||
.EPID("1")
|
||||
.EPID("EPID" + currentIndex)
|
||||
.FixId("20190920100101")
|
||||
.build();
|
||||
ZyMerSyncDealerInfoVo vo = zyMerService.syncDealerInfoApi(dto);
|
||||
List<ZyMerSyncDealerInfoDto> list = List.of(dto);
|
||||
ZyMerSyncDealerInfoVo vo = zyMerService.syncDealerInfoApi(list);
|
||||
System.out.println(vo);
|
||||
}
|
||||
|
||||
@@ -121,8 +127,7 @@ public class ZyTest {
|
||||
*/
|
||||
@Test
|
||||
public void foreignGetRegionIdByToken() {
|
||||
ZyForeignGetRegionIdByTokenDto dto = new ZyForeignGetRegionIdByTokenDto();
|
||||
ZyForeignGetRegionIdByTokenVo vo = zyForeignService.getRegionIdByToken(dto);
|
||||
ZyForeignGetRegionIdByTokenVo.VoData vo = zyForeignService.getRegionIdByToken();
|
||||
System.out.println(vo);
|
||||
}
|
||||
|
||||
@@ -165,57 +170,26 @@ public class ZyTest {
|
||||
/************************** end stride end **************************/
|
||||
|
||||
@Test
|
||||
public void encryption() {
|
||||
try {
|
||||
public void encryption() throws Exception {
|
||||
// 第一步:组装业务数据
|
||||
String data = "{\"dealers\":[{\"EPID\": \"1\",\"DealerKeyObj\":\"123\",\"IsValid\":1,\"DealerName\":\"食堂\",\"FixId\":\"20190920100101\"}]}";
|
||||
|
||||
// 1. 构建业务数据
|
||||
Map<String, Object> dealer = new HashMap<>();
|
||||
dealer.put("EPID", "1");
|
||||
dealer.put("DealerKeyObj", "123");
|
||||
dealer.put("IsValid", 1);
|
||||
dealer.put("DealerName", "食堂");
|
||||
dealer.put("FixId", "20190920100101");
|
||||
// 第二步:进行 Base64 编码
|
||||
String encodedData = Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("dealers", new Object[]{dealer});
|
||||
|
||||
// 2. 生成 data 参数(Base64 编码)
|
||||
String jsonData = JSONUtil.toJsonStr(data);
|
||||
String base64Data = Base64.getEncoder().encodeToString(jsonData.getBytes("UTF-8"));
|
||||
|
||||
// 3. 生成签名
|
||||
String signStr = String.format("data=%s&key=%s", jsonData, "03D9608D1735D424F984733BA71321C6");
|
||||
String sign = md5(signStr).toUpperCase();
|
||||
|
||||
// 4. 构建请求参数
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("data", base64Data);
|
||||
params.put("sign", sign);
|
||||
System.out.println(params);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 输出结果
|
||||
System.out.println("Base64 Encoded Data: " + encodedData);
|
||||
}
|
||||
|
||||
// MD5 加密方法
|
||||
private static String md5(String input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] messageDigest = md.digest(input.getBytes());
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
|
||||
for (byte b : messageDigest) {
|
||||
String hex = Integer.toHexString(0xFF & b);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
|
||||
return hexString.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
private static String md5(String input) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : messageDigest) {
|
||||
sb.append(String.format("%02x", b));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user