Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
huang.tao
/
jmai-platform
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
76120359
authored
Jan 27, 2026
by
zhu.zewen
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
新增云签相关接口
parent
2c397c16
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
321 additions
and
191 deletions
config/application-dev.yaml
jmai-physic/src/main/java/com/jmai/physic/cloudsign/CloudsignService.java
jmai-physic/src/main/java/com/jmai/physic/cloudsign/GetCertInfoRequest.java
jmai-physic/src/main/java/com/jmai/physic/cloudsign/LoginBypinRequest.java
jmai-physic/src/main/java/com/jmai/physic/cloudsign/PinLoginRequest.java
jmai-physic/src/main/java/com/jmai/physic/cloudsign/QRCodeLoginRequest.java
jmai-physic/src/main/java/com/jmai/physic/cloudsign/SignDataRequest.java
jmai-physic/src/main/java/com/jmai/physic/config/CloudSignProperties.java
jmai-physic/src/main/java/com/jmai/physic/controller/CloudSignController.java
jmai-physic/src/main/java/com/jmai/physic/entity/CloudSignToken.java
jmai-physic/src/main/java/com/jmai/physic/mapper/CloudSignTokenMapper.java
config/application-dev.yaml
View file @
76120359
...
...
@@ -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
:
455
835303
testBusinessSystemCode
:
1
176
testBusinessSystemAppID
:
w
6qpjDk1WBSrFCfgcj
testBusinessOrgCode
:
455
755717
testBusinessSystemCode
:
1
801
testBusinessSystemAppID
:
w
4CcCkLuzszYADIOeI
#
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
# ################################################
# 交接单配置
# ################################################
...
...
jmai-physic/src/main/java/com/jmai/physic/cloudsign/CloudsignService.java
View file @
76120359
...
...
@@ -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
(
Genloginqrcode
Request
request
){
String
logTip
=
"
genLoginQrCode
"
;
public
QueryStatusResponse
queryStatus
(
QueryStatus
Request
request
){
String
logTip
=
"
queryStatus
"
;
String
json
=
OpenUtil
.
toJson
(
request
);
try
{
log
.
info
(
"{}-入参:
{}"
,
logTip
,
json
);
String
response
=
HttpUtils
.
sendPostRequestAndParse
(
buildUrl
(
cloudSignProperties
.
get
Genloginqrcode
Url
()),
json
,
null
);
log
.
info
(
"{}-返回数据:
{}"
,
logTip
,
response
);
log
.
info
(
"{}-入参:
{}"
,
logTip
,
json
);
String
response
=
HttpUtils
.
sendPostRequestAndParse
(
buildUrl
(
cloudSignProperties
.
get
Querystatus
Url
()),
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
e
xception
)
{
log
.
error
(
"
查询云签状态失败,e:{}"
,
exception
.
getMessage
()
);
throw
new
ServiceException
(
"
查询失败"
);
}
}
/**
* PIN码登录
*/
public
GenloginqrcodeRespon
pinLog
in
(
PinLoginRequest
request
){
public
GenloginqrcodeRespon
loginByP
in
(
PinLoginRequest
request
){
request
.
setLoginType
(
1
);
String
logTip
=
"
pinLog
in"
;
String
logTip
=
"
loginByP
in"
;
String
json
=
OpenUtil
.
toJson
(
request
);
try
{
log
.
info
(
"{}-入参:{}"
,
logTip
,
json
);
String
response
=
HttpUtils
.
sendPostRequestAndParse
(
buildUrl
(
cloudSignProperties
.
get
Pinlog
inUrl
()),
json
,
null
);
String
response
=
HttpUtils
.
sendPostRequestAndParse
(
buildUrl
(
cloudSignProperties
.
get
Loginbyp
inUrl
()),
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
(
QRCodeLogin
Request
request
){
String
logTip
=
"
qrCodeLogin
"
;
public
GenloginqrcodeRespon
genLoginQrcode
(
Genloginqrcode
Request
request
){
String
logTip
=
"
genLoginQrcode
"
;
String
json
=
OpenUtil
.
toJson
(
request
);
try
{
log
.
info
(
"{}-入参: {}"
,
logTip
,
json
);
String
response
=
HttpUtils
.
sendPostRequestAndParse
(
buildUrl
(
cloudSignProperties
.
get
Qrcodelogin
Url
()),
json
,
null
);
String
response
=
HttpUtils
.
sendPostRequestAndParse
(
buildUrl
(
cloudSignProperties
.
get
Genloginqrcode
Url
()),
json
,
null
);
log
.
info
(
"{}-返回数据: {}"
,
logTip
,
response
);
if
(
ObjectUtil
.
isEmpty
(
response
)){
throw
new
ServiceException
(
"获取失败"
);
}
QRCodeLoginResponse
qrCodeLoginResponse
=
JSON
.
parseObject
(
response
,
QRCodeLoginResponse
.
class
);
return
qrCodeLoginResponse
;
}
catch
(
Exception
e
xception
)
{
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
.
setBusinessSystemAppI
d
(
cloudSignProperties
.
getTestBusinessSystemAppId
());
request
.
setBusinessSystemAppI
D
(
cloudSignProperties
.
getTestBusinessSystemAppID
());
}
else
{
request
.
setBusinessOrgCode
(
cloudSignProperties
.
getBusinessOrgCode
());
request
.
setBusinessSystemCode
(
cloudSignProperties
.
getBusinessSystemCode
());
request
.
setBusinessSystemAppI
d
(
cloudSignProperties
.
getBusinessSystemAppld
());
request
.
setBusinessSystemAppI
D
(
cloudSignProperties
.
getBusinessSystemApplD
());
}
request
.
setBusinessTypeCode
(
"007"
);
request
.
setWithTsa
(
true
);
request
.
setEncryptedToken
(
encryptedToken
);
request
.
setBase64SourceData
(
base64SourceData
);
sign
d
ata
(
request
);
sign
D
ata
(
request
);
GetstampRequest
getstampRequest
=
new
GetstampRequest
();
getstampRequest
.
setRelBizNo
(
relBizNo
);
String
getstamp
=
get
s
tamp
(
getstampRequest
);
String
getstamp
=
get
S
tamp
(
getstampRequest
);
return
base64SourceData
;
}
...
...
@@ -122,7 +137,7 @@ public class CloudsignService {
* 云签证书数字签名
* @param request
*/
public
SignDataRespon
sign
d
ata
(
SignDataRequest
request
){
public
SignDataRespon
sign
D
ata
(
SignDataRequest
request
){
String
logTip
=
"signdata"
;
String
json
=
OpenUtil
.
toJson
(
request
);
try
{
...
...
@@ -145,7 +160,7 @@ public class CloudsignService {
* 获取手写签名图片
* @param request
*/
public
String
get
s
tamp
(
GetstampRequest
request
){
public
String
get
S
tamp
(
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
(
"查询失败"
);
}
}
}
jmai-physic/src/main/java/com/jmai/physic/cloudsign/GetCertInfoRequest.java
View file @
76120359
...
...
@@ -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
jmai-physic/src/main/java/com/jmai/physic/cloudsign/LoginBypinRequest.java
deleted
100644 → 0
View file @
2c397c16
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
;
}
jmai-physic/src/main/java/com/jmai/physic/cloudsign/PinLoginRequest.java
View file @
76120359
...
...
@@ -14,7 +14,7 @@ public class PinLoginRequest {
private
String
businessSystemCode
;
@ApiModelProperty
(
value
=
"业务系统应用 ID,业务系统的唯一标识号"
,
hidden
=
true
)
private
String
businessSystemAppI
d
;
private
String
businessSystemAppI
D
;
@ApiModelProperty
(
value
=
"医生工号(当前用户工号)"
,
hidden
=
true
)
private
String
relBizNo
;
...
...
jmai-physic/src/main/java/com/jmai/physic/cloudsign/QRCodeLoginRequest.java
View file @
76120359
...
...
@@ -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
jmai-physic/src/main/java/com/jmai/physic/cloudsign/SignDataRequest.java
View file @
76120359
...
...
@@ -13,7 +13,7 @@ public class SignDataRequest {
@ApiModelProperty
(
value
=
"深圳市CA业务系统编码,每个业务系统均有独立编码"
,
required
=
true
)
private
String
businessSystemCode
;
@ApiModelProperty
(
value
=
"业务系统应用ID,业务系统的唯一标识号"
,
required
=
true
)
private
String
businessSystemAppI
d
;
private
String
businessSystemAppI
D
;
@ApiModelProperty
(
value
=
"业务类型代码"
,
required
=
true
)
private
String
businessTypeCode
;
@ApiModelProperty
(
value
=
"加密令牌"
,
required
=
true
)
...
...
jmai-physic/src/main/java/com/jmai/physic/config/CloudSignProperties.java
View file @
76120359
...
...
@@ -27,7 +27,7 @@ public class CloudSignProperties {
/**
* 业务系统应用 ID,业务系统的唯一标识号
*/
private
String
businessSystemAppl
d
;
private
String
businessSystemAppl
D
;
/**
* 登录方式,1-PIN码认证
...
...
@@ -52,7 +52,7 @@ public class CloudSignProperties {
/**
* 测试用的业务系统应用ID
*/
private
String
testBusinessSystemAppI
d
=
"o7d7q8ehm4tkrc6o"
;
private
String
testBusinessSystemAppI
D
=
"o7d7q8ehm4tkrc6o"
;
/**
* 测试用的医生工号
...
...
@@ -72,45 +72,51 @@ public class CloudSignProperties {
/**
* PIN码登录接口
*/
private
String
pinlog
inUrl
=
"/v1.0/cloudsign/loginbypin"
;
private
String
loginbyp
inUrl
=
"/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"
;
}
jmai-physic/src/main/java/com/jmai/physic/controller/CloudSignController.java
View file @
76120359
...
...
@@ -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
.
getBusinessSystemAppl
d
());
queryStatusRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getBusinessSystemAppl
D
());
if
(
cloudSignProperties
.
getTestEnabled
())
{
queryStatusRequest
.
setBusinessOrgCode
(
cloudSignProperties
.
getTestBusinessOrgCode
());
queryStatusRequest
.
setBusinessSystemCode
(
cloudSignProperties
.
getTestBusinessSystemCode
());
queryStatusRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getTestBusinessSystemAppI
d
());
queryStatusRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getTestBusinessSystemAppI
D
());
}
else
{
queryStatusRequest
.
setBusinessOrgCode
(
cloudSignProperties
.
getBusinessOrgCode
());
queryStatusRequest
.
setBusinessSystemCode
(
cloudSignProperties
.
getBusinessSystemCode
());
queryStatusRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getBusinessSystemAppl
d
());
queryStatusRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getBusinessSystemAppl
D
());
}
QueryStatusResponse
queryStatus
=
cloudsignService
.
queryStatus
(
queryStatusRequest
);
...
...
@@ -70,39 +80,59 @@ public class CloudSignController {
if
(
cloudSignProperties
.
getTestEnabled
())
{
pinLoginRequest
.
setBusinessOrgCode
(
cloudSignProperties
.
getTestBusinessOrgCode
());
pinLoginRequest
.
setBusinessSystemCode
(
cloudSignProperties
.
getTestBusinessSystemCode
());
pinLoginRequest
.
setBusinessSystemAppI
d
(
cloudSignProperties
.
getTestBusinessSystemAppId
());
pinLoginRequest
.
setBusinessSystemAppI
D
(
cloudSignProperties
.
getTestBusinessSystemAppID
());
}
else
{
pinLoginRequest
.
setBusinessOrgCode
(
cloudSignProperties
.
getBusinessOrgCode
());
pinLoginRequest
.
setBusinessSystemCode
(
cloudSignProperties
.
getBusinessSystemCode
());
pinLoginRequest
.
setBusinessSystemAppI
d
(
cloudSignProperties
.
getBusinessSystemAppld
());
pinLoginRequest
.
setBusinessSystemAppI
D
(
cloudSignProperties
.
getBusinessSystemApplD
());
}
GenloginqrcodeRespon
pinLogin
=
cloudsignService
.
pinLog
in
(
pinLoginRequest
);
GenloginqrcodeRespon
pinLogin
=
cloudsignService
.
loginByP
in
(
pinLoginRequest
);
return
ResponseData
.
ok
(
pinLogin
);
}
@PostMapping
(
"/
loginBy
Qrcode"
)
@ApiOperation
(
value
=
"
二维码登录
"
)
public
ResponseData
<
QRCodeLoginResponse
>
loginByQrcode
(
@RequestBody
QRCodeLoginRequest
qrCodeLoginRequest
)
{
@PostMapping
(
"/
genLogin
Qrcode"
)
@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
);
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
);
}
}
QRCodeLoginResponse
qrCodeLogin
=
cloudsignService
.
qrCodeLogin
(
qrCodeLoginRequest
);
return
ResponseData
.
ok
(
qrCodeLogin
);
}
// 跳过认证
@AuthSkipped
@PostMapping
(
"/loginByQrcode/callback"
)
@ApiOperation
(
value
=
"二维码登录回调"
)
public
ResponseData
<
CloudSignCallbackResponse
>
loginByQrcodeCallback
(
@RequestBody
CloudSignCallbackRequest
callbackRequest
)
{
...
...
@@ -110,12 +140,58 @@ 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
();
...
...
@@ -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
.
getTestBusinessSystemAppI
d
());
getLoginResultRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getTestBusinessSystemAppI
D
());
}
else
{
getLoginResultRequest
.
setBusinessOrgCode
(
cloudSignProperties
.
getBusinessOrgCode
());
getLoginResultRequest
.
setBusinessSystemCode
(
cloudSignProperties
.
getBusinessSystemCode
());
getLoginResultRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getBusinessSystemAppl
d
());
getLoginResultRequest
.
setBusinessSystemAppID
(
cloudSignProperties
.
getBusinessSystemAppl
D
());
}
GetLoginResultResponse
getLoginResult
=
cloudsignService
.
getLoginResult
(
getLoginResultRequest
);
GetLoginResultResponse
getLoginResult
=
cloudsignService
.
getLogin
ByQrcode
Result
(
getLoginResultRequest
);
return
ResponseData
.
ok
(
getLoginResult
);
}
...
...
jmai-physic/src/main/java/com/jmai/physic/entity/CloudSignToken.java
0 → 100644
View file @
76120359
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
jmai-physic/src/main/java/com/jmai/physic/mapper/CloudSignTokenMapper.java
0 → 100644
View file @
76120359
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment