Commit 76120359 by zhu.zewen

新增云签相关接口

parent 2c397c16
...@@ -17,24 +17,6 @@ infynova: ...@@ -17,24 +17,6 @@ infynova:
# 后端下载地址 # 后端下载地址
downloadUrl: http://${serverAddress}:38098/api/oss/downloadFile downloadUrl: http://${serverAddress}:38098/api/oss/downloadFile
# # ########################
# # IVS
# # ########################
# # FIXME:业务数据存储是否开启:true - 开启,false - 关闭(默认)
# bizDataStoreEnabled: false
# # 业务数据存储类型:空 - 不存储(默认),snapshot - 快照(直接恢复),view - 视图(按逻辑还原)
# bizDataStoreType:
# # FIXME:业务数据存储源:空 - 无需存储(默认),database - 数据库存储,thirdParty - 第三方存储
# bizDataStoreSource:
# # 允许删除本地数据库的业务单相关业务数据:true - 允许(仅测试用),false - 不允许(默认)
# deleteOrderInLocalEnabled: false
# ########################
# OPEN
# ########################
# 开启OpenAPI:true - 开启,false - 关闭(默认)
openapiEnabled: true
# ################################################ # ################################################
# 数据库 # 数据库
# ################################################ # ################################################
...@@ -64,30 +46,29 @@ mysql-bak: ...@@ -64,30 +46,29 @@ mysql-bak:
# ################################################ # ################################################
# 仅测试用 # 仅测试用
cloudsign: cloudsign:
# 是否开启测试:true - 开启,false - 关闭(默认)
testEnabled: true
# 云签名服务基础地址 # 云签名服务基础地址
# 内网 # 内网
# host: http://192.168.2.194:18087 # host: http://192.168.2.194:18087
# 公网测试 # 公网测试:http://www.jztech.top:8088/
host: http://www.jztech.top:18087 host: http://www.jztech.top:8088
# 是否开启测试:true - 开启,false - 关闭(默认)
testEnabled: true
# 生产 # 生产
businessOrgCode: xxx businessOrgCode: xxx
businessSystemCode: xxx businessSystemCode: xxx
businessSystemAppID: xxx businessSystemAppID: xxx
# 测试 # 测试
testBusinessOrgCode: 455835303 testBusinessOrgCode: 455755717
testBusinessSystemCode: 1176 testBusinessSystemCode: 1801
testBusinessSystemAppID: w6qpjDk1WBSrFCfgcj testBusinessSystemAppID: w4CcCkLuzszYADIOeI
# API # 云签API接口
# PIN码登录接口 # PIN码登录接口
pinloginUrl: /v1.0/cloudsign/loginbypin pinloginUrl: /v1.0/cloudsign/loginbypin
# 生成登录二维码接口 # 生成登录二维码接口
genloginqrcodeUrl: /v1.0/cloudsign/genloginqrcode genloginqrcodeUrl: /v1.0/cloudsign/genloginqrcode
# 二维码登录接口
qrcodeloginUrl: /v1.0/cloudsign/genloginqrcode
# 签名数据接口 # 签名数据接口
signdataUrl: /v1.0/cloudsign/signdata signdataUrl: /v1.0/cloudsign/signdata
# 获取印章接口 # 获取印章接口
...@@ -101,6 +82,9 @@ cloudsign: ...@@ -101,6 +82,9 @@ cloudsign:
# 验证数据接口 # 验证数据接口
verifydataUrl: /v1.0/cloudsign/verify/data verifydataUrl: /v1.0/cloudsign/verify/data
# 云签回调接口
callbackUrl: /api/cloudsign/loginByQrcode/callback
# ################################################ # ################################################
# 交接单配置 # 交接单配置
# ################################################ # ################################################
......
...@@ -15,8 +15,6 @@ import javax.annotation.Resource; ...@@ -15,8 +15,6 @@ import javax.annotation.Resource;
@Slf4j @Slf4j
@Component @Component
public class CloudsignService { public class CloudsignService {
@Resource @Resource
private CloudSignProperties cloudSignProperties; private CloudSignProperties cloudSignProperties;
...@@ -25,39 +23,38 @@ public class CloudsignService { ...@@ -25,39 +23,38 @@ public class CloudsignService {
} }
/** /**
* 生成登录二维码 * 检查云签状态
* @param request * @param request
*/ */
public GenloginqrcodeRespon genLoginQrCode(GenloginqrcodeRequest request){ public QueryStatusResponse queryStatus(QueryStatusRequest request){
String logTip = "genLoginQrCode"; String logTip = "queryStatus";
String json = OpenUtil.toJson(request); String json = OpenUtil.toJson(request);
try { try {
log.info("{}-入参: {}", logTip, json); log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getGenloginqrcodeUrl()), json, null); String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getQuerystatusUrl()), json, null);
log.info("{}-返回数据: {}", logTip, response); log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){ if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败"); throw new ServiceException("查询失败");
} }
GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class); QueryStatusResponse queryStatusResponse = JSON.parseObject(response, QueryStatusResponse.class);
return genloginqrcodeRespon; return queryStatusResponse;
} catch (Exception e) { } catch (Exception exception) {
log.error("获取二维码失败:" + e.getMessage(), e); log.error("查询云签状态失败,e:{}", exception.getMessage());
throw new ServiceException("genLoginQrCode-获取二维码失败", e); throw new ServiceException("查询失败");
} }
} }
/** /**
* PIN码登录 * PIN码登录
*/ */
public GenloginqrcodeRespon pinLogin(PinLoginRequest request){ public GenloginqrcodeRespon loginByPin(PinLoginRequest request){
request.setLoginType(1); request.setLoginType(1);
String logTip = "pinLogin"; String logTip = "loginByPin";
String json = OpenUtil.toJson(request); String json = OpenUtil.toJson(request);
try { try {
log.info("{}-入参:{}",logTip,json); log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getPinloginUrl()), json, null); String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getLoginbypinUrl()), json, null);
log.info("{}-返回数据: {}",logTip,response); log.info("{}-返回数据: {}",logTip,response);
if(ObjectUtil.isEmpty(response)){ if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败"); throw new ServiceException("获取失败");
...@@ -65,56 +62,74 @@ public class CloudsignService { ...@@ -65,56 +62,74 @@ public class CloudsignService {
GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class); GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class);
return genloginqrcodeRespon; return genloginqrcodeRespon;
} catch (Exception e) { } catch (Exception e) {
log.error("获取令牌失败:"+e.getMessage(), e); log.error("获取动态令牌失败:"+e.getMessage(), e);
throw new ServiceException("pinLogin-获取令牌失败", e); throw new ServiceException("loginByPin-获取动态令牌失败", e);
} }
} }
/** /**
* 二维码登录 * 生成登录二维码
* @param request * @param request
*/ */
public QRCodeLoginResponse qrCodeLogin(QRCodeLoginRequest request){ public GenloginqrcodeRespon genLoginQrcode(GenloginqrcodeRequest request){
String logTip = "qrCodeLogin"; String logTip = "genLoginQrcode";
String json = OpenUtil.toJson(request); String json = OpenUtil.toJson(request);
try { try {
log.info("{}-入参: {}", logTip, json); log.info("{}-入参: {}", logTip, json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getQrcodeloginUrl()), json, null); String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getGenloginqrcodeUrl()), json, null);
log.info("{}-返回数据: {}", logTip, response); log.info("{}-返回数据: {}", logTip, response);
if(ObjectUtil.isEmpty(response)){ if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败"); throw new ServiceException("获取失败");
} }
QRCodeLoginResponse qrCodeLoginResponse = JSON.parseObject(response, QRCodeLoginResponse.class); GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class);
return qrCodeLoginResponse; return genloginqrcodeRespon;
} catch (Exception exception) { } catch (Exception e) {
log.error("获取二维码失败,e:{}", exception.getMessage()); log.error("获取二维码失败:" + e.getMessage(), e);
throw new ServiceException("获取失败"); throw new ServiceException("genLoginQrcode-获取二维码失败", e);
} }
} }
/**
* 查询云签二维码扫码结果
* @param request
*/
public GetLoginResultResponse getLoginByQrcodeResult(GetLoginResultRequest request){
String logTip = "getLoginResult";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getGetloginresultUrl()), json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("查询失败");
}
GetLoginResultResponse getLoginResultResponse = JSON.parseObject(response, GetLoginResultResponse.class);
return getLoginResultResponse;
} catch (Exception exception) {
log.error("查询云签二维码扫码结果失败,e:{}", exception.getMessage());
throw new ServiceException("查询失败");
}
}
public String sign(String encryptedToken,String relBizNo,String base64SourceData){ public String sign(String encryptedToken,String relBizNo,String base64SourceData){
SignDataRequest request = new SignDataRequest(); SignDataRequest request = new SignDataRequest();
if (cloudSignProperties.getTestEnabled()) { if (cloudSignProperties.getTestEnabled()) {
request.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode()); request.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
request.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode()); request.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
request.setBusinessSystemAppId(cloudSignProperties.getTestBusinessSystemAppId()); request.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else { } else {
request.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode()); request.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
request.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode()); request.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
request.setBusinessSystemAppId(cloudSignProperties.getBusinessSystemAppld()); request.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
} }
request.setBusinessTypeCode("007"); request.setBusinessTypeCode("007");
request.setWithTsa(true); request.setWithTsa(true);
request.setEncryptedToken(encryptedToken); request.setEncryptedToken(encryptedToken);
request.setBase64SourceData(base64SourceData); request.setBase64SourceData(base64SourceData);
signdata(request); signData(request);
GetstampRequest getstampRequest = new GetstampRequest(); GetstampRequest getstampRequest = new GetstampRequest();
getstampRequest.setRelBizNo(relBizNo); getstampRequest.setRelBizNo(relBizNo);
String getstamp = getstamp(getstampRequest); String getstamp = getStamp(getstampRequest);
return base64SourceData; return base64SourceData;
} }
...@@ -122,7 +137,7 @@ public class CloudsignService { ...@@ -122,7 +137,7 @@ public class CloudsignService {
* 云签证书数字签名 * 云签证书数字签名
* @param request * @param request
*/ */
public SignDataRespon signdata(SignDataRequest request){ public SignDataRespon signData(SignDataRequest request){
String logTip = "signdata"; String logTip = "signdata";
String json = OpenUtil.toJson(request); String json = OpenUtil.toJson(request);
try { try {
...@@ -145,7 +160,7 @@ public class CloudsignService { ...@@ -145,7 +160,7 @@ public class CloudsignService {
* 获取手写签名图片 * 获取手写签名图片
* @param request * @param request
*/ */
public String getstamp(GetstampRequest request){ public String getStamp(GetstampRequest request){
String logTip = "getstamp"; String logTip = "getstamp";
String json = OpenUtil.toJson(request); String json = OpenUtil.toJson(request);
try { try {
...@@ -168,28 +183,6 @@ public class CloudsignService { ...@@ -168,28 +183,6 @@ public class CloudsignService {
} }
/** /**
* 检查云签状态
* @param request
*/
public QueryStatusResponse queryStatus(QueryStatusRequest request){
String logTip = "queryStatus";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getQuerystatusUrl()), json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("查询失败");
}
QueryStatusResponse queryStatusResponse = JSON.parseObject(response, QueryStatusResponse.class);
return queryStatusResponse;
} catch (Exception exception) {
log.error("查询云签状态失败,e:{}", exception.getMessage());
throw new ServiceException("查询失败");
}
}
/**
* 获取Base64编码证书 * 获取Base64编码证书
* @param request * @param request
*/ */
...@@ -232,26 +225,4 @@ public class CloudsignService { ...@@ -232,26 +225,4 @@ public class CloudsignService {
throw new ServiceException("验证失败"); throw new ServiceException("验证失败");
} }
} }
/**
* 查询云签二维码扫码结果
* @param request
*/
public GetLoginResultResponse getLoginResult(GetLoginResultRequest request){
String logTip = "getLoginResult";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getGetloginresultUrl()), json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("查询失败");
}
GetLoginResultResponse getLoginResultResponse = JSON.parseObject(response, GetLoginResultResponse.class);
return getLoginResultResponse;
} catch (Exception exception) {
log.error("查询云签二维码扫码结果失败,e:{}", exception.getMessage());
throw new ServiceException("查询失败");
}
}
} }
...@@ -7,9 +7,9 @@ import lombok.Data; ...@@ -7,9 +7,9 @@ import lombok.Data;
@Data @Data
@ApiModel(value = "GetCertInfoRequest", description = "获取Base64编码证书请求参数") @ApiModel(value = "GetCertInfoRequest", description = "获取Base64编码证书请求参数")
public class GetCertInfoRequest { public class GetCertInfoRequest {
@ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", required = true) @ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", hidden = true)
private String businessOrgCode; private String businessOrgCode;
@ApiModelProperty(value = "云签账号", required = true) @ApiModelProperty(value = "云签账号", hidden = true)
private String relBizNo; private String relBizNo;
} }
\ No newline at end of file
package com.jmai.physic.cloudsign;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "LoginBypinRequest", description = "PIN码登录请求参数")
public class LoginBypinRequest {
@ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", hidden = true)
private String businessOrgCode;
@ApiModelProperty(value = "深圳市 CA 业务系统编码,每个业务系统均有独立编码", hidden = true)
private String businessSystemCode;
@ApiModelProperty(value = "业务系统应用 ID,业务系统的唯一标识号", hidden = true)
private String businessSystemAppId;
@ApiModelProperty(value = "医生工号(当前用户工号)", hidden = true)
private String relBizNo;
@ApiModelProperty(value = "医生在业务系统输入的证书 PIN 码,进行 Base64 编码后的字符串。" +
"注意:云签数字证书申请成功后,医生手机上会收到 PIN 码,可通过云签 APP 进行修改。", required = true)
private String userEncodePin;
@ApiModelProperty(value = "登录方式,1 表示 PIN 码认证", required = true)
private Integer loginType;
}
...@@ -14,7 +14,7 @@ public class PinLoginRequest { ...@@ -14,7 +14,7 @@ public class PinLoginRequest {
private String businessSystemCode; private String businessSystemCode;
@ApiModelProperty(value = "业务系统应用 ID,业务系统的唯一标识号", hidden = true) @ApiModelProperty(value = "业务系统应用 ID,业务系统的唯一标识号", hidden = true)
private String businessSystemAppId; private String businessSystemAppID;
@ApiModelProperty(value = "医生工号(当前用户工号)", hidden = true) @ApiModelProperty(value = "医生工号(当前用户工号)", hidden = true)
private String relBizNo; private String relBizNo;
......
...@@ -7,14 +7,14 @@ import lombok.Data; ...@@ -7,14 +7,14 @@ import lombok.Data;
@Data @Data
@ApiModel(value = "QRCodeLoginRequest", description = "二维码登录请求参数") @ApiModel(value = "QRCodeLoginRequest", description = "二维码登录请求参数")
public class QRCodeLoginRequest { public class QRCodeLoginRequest {
@ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", required = true) @ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", hidden = true)
private String businessOrgCode; private String businessOrgCode;
@ApiModelProperty(value = "深圳市CA业务系统编码,每个业务系统均有独立编码", required = true) @ApiModelProperty(value = "深圳市CA业务系统编码,每个业务系统均有独立编码", hidden = true)
private String businessSystemCode; private String businessSystemCode;
@ApiModelProperty(value = "业务系统应用ID,业务系统的唯一标识号", required = true) @ApiModelProperty(value = "业务系统应用ID,业务系统的唯一标识号", hidden = true)
private String businessSystemAppID; private String businessSystemAppID;
@ApiModelProperty(value = "通知回调地址") @ApiModelProperty(value = "通知回调地址", hidden = true)
private String notifyUrl; private String notifyUrl;
@ApiModelProperty(value = "二维码图片格式:1-JPG,2-PNG") @ApiModelProperty(value = "二维码图片格式:1-JPG,2-PNG", hidden = true)
private Integer imageFormat; private Integer imageFormat = 1;
} }
\ No newline at end of file
...@@ -13,7 +13,7 @@ public class SignDataRequest { ...@@ -13,7 +13,7 @@ public class SignDataRequest {
@ApiModelProperty(value = "深圳市CA业务系统编码,每个业务系统均有独立编码", required = true) @ApiModelProperty(value = "深圳市CA业务系统编码,每个业务系统均有独立编码", required = true)
private String businessSystemCode; private String businessSystemCode;
@ApiModelProperty(value = "业务系统应用ID,业务系统的唯一标识号", required = true) @ApiModelProperty(value = "业务系统应用ID,业务系统的唯一标识号", required = true)
private String businessSystemAppId; private String businessSystemAppID;
@ApiModelProperty(value = "业务类型代码", required = true) @ApiModelProperty(value = "业务类型代码", required = true)
private String businessTypeCode; private String businessTypeCode;
@ApiModelProperty(value = "加密令牌", required = true) @ApiModelProperty(value = "加密令牌", required = true)
......
...@@ -27,7 +27,7 @@ public class CloudSignProperties { ...@@ -27,7 +27,7 @@ public class CloudSignProperties {
/** /**
* 业务系统应用 ID,业务系统的唯一标识号 * 业务系统应用 ID,业务系统的唯一标识号
*/ */
private String businessSystemAppld; private String businessSystemApplD;
/** /**
* 登录方式,1-PIN码认证 * 登录方式,1-PIN码认证
...@@ -52,7 +52,7 @@ public class CloudSignProperties { ...@@ -52,7 +52,7 @@ public class CloudSignProperties {
/** /**
* 测试用的业务系统应用ID * 测试用的业务系统应用ID
*/ */
private String testBusinessSystemAppId = "o7d7q8ehm4tkrc6o"; private String testBusinessSystemAppID = "o7d7q8ehm4tkrc6o";
/** /**
* 测试用的医生工号 * 测试用的医生工号
...@@ -72,45 +72,51 @@ public class CloudSignProperties { ...@@ -72,45 +72,51 @@ public class CloudSignProperties {
/** /**
* PIN码登录接口 * PIN码登录接口
*/ */
private String pinloginUrl = "/v1.0/cloudsign/loginbypin"; private String loginbypinUrl = "/v1.0/cloudsign/loginbypin";
/** /**
* 生成登录二维码接口 * 生成登录二维码接口 (接口编号: 301)
*/ */
private String genloginqrcodeUrl = "/v1.0/cloudsign/genloginqrcode"; private String genloginqrcodeUrl = "/v1.0/cloudsign/genloginqrcode";
/** /**
* 二维码登录接口 * 签名数据接口 (接口编号: 304)
*/
private String qrcodeloginUrl = "/v1.0/cloudsign/genloginqrcode";
/**
* 签名数据接口
*/ */
private String signdataUrl = "/v1.0/cloudsign/signdata"; private String signdataUrl = "/v1.0/cloudsign/signdata";
/** /**
* 获取印章接口 * 获取印章接口 (接口编号: 305)
*/ */
private String getstampUrl = "/v1.0/cloudsign/getstamp"; private String getstampUrl = "/v1.0/cloudsign/getstamp";
/** /**
* 查询用户令牌状态接口 * 查询用户令牌状态接口 (接口编号: 306)
*/ */
private String querystatusUrl = "/v1.0/cloudsign/usertoken/queryStatus"; private String querystatusUrl = "/v1.0/cloudsign/usertoken/queryStatus";
/** /**
* 获取登录结果接口 * 3.3查询云签二维码扫码结果 (接口编号: 303)
*/ */
private String getloginresultUrl = "/v1.0/cloudsign/getLoginResult/web"; private String getloginresultUrl = "/v1.0/cloudsign/getLoginResult/web";
/** /**
* 获取证书信息接口 * 获取证书信息接口 (接口编号: 304)
*/ */
private String getcertinfoUrl = "/v1.0/cloudsign/getcertinfo"; private String getcertinfoUrl = "/v1.0/cloudsign/getcertinfo";
/** /**
* 验证数据接口 * 验证数据接口 (接口编号: 305)
*/ */
private String verifydataUrl = "/v1.0/cloudsign/verify/data"; private String verifydataUrl = "/v1.0/cloudsign/verify/data";
//=========================================
/**
* 回调接口(云签 -> JMAI)
*/
private String callbackUrl = "/api/cloudsign/loginByQrcode/callback";
/**
* 二维码图片保存路径
*/
private String qrCodeSavePath = "D:/jmai/cloudsign";
} }
...@@ -2,14 +2,24 @@ package com.jmai.physic.controller; ...@@ -2,14 +2,24 @@ package com.jmai.physic.controller;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jmai.api.exception.ServiceException; import com.jmai.api.exception.ServiceException;
import com.jmai.physic.cloudsign.*; import com.jmai.physic.cloudsign.*;
import com.jmai.physic.cloudsign.QRCodeLoginRequest;
import com.jmai.physic.cloudsign.QRCodeLoginResponse;
import com.jmai.physic.config.CloudSignProperties; import com.jmai.physic.config.CloudSignProperties;
import com.jmai.physic.entity.CloudSignToken;
import com.jmai.physic.mapper.CloudSignTokenMapper;
import com.jmai.sys.AbstractService;
import com.jmai.sys.aop.Auth; import com.jmai.sys.aop.Auth;
import com.jmai.sys.aop.AuthSkipped;
import com.jmai.sys.ctx.SpringContextUtils; import com.jmai.sys.ctx.SpringContextUtils;
import com.jmai.sys.dto.ResponseData; import com.jmai.sys.dto.ResponseData;
import com.jmai.sys.dto.UserDto;
import com.jmai.sys.service.BaseService;
import com.jmai.sys.service.UserService;
import java.time.LocalDateTime;
import java.util.Optional;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -25,7 +35,7 @@ import javax.annotation.Resource; ...@@ -25,7 +35,7 @@ import javax.annotation.Resource;
@RestController @RestController
@RequestMapping("/cloudsign") @RequestMapping("/cloudsign")
@Api(tags = "云签") @Api(tags = "云签")
public class CloudSignController { public class CloudSignController extends AbstractService {
@Resource @Resource
private CloudsignService cloudsignService; private CloudsignService cloudsignService;
@Resource @Resource
...@@ -41,16 +51,16 @@ public class CloudSignController { ...@@ -41,16 +51,16 @@ public class CloudSignController {
queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode()); queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode()); queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemAppld()); queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
if (cloudSignProperties.getTestEnabled()) { if (cloudSignProperties.getTestEnabled()) {
queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode()); queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode()); queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppId()); queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else { } else {
queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode()); queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode()); queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemAppld()); queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
} }
QueryStatusResponse queryStatus = cloudsignService.queryStatus(queryStatusRequest); QueryStatusResponse queryStatus = cloudsignService.queryStatus(queryStatusRequest);
...@@ -70,39 +80,59 @@ public class CloudSignController { ...@@ -70,39 +80,59 @@ public class CloudSignController {
if (cloudSignProperties.getTestEnabled()) { if (cloudSignProperties.getTestEnabled()) {
pinLoginRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode()); pinLoginRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
pinLoginRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode()); pinLoginRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
pinLoginRequest.setBusinessSystemAppId(cloudSignProperties.getTestBusinessSystemAppId()); pinLoginRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else { } else {
pinLoginRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode()); pinLoginRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
pinLoginRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode()); pinLoginRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
pinLoginRequest.setBusinessSystemAppId(cloudSignProperties.getBusinessSystemAppld()); pinLoginRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
} }
GenloginqrcodeRespon pinLogin = cloudsignService.pinLogin(pinLoginRequest); GenloginqrcodeRespon pinLogin = cloudsignService.loginByPin(pinLoginRequest);
return ResponseData.ok(pinLogin); return ResponseData.ok(pinLogin);
} }
@PostMapping("/loginByQrcode") @PostMapping("/genLoginQrcode")
@ApiOperation(value = "二维码登录") @ApiOperation(value = "生成登录二维码")
public ResponseData<QRCodeLoginResponse> loginByQrcode(@RequestBody QRCodeLoginRequest qrCodeLoginRequest) { public ResponseData<GenloginqrcodeRespon> genLoginQrcode(@RequestBody GenloginqrcodeRequest req) {
String workNo = SpringContextUtils.getWorkNo(); String workNo = SpringContextUtils.getWorkNo();
if (ObjectUtil.isEmpty(workNo)) { if (ObjectUtil.isEmpty(workNo)) {
throw new ServiceException("当前用户工号为空"); throw new ServiceException("当前用户工号为空");
} }
if (cloudSignProperties.getTestEnabled()) { if (cloudSignProperties.getTestEnabled()) {
qrCodeLoginRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode()); req.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
qrCodeLoginRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode()); req.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
qrCodeLoginRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppId()); req.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else { } else {
qrCodeLoginRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode()); req.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
qrCodeLoginRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode()); req.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
qrCodeLoginRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemAppld()); req.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
} }
req.setNotifyUrl(cloudSignProperties.getCallbackUrl());
req.setImageFormat(1);
QRCodeLoginResponse qrCodeLogin = cloudsignService.qrCodeLogin(qrCodeLoginRequest); GenloginqrcodeRespon qrCodeLogin = cloudsignService.genLoginQrcode(req);
// 如果二维码生成成功,保存二维码图片到本地
if (qrCodeLogin.getStatusCode() == 0 && qrCodeLogin.getEventValue() != null
&& qrCodeLogin.getEventValue().getQRCodeBase64() != null) {
try {
String base64Image = qrCodeLogin.getEventValue().getQRCodeBase64();
Long userId = SpringContextUtils.getUserId();
String savedFilePath = saveQRCodeImage(base64Image, userId);
if (savedFilePath != null) {
log.info("二维码图片已保存,用户ID: {}, 文件路径: {}", userId, savedFilePath);
}
} catch (Exception e) {
log.error("保存二维码图片失败: {}", e.getMessage(), e);
}
}
return ResponseData.ok(qrCodeLogin); return ResponseData.ok(qrCodeLogin);
} }
// 跳过认证
@AuthSkipped
@PostMapping("/loginByQrcode/callback") @PostMapping("/loginByQrcode/callback")
@ApiOperation(value = "二维码登录回调") @ApiOperation(value = "二维码登录回调")
public ResponseData<CloudSignCallbackResponse> loginByQrcodeCallback(@RequestBody CloudSignCallbackRequest callbackRequest) { public ResponseData<CloudSignCallbackResponse> loginByQrcodeCallback(@RequestBody CloudSignCallbackRequest callbackRequest) {
...@@ -110,13 +140,59 @@ public class CloudSignController { ...@@ -110,13 +140,59 @@ public class CloudSignController {
callbackRequest.getClaimUuid(), callbackRequest.getLoginStatus(), callbackRequest.getRelBizNo()); callbackRequest.getClaimUuid(), callbackRequest.getLoginStatus(), callbackRequest.getRelBizNo());
try { try {
// 处理登录回调逻辑 // 1. 验证登录状态,只有登录成功(0)才继续处理
// 这里可以根据登录状态更新用户登录状态或执行其他业务逻辑 if (!"0".equals(callbackRequest.getLoginStatus())) {
// 示例逻辑: log.warn("云签登录失败或被取消,loginStatus: {}", callbackRequest.getLoginStatus());
// 1. 根据claimUuid找到对应的登录请求 CloudSignCallbackResponse response = new CloudSignCallbackResponse();
// 2. 根据loginStatus处理不同状态(登录成功、失败、取消) response.setStatusCode(0); // 仍然返回成功状态,表示已接收到回调
// 3. 如果登录成功,保存加密令牌encryptedToken供后续使用 response.setEventMsg("登录失败或已取消,不进行后续处理.");
return ResponseData.ok(response);
}
// 2. 根据relBizNo(云签账号)校验是否存在对应工号的用户
String relBizNo = callbackRequest.getRelBizNo();
if (ObjectUtil.isEmpty(relBizNo)) {
log.error("云签回调中relBizNo为空");
CloudSignCallbackResponse response = new CloudSignCallbackResponse();
response.setStatusCode(-11);
response.setEventMsg("云签账号为空,无法处理登录.");
return ResponseData.ok(response);
}
// 3. 查找系统中是否存在对应工号的用户
UserService userService = SpringContextUtils.getBean(UserService.class);
Optional<UserDto> userOpt = userService.getUserByWorkNo(relBizNo);
if (!userOpt.isPresent()) {
log.error("未找到工号为 {} 的用户", relBizNo);
CloudSignCallbackResponse response = new CloudSignCallbackResponse();
response.setStatusCode(-11);
response.setEventMsg("未找到对应工号的用户,登录失败.");
return ResponseData.ok(response);
}
UserDto user = userOpt.get();
// 4. 验证用户状态是否正常
if (user.getStatus() != null && user.getStatus().equals(0)) { // 假设0表示禁用状态
log.error("用户 {} 已被禁用,无法登录", user.getUserName());
CloudSignCallbackResponse response = new CloudSignCallbackResponse();
response.setStatusCode(-11);
response.setEventMsg("用户已被禁用,登录失败.");
return ResponseData.ok(response);
}
// 5. 如果登录成功且用户存在,生成并保存用户Token
String encryptedToken = callbackRequest.getEncryptedToken();
if (ObjectUtil.isEmpty(encryptedToken)) {
log.warn("登录成功但encryptedToken为空,可能影响后续签名操作");
}
// 保存云签令牌信息
saveCloudSignToken(user, encryptedToken);
log.info("云签登录成功,用户ID: {}, 工号: {}, 用户名: {}", user.getUserId(), user.getWorkNo(), user.getUserName());
// 构造响应 // 构造响应
CloudSignCallbackResponse response = new CloudSignCallbackResponse(); CloudSignCallbackResponse response = new CloudSignCallbackResponse();
response.setStatusCode(0); response.setStatusCode(0);
...@@ -127,13 +203,86 @@ public class CloudSignController { ...@@ -127,13 +203,86 @@ public class CloudSignController {
log.error("处理云签登录回调失败", e); log.error("处理云签登录回调失败", e);
CloudSignCallbackResponse response = new CloudSignCallbackResponse(); CloudSignCallbackResponse response = new CloudSignCallbackResponse();
response.setStatusCode(-11); response.setStatusCode(-11);
response.setEventMsg("处理登录二维码请求失败, 系统异常."); response.setEventMsg("处理登录二维码请求失败, 系统异常: " + e.getMessage());
return ResponseData.ok(response); return ResponseData.ok(response);
} }
} }
/**
* 将Base64编码的二维码图片保存到本地
* @param base64Image Base64编码的图片数据
* @param userId 用户ID,用于生成唯一的文件名
* @return 保存的文件路径
*/
private String saveQRCodeImage(String base64Image, Long userId) {
if (cn.hutool.core.util.StrUtil.isBlank(base64Image)) {
log.warn("二维码图片数据为空,无法保存");
return null;
}
try {
// 解码Base64数据
byte[] imageBytes = java.util.Base64.getDecoder().decode(base64Image);
// 创建BufferedImage对象
java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream(imageBytes);
javax.imageio.ImageIO.write(javax.imageio.ImageIO.read(bis), "jpg", new java.io.File(getQRCodeSavePath(userId)));
bis.close();
String filePath = getQRCodeSavePath(userId);
log.info("二维码图片已保存至: {}", filePath);
return filePath;
} catch (Exception e) {
log.error("保存二维码图片失败: {}", e.getMessage(), e);
return null;
}
}
/**
* 获取二维码保存路径
* @param userId 用户ID
* @return 保存路径
*/
private String getQRCodeSavePath(Long userId) {
String saveDir = cloudSignProperties.getQrCodeSavePath();
if (StrUtil.isBlank(saveDir)) {
// 如果配置中没有指定路径,则使用默认路径
saveDir = System.getProperty("user.home") + java.io.File.separator + ".jmai-platform" + java.io.File.separator + "qrcodes";
}
// 创建目录(如果不存在)
cn.hutool.core.io.FileUtil.mkdir(saveDir);
// 生成唯一的文件名(使用用户ID和雪花算法ID)
String fileName = "qrcode_" + userId + "_" + nextId() + ".jpg";
return saveDir + java.io.File.separator + fileName;
}
/**
* 保存云签令牌信息到数据库
*/
private void saveCloudSignToken(UserDto user, String encryptedToken) {
// 创建云签令牌信息并保存到数据库
CloudSignToken cloudSignToken = new CloudSignToken();
cloudSignToken.setUserId(user.getUserId());
cloudSignToken.setWorkNo(user.getWorkNo());
cloudSignToken.setEncryptedToken(encryptedToken);
// 设置令牌过期时间为当前时间加上默认有效期(例如2小时)
cloudSignToken.setExpiryTime(LocalDateTime.now().plusHours(2));
cloudSignToken.setStatus(1); // 设置为有效状态
// 保存到数据库
CloudSignTokenMapper cloudSignTokenMapper = SpringContextUtils.getBean(CloudSignTokenMapper.class);
// 先尝试删除旧的令牌记录(如果有)
cloudSignTokenMapper.delete(Wrappers.<CloudSignToken>lambdaUpdate()
.eq(CloudSignToken::getUserId, user.getUserId()));
// 插入新的令牌记录
cloudSignTokenMapper.insert(cloudSignToken);
}
@PostMapping("/getLoginByQrcodeResult") @PostMapping("/getLoginByQrcodeResult")
@ApiOperation(value = "查询二维码扫码结果") @ApiOperation(value = "查询二维码登录结果")
public ResponseData<GetLoginResultResponse> getLoginByQrcodeResult(@RequestBody GetLoginResultRequest getLoginResultRequest) { public ResponseData<GetLoginResultResponse> getLoginByQrcodeResult(@RequestBody GetLoginResultRequest getLoginResultRequest) {
String workNo = SpringContextUtils.getWorkNo(); String workNo = SpringContextUtils.getWorkNo();
if (ObjectUtil.isEmpty(workNo)) { if (ObjectUtil.isEmpty(workNo)) {
...@@ -143,14 +292,14 @@ public class CloudSignController { ...@@ -143,14 +292,14 @@ public class CloudSignController {
if (cloudSignProperties.getTestEnabled()) { if (cloudSignProperties.getTestEnabled()) {
getLoginResultRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode()); getLoginResultRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
getLoginResultRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode()); getLoginResultRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
getLoginResultRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppId()); getLoginResultRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else { } else {
getLoginResultRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode()); getLoginResultRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
getLoginResultRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode()); getLoginResultRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
getLoginResultRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemAppld()); getLoginResultRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
} }
GetLoginResultResponse getLoginResult = cloudsignService.getLoginResult(getLoginResultRequest); GetLoginResultResponse getLoginResult = cloudsignService.getLoginByQrcodeResult(getLoginResultRequest);
return ResponseData.ok(getLoginResult); return ResponseData.ok(getLoginResult);
} }
......
package com.jmai.physic.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.jmai.sys.entity.BaseVersionEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 云签令牌信息表
*/
@Data
@ApiModel(description = "云签令牌信息")
@TableName("cloud_sign_token")
public class CloudSignToken extends BaseVersionEntity {
@ApiModelProperty(value = "用户ID")
private Long userId;
@ApiModelProperty(value = "工号")
private String workNo;
@ApiModelProperty(value = "加密令牌,用于登录后的CA签名等操作使用")
private String encryptedToken;
@ApiModelProperty(value = "令牌过期时间")
private LocalDateTime expiryTime;
@ApiModelProperty(value = "状态:0-失效,1-有效")
private Integer status;
}
\ No newline at end of file
package com.jmai.physic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jmai.physic.entity.CloudSignToken;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CloudSignTokenMapper extends BaseMapper<CloudSignToken> {
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment