Commit 76120359 by zhu.zewen

新增云签相关接口

parent 2c397c16
......@@ -17,24 +17,6 @@ infynova:
# 后端下载地址
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:
# ################################################
# 仅测试用
cloudsign:
# 是否开启测试:true - 开启,false - 关闭(默认)
testEnabled: true
# 云签名服务基础地址
# 内网
# host: http://192.168.2.194:18087
# 公网测试
host: http://www.jztech.top:18087
# 公网测试:http://www.jztech.top:8088/
host: http://www.jztech.top:8088
# 是否开启测试:true - 开启,false - 关闭(默认)
testEnabled: true
# 生产
businessOrgCode: xxx
businessSystemCode: xxx
businessSystemAppID: xxx
# 测试
testBusinessOrgCode: 455835303
testBusinessSystemCode: 1176
testBusinessSystemAppID: w6qpjDk1WBSrFCfgcj
testBusinessOrgCode: 455755717
testBusinessSystemCode: 1801
testBusinessSystemAppID: w4CcCkLuzszYADIOeI
# API
# 云签API接口
# PIN码登录接口
pinloginUrl: /v1.0/cloudsign/loginbypin
# 生成登录二维码接口
genloginqrcodeUrl: /v1.0/cloudsign/genloginqrcode
# 二维码登录接口
qrcodeloginUrl: /v1.0/cloudsign/genloginqrcode
# 签名数据接口
signdataUrl: /v1.0/cloudsign/signdata
# 获取印章接口
......@@ -101,6 +82,9 @@ cloudsign:
# 验证数据接口
verifydataUrl: /v1.0/cloudsign/verify/data
# 云签回调接口
callbackUrl: /api/cloudsign/loginByQrcode/callback
# ################################################
# 交接单配置
# ################################################
......
......@@ -15,8 +15,6 @@ import javax.annotation.Resource;
@Slf4j
@Component
public class CloudsignService {
@Resource
private CloudSignProperties cloudSignProperties;
......@@ -25,39 +23,38 @@ public class CloudsignService {
}
/**
* 生成登录二维码
* 检查云签状态
* @param request
*/
public GenloginqrcodeRespon genLoginQrCode(GenloginqrcodeRequest request){
String logTip = "genLoginQrCode";
public QueryStatusResponse queryStatus(QueryStatusRequest request){
String logTip = "queryStatus";
String json = OpenUtil.toJson(request);
try {
log.info("{}-入参: {}", logTip, json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getGenloginqrcodeUrl()), json, null);
log.info("{}-返回数据: {}", logTip, response);
log.info("{}-入参:{}",logTip,json);
String response = HttpUtils.sendPostRequestAndParse(buildUrl(cloudSignProperties.getQuerystatusUrl()), json, null);
log.info("{}-返回数据:{}",logTip,response);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败");
throw new ServiceException("查询失败");
}
GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class);
return genloginqrcodeRespon;
} catch (Exception e) {
log.error("获取二维码失败:" + e.getMessage(), e);
throw new ServiceException("genLoginQrCode-获取二维码失败", e);
QueryStatusResponse queryStatusResponse = JSON.parseObject(response, QueryStatusResponse.class);
return queryStatusResponse;
} catch (Exception exception) {
log.error("查询云签状态失败,e:{}", exception.getMessage());
throw new ServiceException("查询失败");
}
}
/**
* PIN码登录
*/
public GenloginqrcodeRespon pinLogin(PinLoginRequest request){
public GenloginqrcodeRespon loginByPin(PinLoginRequest request){
request.setLoginType(1);
String logTip = "pinLogin";
String logTip = "loginByPin";
String json = OpenUtil.toJson(request);
try {
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);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败");
......@@ -65,56 +62,74 @@ public class CloudsignService {
GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class);
return genloginqrcodeRespon;
} catch (Exception e) {
log.error("获取令牌失败:"+e.getMessage(), e);
throw new ServiceException("pinLogin-获取令牌失败", e);
log.error("获取动态令牌失败:"+e.getMessage(), e);
throw new ServiceException("loginByPin-获取动态令牌失败", e);
}
}
/**
* 二维码登录
* 生成登录二维码
* @param request
*/
public QRCodeLoginResponse qrCodeLogin(QRCodeLoginRequest request){
String logTip = "qrCodeLogin";
public GenloginqrcodeRespon genLoginQrcode(GenloginqrcodeRequest request){
String logTip = "genLoginQrcode";
String json = OpenUtil.toJson(request);
try {
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);
if(ObjectUtil.isEmpty(response)){
throw new ServiceException("获取失败");
}
QRCodeLoginResponse qrCodeLoginResponse = JSON.parseObject(response, QRCodeLoginResponse.class);
return qrCodeLoginResponse;
} catch (Exception exception) {
log.error("获取二维码失败,e:{}", exception.getMessage());
throw new ServiceException("获取失败");
GenloginqrcodeRespon genloginqrcodeRespon = JSON.parseObject(response, GenloginqrcodeRespon.class);
return genloginqrcodeRespon;
} catch (Exception e) {
log.error("获取二维码失败:" + e.getMessage(), e);
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){
SignDataRequest request = new SignDataRequest();
if (cloudSignProperties.getTestEnabled()) {
request.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
request.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
request.setBusinessSystemAppId(cloudSignProperties.getTestBusinessSystemAppId());
request.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else {
request.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
request.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
request.setBusinessSystemAppId(cloudSignProperties.getBusinessSystemAppld());
request.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
}
request.setBusinessTypeCode("007");
request.setWithTsa(true);
request.setEncryptedToken(encryptedToken);
request.setBase64SourceData(base64SourceData);
signdata(request);
signData(request);
GetstampRequest getstampRequest = new GetstampRequest();
getstampRequest.setRelBizNo(relBizNo);
String getstamp = getstamp(getstampRequest);
String getstamp = getStamp(getstampRequest);
return base64SourceData;
}
......@@ -122,7 +137,7 @@ public class CloudsignService {
* 云签证书数字签名
* @param request
*/
public SignDataRespon signdata(SignDataRequest request){
public SignDataRespon signData(SignDataRequest request){
String logTip = "signdata";
String json = OpenUtil.toJson(request);
try {
......@@ -145,7 +160,7 @@ public class CloudsignService {
* 获取手写签名图片
* @param request
*/
public String getstamp(GetstampRequest request){
public String getStamp(GetstampRequest request){
String logTip = "getstamp";
String json = OpenUtil.toJson(request);
try {
......@@ -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编码证书
* @param request
*/
......@@ -232,26 +225,4 @@ public class CloudsignService {
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;
@Data
@ApiModel(value = "GetCertInfoRequest", description = "获取Base64编码证书请求参数")
public class GetCertInfoRequest {
@ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", required = true)
@ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", hidden = true)
private String businessOrgCode;
@ApiModelProperty(value = "云签账号", required = true)
@ApiModelProperty(value = "云签账号", hidden = true)
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 {
private String businessSystemCode;
@ApiModelProperty(value = "业务系统应用 ID,业务系统的唯一标识号", hidden = true)
private String businessSystemAppId;
private String businessSystemAppID;
@ApiModelProperty(value = "医生工号(当前用户工号)", hidden = true)
private String relBizNo;
......
......@@ -7,14 +7,14 @@ import lombok.Data;
@Data
@ApiModel(value = "QRCodeLoginRequest", description = "二维码登录请求参数")
public class QRCodeLoginRequest {
@ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", required = true)
@ApiModelProperty(value = "深圳市卫生计生组织机构代码,每个医院均有独立编码", hidden = true)
private String businessOrgCode;
@ApiModelProperty(value = "深圳市CA业务系统编码,每个业务系统均有独立编码", required = true)
@ApiModelProperty(value = "深圳市CA业务系统编码,每个业务系统均有独立编码", hidden = true)
private String businessSystemCode;
@ApiModelProperty(value = "业务系统应用ID,业务系统的唯一标识号", required = true)
@ApiModelProperty(value = "业务系统应用ID,业务系统的唯一标识号", hidden = true)
private String businessSystemAppID;
@ApiModelProperty(value = "通知回调地址")
@ApiModelProperty(value = "通知回调地址", hidden = true)
private String notifyUrl;
@ApiModelProperty(value = "二维码图片格式:1-JPG,2-PNG")
private Integer imageFormat;
@ApiModelProperty(value = "二维码图片格式:1-JPG,2-PNG", hidden = true)
private Integer imageFormat = 1;
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ public class SignDataRequest {
@ApiModelProperty(value = "深圳市CA业务系统编码,每个业务系统均有独立编码", required = true)
private String businessSystemCode;
@ApiModelProperty(value = "业务系统应用ID,业务系统的唯一标识号", required = true)
private String businessSystemAppId;
private String businessSystemAppID;
@ApiModelProperty(value = "业务类型代码", required = true)
private String businessTypeCode;
@ApiModelProperty(value = "加密令牌", required = true)
......
......@@ -27,7 +27,7 @@ public class CloudSignProperties {
/**
* 业务系统应用 ID,业务系统的唯一标识号
*/
private String businessSystemAppld;
private String businessSystemApplD;
/**
* 登录方式,1-PIN码认证
......@@ -52,7 +52,7 @@ public class CloudSignProperties {
/**
* 测试用的业务系统应用ID
*/
private String testBusinessSystemAppId = "o7d7q8ehm4tkrc6o";
private String testBusinessSystemAppID = "o7d7q8ehm4tkrc6o";
/**
* 测试用的医生工号
......@@ -72,45 +72,51 @@ public class CloudSignProperties {
/**
* 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 qrcodeloginUrl = "/v1.0/cloudsign/genloginqrcode";
/**
* 签名数据接口
* 签名数据接口 (接口编号: 304)
*/
private String signdataUrl = "/v1.0/cloudsign/signdata";
/**
* 获取印章接口
* 获取印章接口 (接口编号: 305)
*/
private String getstampUrl = "/v1.0/cloudsign/getstamp";
/**
* 查询用户令牌状态接口
* 查询用户令牌状态接口 (接口编号: 306)
*/
private String querystatusUrl = "/v1.0/cloudsign/usertoken/queryStatus";
/**
* 获取登录结果接口
* 3.3查询云签二维码扫码结果 (接口编号: 303)
*/
private String getloginresultUrl = "/v1.0/cloudsign/getLoginResult/web";
/**
* 获取证书信息接口
* 获取证书信息接口 (接口编号: 304)
*/
private String getcertinfoUrl = "/v1.0/cloudsign/getcertinfo";
/**
* 验证数据接口
* 验证数据接口 (接口编号: 305)
*/
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;
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.physic.cloudsign.*;
import com.jmai.physic.cloudsign.QRCodeLoginRequest;
import com.jmai.physic.cloudsign.QRCodeLoginResponse;
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.AuthSkipped;
import com.jmai.sys.ctx.SpringContextUtils;
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.ApiOperation;
import lombok.extern.slf4j.Slf4j;
......@@ -25,7 +35,7 @@ import javax.annotation.Resource;
@RestController
@RequestMapping("/cloudsign")
@Api(tags = "云签")
public class CloudSignController {
public class CloudSignController extends AbstractService {
@Resource
private CloudsignService cloudsignService;
@Resource
......@@ -41,16 +51,16 @@ public class CloudSignController {
queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemAppld());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
if (cloudSignProperties.getTestEnabled()) {
queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppId());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else {
queryStatusRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
queryStatusRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemAppld());
queryStatusRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemApplD());
}
QueryStatusResponse queryStatus = cloudsignService.queryStatus(queryStatusRequest);
......@@ -70,39 +80,59 @@ public class CloudSignController {
if (cloudSignProperties.getTestEnabled()) {
pinLoginRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
pinLoginRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
pinLoginRequest.setBusinessSystemAppId(cloudSignProperties.getTestBusinessSystemAppId());
pinLoginRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else {
pinLoginRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
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);
}
@PostMapping("/loginByQrcode")
@ApiOperation(value = "二维码登录")
public ResponseData<QRCodeLoginResponse> loginByQrcode(@RequestBody QRCodeLoginRequest qrCodeLoginRequest) {
@PostMapping("/genLoginQrcode")
@ApiOperation(value = "生成登录二维码")
public ResponseData<GenloginqrcodeRespon> genLoginQrcode(@RequestBody GenloginqrcodeRequest req) {
String workNo = SpringContextUtils.getWorkNo();
if (ObjectUtil.isEmpty(workNo)) {
throw new ServiceException("当前用户工号为空");
}
if (cloudSignProperties.getTestEnabled()) {
qrCodeLoginRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
qrCodeLoginRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
qrCodeLoginRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppId());
req.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
req.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
req.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else {
qrCodeLoginRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
qrCodeLoginRequest.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
qrCodeLoginRequest.setBusinessSystemAppID(cloudSignProperties.getBusinessSystemAppld());
req.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
req.setBusinessSystemCode(cloudSignProperties.getBusinessSystemCode());
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);
}
// 跳过认证
@AuthSkipped
@PostMapping("/loginByQrcode/callback")
@ApiOperation(value = "二维码登录回调")
public ResponseData<CloudSignCallbackResponse> loginByQrcodeCallback(@RequestBody CloudSignCallbackRequest callbackRequest) {
......@@ -110,13 +140,59 @@ public class CloudSignController {
callbackRequest.getClaimUuid(), callbackRequest.getLoginStatus(), callbackRequest.getRelBizNo());
try {
// 处理登录回调逻辑
// 这里可以根据登录状态更新用户登录状态或执行其他业务逻辑
// 示例逻辑:
// 1. 根据claimUuid找到对应的登录请求
// 2. 根据loginStatus处理不同状态(登录成功、失败、取消)
// 3. 如果登录成功,保存加密令牌encryptedToken供后续使用
// 1. 验证登录状态,只有登录成功(0)才继续处理
if (!"0".equals(callbackRequest.getLoginStatus())) {
log.warn("云签登录失败或被取消,loginStatus: {}", callbackRequest.getLoginStatus());
CloudSignCallbackResponse response = new CloudSignCallbackResponse();
response.setStatusCode(0); // 仍然返回成功状态,表示已接收到回调
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();
response.setStatusCode(0);
......@@ -127,13 +203,86 @@ public class CloudSignController {
log.error("处理云签登录回调失败", e);
CloudSignCallbackResponse response = new CloudSignCallbackResponse();
response.setStatusCode(-11);
response.setEventMsg("处理登录二维码请求失败, 系统异常.");
response.setEventMsg("处理登录二维码请求失败, 系统异常: " + e.getMessage());
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")
@ApiOperation(value = "查询二维码扫码结果")
@ApiOperation(value = "查询二维码登录结果")
public ResponseData<GetLoginResultResponse> getLoginByQrcodeResult(@RequestBody GetLoginResultRequest getLoginResultRequest) {
String workNo = SpringContextUtils.getWorkNo();
if (ObjectUtil.isEmpty(workNo)) {
......@@ -143,14 +292,14 @@ public class CloudSignController {
if (cloudSignProperties.getTestEnabled()) {
getLoginResultRequest.setBusinessOrgCode(cloudSignProperties.getTestBusinessOrgCode());
getLoginResultRequest.setBusinessSystemCode(cloudSignProperties.getTestBusinessSystemCode());
getLoginResultRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppId());
getLoginResultRequest.setBusinessSystemAppID(cloudSignProperties.getTestBusinessSystemAppID());
} else {
getLoginResultRequest.setBusinessOrgCode(cloudSignProperties.getBusinessOrgCode());
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);
}
......
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