Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cnooc_zydeepen-cggl_expert-manage-miniapp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙德龙
cnooc_zydeepen-cggl_expert-manage-miniapp
Commits
4baf314d
Commit
4baf314d
authored
Nov 13, 2025
by
kenzo
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
http://git.gdatac.com/sundelong/cnooc_zydeepen-cggl_expert-manage-miniapp
parents
5d1960cb
8143c904
Show whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
1909 additions
and
12 deletions
+1909
-12
pom.xml
+42
-0
src/main/java/com/cnooc/expert/auth/service/LoginService.java
+15
-0
src/main/java/com/cnooc/expert/auth/service/SmsService.java
+28
-0
src/main/java/com/cnooc/expert/auth/service/SysCaptchaService.java
+27
-0
src/main/java/com/cnooc/expert/auth/service/Test.java
+4
-0
src/main/java/com/cnooc/expert/auth/service/impl/LoginServiceImpl.java
+240
-0
src/main/java/com/cnooc/expert/auth/service/impl/SmsServiceImpl.java
+153
-0
src/main/java/com/cnooc/expert/auth/service/impl/SysCaptchaServiceImpl.java
+80
-0
src/main/java/com/cnooc/expert/common/cache/RedisKeys.java
+28
-0
src/main/java/com/cnooc/expert/common/constant/TokenConstants.java
+36
-0
src/main/java/com/cnooc/expert/common/crypto/Sm3PasswordEncoder.java
+22
-0
src/main/java/com/cnooc/expert/common/exception/BusinessException.java
+140
-6
src/main/java/com/cnooc/expert/common/exception/GlobalExceptionHandler.java
+8
-6
src/main/java/com/cnooc/expert/common/interceptor/LoginInterceptor.java
+76
-0
src/main/java/com/cnooc/expert/common/utils/AesUtil.java
+131
-0
src/main/java/com/cnooc/expert/common/utils/CommonUtil.java
+97
-0
src/main/java/com/cnooc/expert/common/utils/JsonUtils.java
+77
-0
src/main/java/com/cnooc/expert/common/utils/JwtUtils.java
+71
-0
src/main/java/com/cnooc/expert/common/utils/RestUtils.java
+56
-0
src/main/java/com/cnooc/expert/common/utils/Sm2Util.java
+82
-0
src/main/java/com/cnooc/expert/common/utils/SmsHttpUtil.java
+33
-0
src/main/java/com/cnooc/expert/common/utils/SmsUtil.java
+85
-0
src/main/java/com/cnooc/expert/common/utils/UserUtils.java
+36
-0
src/main/java/com/cnooc/expert/common/utils/ValidUtils.java
+94
-0
src/main/java/com/cnooc/expert/config/PasswordConfig.java
+20
-0
src/main/java/com/cnooc/expert/config/TheWebMvcConfigurer.java
+16
-0
src/main/java/com/cnooc/expert/external/expert/api/LoginServiceApi.java
+15
-0
src/main/java/com/cnooc/expert/external/expert/auth/service/LoginServicesClient.java
+34
-0
src/main/java/com/cnooc/expert/external/expert/auth/service/Test.java
+4
-0
src/main/java/com/cnooc/expert/system/entity/pojo/ZhuanJiaUser.java
+40
-0
src/main/java/com/cnooc/expert/system/entity/vo/LoginVO.java
+40
-0
src/main/java/com/cnooc/expert/system/entity/vo/SmsConfig.java
+20
-0
src/main/java/com/cnooc/expert/system/entity/vo/SysCaptchaVO.java
+16
-0
src/main/java/com/cnooc/expert/system/entity/vo/VerifyCodeVO.java
+18
-0
src/main/java/com/cnooc/expert/system/entity/vo/ZhuanJiaInfoAppVo.java
+12
-0
src/main/java/com/cnooc/expert/system/entity/vo/ZhuanJiaInfoVo.java
+13
-0
No files found.
pom.xml
View file @
4baf314d
...
@@ -53,6 +53,18 @@
...
@@ -53,6 +53,18 @@
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
fastjson
</artifactId>
<version>
2.0.7
</version>
</dependency>
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
<version>
0.9.1
</version>
</dependency>
<dependency>
<groupId>
org.apache.commons
</groupId>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<artifactId>
commons-lang3
</artifactId>
<version>
3.18.0
</version>
<version>
3.18.0
</version>
...
@@ -70,6 +82,36 @@
...
@@ -70,6 +82,36 @@
<version>
32.0.1-android
</version>
<version>
32.0.1-android
</version>
</dependency>
</dependency>
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-crypto
</artifactId>
<version>
5.7.3
</version>
</dependency>
<dependency>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-all
</artifactId>
<version>
5.8.36
</version>
</dependency>
<dependency>
<groupId>
commons-codec
</groupId>
<artifactId>
commons-codec
</artifactId>
<version>
1.17.1
</version>
</dependency>
<dependency>
<groupId>
org.bouncycastle
</groupId>
<artifactId>
bcprov-jdk15to18
</artifactId>
<version>
1.69
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-validation
</artifactId>
</dependency>
<dependency>
<groupId>
com.github.whvcse
</groupId>
<artifactId>
easy-captcha
</artifactId>
<version>
1.6.2
</version>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
src/main/java/com/cnooc/expert/auth/service/LoginService.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
auth
.
service
;
import
com.cnooc.expert.system.entity.vo.LoginVO
;
import
com.cnooc.expert.system.entity.vo.VerifyCodeVO
;
public
interface
LoginService
{
String
login
(
LoginVO
loginVO
);
String
sendPhoneCode
(
LoginVO
vo
);
String
changePass
(
LoginVO
loginVO
);
String
verifyCode
(
VerifyCodeVO
codeVO
);
}
src/main/java/com/cnooc/expert/auth/service/SmsService.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
auth
.
service
;
public
interface
SmsService
{
/**
* 校验短信验证码
*
* @param phone 手机号
* @param code 验证码
* @return 是否校验通过
*/
boolean
verifySmsCode
(
String
phone
,
String
code
);
/**
* 发送短信验证码
*
* @param phone 手机号
* @return 是否发送成功
*/
boolean
sendSmsCode
(
String
phone
);
boolean
sendMasSmsCode
(
String
phone
);
boolean
sendMasSmsContent
(
String
phone
,
String
content
);
void
asyncSendMasSmsContent
(
String
phone
,
String
content
);
}
src/main/java/com/cnooc/expert/auth/service/SysCaptchaService.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
auth
.
service
;
import
com.cnooc.expert.system.entity.vo.SysCaptchaVO
;
public
interface
SysCaptchaService
{
/**
* 生成验证码
* @return 验证码captcha vo
*/
SysCaptchaVO
generate
();
/**
* 验证码效验
*
* @param key key
* @param code 验证码
* @return true:成功 false:失败
*/
boolean
validate
(
String
key
,
String
code
);
/**
* 是否开启登录验证码
*
* @return true:开启 false:关闭
*/
boolean
isCaptchaEnabled
();
}
src/main/java/com/cnooc/expert/auth/service/Test.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
auth
.
service
;
public
class
Test
{
}
src/main/java/com/cnooc/expert/auth/service/impl/LoginServiceImpl.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
auth
.
service
.
impl
;
import
cn.hutool.core.lang.Validator
;
import
cn.hutool.core.util.IdcardUtil
;
import
com.cnooc.expert.common.constant.TokenConstants
;
import
com.cnooc.expert.common.exception.BusinessException
;
import
com.cnooc.expert.common.utils.JwtUtils
;
import
com.cnooc.expert.common.utils.Sm2Util
;
import
com.cnooc.expert.common.utils.ValidUtils
;
import
com.cnooc.expert.external.expert.auth.service.LoginServicesClient
;
import
com.cnooc.expert.system.entity.vo.LoginVO
;
import
com.cnooc.expert.system.entity.vo.VerifyCodeVO
;
import
com.cnooc.expert.system.entity.vo.ZhuanJiaInfoAppVo
;
import
com.cnooc.expert.system.entity.vo.ZhuanJiaInfoVo
;
import
com.cnooc.expert.auth.service.LoginService
;
import
com.cnooc.expert.auth.service.SmsService
;
import
com.cnooc.expert.auth.service.SysCaptchaService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.stereotype.Service
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
java.time.Duration
;
import
java.util.UUID
;
/**
* @Author: songYuHang
* @CreateTime: 2025-09-18 15:23
*/
@Service
@Slf4j
public
class
LoginServiceImpl
implements
LoginService
{
@Autowired
private
StringRedisTemplate
redisTemplate
;
@Autowired
private
SmsService
smsService
;
@Autowired
private
SysCaptchaService
sysCaptchaService
;
@Autowired
private
PasswordEncoder
passwordEncoder
;
@Autowired
private
LoginServicesClient
loginServicesClient
;
/** 身份证密码登录 */
private
static
final
int
ID_NUMBER_PASSWORD
=
1
;
/** 手机验证码登录 */
private
static
final
int
PHONE_CODE
=
2
;
/**
* 登录逻辑
* @param loginVO 登录
* @return Result<String> token
*/
@Override
public
String
login
(
LoginVO
loginVO
)
{
log
.
info
(
"开始执行登录逻辑"
);
String
token
;
switch
(
loginVO
.
getLoginType
())
{
case
ID_NUMBER_PASSWORD:
token
=
idNumberLogin
(
loginVO
);
break
;
case
PHONE_CODE:
token
=
phoneCodeLogin
(
loginVO
);
break
;
default
:
throw
new
BusinessException
(
"请选择登录类型"
);
}
return
token
;
}
/**
* 获取验证码逻辑
* @param vo 手机号等信息
* @return Result<String> token
*/
@Override
public
String
sendPhoneCode
(
LoginVO
vo
)
{
log
.
info
(
"开始执行获取验证码逻辑"
);
ValidUtils
.
isText
(
vo
.
getPhoneNumber
(),
"请输入手机号"
);
ValidUtils
.
isTrue
(
Validator
.
isMobile
(
vo
.
getPhoneNumber
()),
"请输入正确的手机号"
);
//待确认,验证码下发是调用第三方平台吗
//return Result.success("验证码已发送");
boolean
flag
=
sysCaptchaService
.
validate
(
vo
.
getKey
(),
vo
.
getCaptcha
());
if
(!
flag
){
return
"验证码错误"
;
}
else
{
boolean
smsfalg
=
smsService
.
sendSmsCode
(
vo
.
getPhoneNumber
());
if
(!
smsfalg
)
{
return
"短信验证码发送失败"
;
}
else
{
return
"短信验证码发送成功"
;
}
}
}
@Override
public
String
changePass
(
LoginVO
loginVO
)
{
log
.
info
(
"开始执行修改密码逻辑"
);
ValidUtils
.
isText
(
loginVO
.
getPhoneNumber
(),
"请输入手机号"
);
ValidUtils
.
isText
(
loginVO
.
getPhoneCode
(),
"请输入验证码"
);
ValidUtils
.
isTrue
(
Validator
.
isMobile
(
loginVO
.
getPhoneNumber
()),
"请输入正确格式的手机号"
);
ValidUtils
.
isText
(
loginVO
.
getPassword
(),
"请输入密码"
);
//1.根据手机号去库中查询是否存在
ZhuanJiaInfoVo
zhuanJiaInfoVo
=
new
ZhuanJiaInfoVo
();
zhuanJiaInfoVo
.
setMobile
(
loginVO
.
getPhoneNumber
());
zhuanJiaInfoVo
=
loginServicesClient
.
querySingleByShengFenZhengOrMobile
(
zhuanJiaInfoVo
);
if
(
zhuanJiaInfoVo
==
null
){
return
"用户信息不存在"
;
}
//2.判断密码是否存在
ZhuanJiaInfoAppVo
zhuanJiaInfoAppVo
=
new
ZhuanJiaInfoAppVo
();
zhuanJiaInfoAppVo
.
setBaseGuid
(
zhuanJiaInfoVo
.
getBaseGuid
());
zhuanJiaInfoAppVo
=
loginServicesClient
.
getZhuanJiaInfoAppById
(
zhuanJiaInfoAppVo
);
String
pwd
=
Sm2Util
.
decrypt
(
loginVO
.
getPassword
());
if
(
zhuanJiaInfoAppVo
==
null
){
//没有记录的话就是新建记录
zhuanJiaInfoAppVo
=
new
ZhuanJiaInfoAppVo
();
zhuanJiaInfoAppVo
.
setPassword
(
passwordEncoder
.
encode
(
pwd
));
loginServicesClient
.
saveZhuanJiaInfoApp
(
zhuanJiaInfoAppVo
);
}
else
{
//否则更新密码
zhuanJiaInfoAppVo
.
setPassword
(
passwordEncoder
.
encode
(
pwd
));
loginServicesClient
.
updateZhuanJiaInfoApp
(
zhuanJiaInfoAppVo
);
}
//手机号,验证码,图形验证码都需要判断
//判断密码是否符合规则
//进行解密处理
//调用数据库更新密码
return
"ok"
;
}
@Override
public
String
verifyCode
(
VerifyCodeVO
codeVO
)
{
log
.
info
(
"手机验证码验证逻辑"
);
boolean
smsfalg
=
smsService
.
verifySmsCode
(
codeVO
.
getPhoneNumber
(),
codeVO
.
getPhoneCode
());
if
(!
smsfalg
){
return
"短信验证码验证失败"
;
}
else
{
return
"短信验证码验证成功"
;
}
}
/**
* 身份证密码登录
* @param loginVO 登录参数
* @return token
*/
private
String
idNumberLogin
(
LoginVO
loginVO
)
{
log
.
info
(
"开始执行身份证登录逻辑"
);
ValidUtils
.
isText
(
loginVO
.
getIdNumber
(),
"请输入身份证号"
);
ValidUtils
.
isText
(
loginVO
.
getPassword
(),
"请输入密码"
);
ValidUtils
.
isTrue
(
IdcardUtil
.
isValidCard
(
loginVO
.
getIdNumber
()),
"请输入正确的身份证号"
);
ZhuanJiaInfoVo
zhuanJiaInfoVo
=
new
ZhuanJiaInfoVo
();
zhuanJiaInfoVo
.
setShengfenzheng
(
loginVO
.
getIdNumber
());
zhuanJiaInfoVo
=
loginServicesClient
.
querySingleByShengFenZhengOrMobile
(
zhuanJiaInfoVo
);
if
(
zhuanJiaInfoVo
==
null
){
return
"用户信息不存在"
;
}
ZhuanJiaInfoAppVo
zhuanJiaInfoAppVo
=
new
ZhuanJiaInfoAppVo
();
zhuanJiaInfoAppVo
.
setBaseGuid
(
zhuanJiaInfoVo
.
getBaseGuid
());
zhuanJiaInfoAppVo
=
loginServicesClient
.
getZhuanJiaInfoAppById
(
zhuanJiaInfoAppVo
);
if
(
zhuanJiaInfoAppVo
==
null
){
return
"该用户还没有设置密码"
;
}
// 验证码效验
boolean
flag
=
sysCaptchaService
.
validate
(
loginVO
.
getKey
(),
loginVO
.
getCaptcha
());
if
(!
flag
)
{
// 保存登录日志
//sysLogLoginService.save(login.getUsername(), Constant.FAIL, LoginOperationEnum.CAPTCHA_FAIL.getValue());
throw
new
BusinessException
(
"图形验证码错误"
);
}
//1.需要去库中查询,是否存在
//2.存在校验密码
//解密
String
pwd
=
Sm2Util
.
decrypt
(
loginVO
.
getPassword
());
flag
=
passwordEncoder
.
matches
(
pwd
,
zhuanJiaInfoAppVo
.
getPassword
());
if
(!
flag
)
{
// 登录日志
//sysLogLoginService.savePortal(login.getAccountName(), Constant.FAIL, LoginOperationEnum.ACCOUNT_FAIL.getValue(), 1);
throw
new
IllegalArgumentException
(
"密码错误"
);
}
//3.生成相应的uuid作为redis的key
// // todo userid
String
uuidKey
=
UUID
.
randomUUID
().
toString
();
String
token
=
JwtUtils
.
createToken
(
1
,
uuidKey
);
tokenSetRedis
(
token
,
uuidKey
);
//6.返回token
return
token
;
}
/**
* 手机验证码登录
* @param loginVO 手机号登录参数
* @return token
*/
private
String
phoneCodeLogin
(
LoginVO
loginVO
)
{
log
.
info
(
"开始执行手机验证码登录逻辑"
);
ValidUtils
.
isText
(
loginVO
.
getPhoneNumber
(),
"请输入手机号"
);
ValidUtils
.
isText
(
loginVO
.
getPhoneCode
(),
"请输入验证码"
);
ValidUtils
.
isTrue
(
Validator
.
isMobile
(
loginVO
.
getPhoneNumber
()),
"请输入正确格式的手机号"
);
//1.根据手机号去库中查询是否存在
ZhuanJiaInfoVo
zhuanJiaInfoVo
=
new
ZhuanJiaInfoVo
();
zhuanJiaInfoVo
.
setMobile
(
loginVO
.
getPhoneNumber
());
zhuanJiaInfoVo
=
loginServicesClient
.
querySingleByShengFenZhengOrMobile
(
zhuanJiaInfoVo
);
if
(
zhuanJiaInfoVo
==
null
){
return
"用户信息不存在"
;
}
//2.存在校验验证码
if
(!
smsService
.
verifySmsCode
(
loginVO
.
getPhoneNumber
(),
loginVO
.
getPhoneCode
()))
{
//登录日志
//sysLogLoginService.savePortal(login.getPhone(), Constant.FAIL, LoginOperationEnum.CAPTCHA_FAIL.getValue(), 1);
throw
new
IllegalArgumentException
(
"手机验证码错误"
);
}
//3.生成相应的uuid作为redis的key
// todo userid
String
uuidKey
=
UUID
.
randomUUID
().
toString
();
String
token
=
JwtUtils
.
createToken
(
1
,
uuidKey
);
tokenSetRedis
(
token
,
uuidKey
);
return
token
;
}
/**
* 缓存存入token
* @param token token
* @param uuidKey uuidKey
*/
private
void
tokenSetRedis
(
String
token
,
String
uuidKey
)
{
String
redisTokenKey
=
TokenConstants
.
TOKEN_KEY_
+
uuidKey
;
redisTemplate
.
opsForValue
().
set
(
redisTokenKey
,
token
,
Duration
.
ofHours
(
24
));
}
}
src/main/java/com/cnooc/expert/auth/service/impl/SmsServiceImpl.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
auth
.
service
.
impl
;
import
cn.hutool.core.util.RandomUtil
;
import
com.cnooc.expert.common.constant.TokenConstants
;
import
com.cnooc.expert.common.utils.SmsHttpUtil
;
import
com.cnooc.expert.common.utils.SmsUtil
;
import
com.cnooc.expert.system.entity.vo.SmsConfig
;
import
com.cnooc.expert.auth.service.SmsService
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.CompletableFuture
;
@Service
@AllArgsConstructor
@Slf4j
public
class
SmsServiceImpl
implements
SmsService
{
public
static
final
String
SMS_CODE_CONTENT
=
"福建通信行业融合创新服务平台,您的验证码是:%s(有效期为2分钟),请勿泄露给他人,如非本人操作,请忽略此消息。"
;
@Autowired
private
StringRedisTemplate
redisTemplate
;
private
final
SmsConfig
smsConfig
;
/**
* 校验短信验证码
*
* @param phone 手机号
* @param code 用户输入的验证码
* @return 是否校验通过
*/
@Override
public
boolean
verifySmsCode
(
String
phone
,
String
code
)
{
String
key
=
"sms:code:"
+
phone
;
String
storedCode
=
redisTemplate
.
opsForValue
().
get
(
key
);
if
(
storedCode
!=
null
&&
storedCode
.
equals
(
code
))
{
// 验证码正确,删除缓存中的验证码
// smsCodeRedisCache.delete(key);
return
true
;
}
return
false
;
}
/**
* 发送短信验证码(可选方法)
*
* @param phone 手机号
* @return 是否发送成功
*/
public
boolean
sendSmsCode
(
String
phone
)
{
// 生成6位验证码
//String code = RandomUtil.randomNumbers(6);
String
code
=
"666666"
;
String
key
=
"sms:code:"
+
phone
;
//redisTemplate.opsForValue().set(key, code, 60 * 60 * 1L);// 存入 Redis,设置过期时间为5分钟
System
.
out
.
println
(
"发送短信验证码:"
+
phone
+
" -> "
+
code
);
// 模拟发送短信,实际应调用第三方短信服务
return
true
;
//return sendMasSmsCode(phone);
}
@Override
public
boolean
sendMasSmsCode
(
String
phone
)
{
// 生成验证码并构建缓存键
String
code
=
SmsUtil
.
generateVerificationCode
();
System
.
out
.
println
(
"发送短信验证码:"
+
phone
+
" -> "
+
code
);
String
key
=
SmsUtil
.
buildCacheKey
(
phone
);
try
{
// 构建短信内容
String
content
=
String
.
format
(
SMS_CODE_CONTENT
,
code
);
System
.
out
.
println
(
"发送短信验证码:"
+
phone
+
" -> "
+
code
);
log
.
info
(
"云MAS业务平台 发送手机号: {},短信验证码:{}"
,
phone
,
code
);
System
.
out
.
println
(
"云MAS业务平台 短信内容: "
+
content
);
boolean
result
=
sendMasSmsContent
(
phone
,
content
);
if
(
result
){
redisTemplate
.
opsForValue
().
set
(
key
,
code
,
2
*
60
);
// 存入 Redis,设置过期时间为2分钟
}
return
result
;
}
catch
(
Exception
e
)
{
log
.
error
(
"云MAS业务平台短信验证码发送失败: {}"
,
e
.
getMessage
(),
e
);
return
false
;
}
}
@Override
public
boolean
sendMasSmsContent
(
String
phone
,
String
content
)
{
try
{
log
.
info
(
"云MAS业务平台 短信内容: {}"
,
content
);
log
.
info
(
"云MAS业务平台 发送手机号: {},短信内容:{}"
,
phone
,
content
);
// 生成 MAC 签名
String
mac
=
SmsUtil
.
calculateMac
(
smsConfig
.
getEcName
(),
smsConfig
.
getApId
(),
smsConfig
.
getSecretKey
(),
phone
,
content
,
smsConfig
.
getSign
(),
smsConfig
.
getAddSerial
());
System
.
out
.
println
(
"云MAS业务平台 mac签名: "
+
mac
);
log
.
info
(
"云MAS业务平台 mac签名: {}"
,
mac
);
// 构建请求体并转换为 Base64 编码的 JSON 字符串
String
encodedJson
=
SmsUtil
.
encodeRequestBodyToBase64
(
buildRequestBody
(
phone
,
content
,
mac
));
System
.
out
.
println
(
"云MAS业务平台 请求体Base64编码: "
+
encodedJson
);
log
.
info
(
"云MAS业务平台 请求体Base64编码: {}"
,
encodedJson
);
// 设置请求头并发送 POST 请求
String
response
=
SmsHttpUtil
.
sendPostRequest
(
smsConfig
.
getApiUrl
(),
encodedJson
);
System
.
out
.
println
(
"云MAS业务平台 响应体: "
+
response
);
log
.
info
(
"云MAS业务平台 响应体response: {}"
,
response
);
// 解析响应并处理结果
return
SmsUtil
.
handleResponse
(
response
);
}
catch
(
Exception
e
)
{
log
.
error
(
"云MAS业务平台短信发送失败: {}"
,
e
.
getMessage
(),
e
);
return
false
;
}
}
@Override
public
void
asyncSendMasSmsContent
(
String
phone
,
String
content
){
CompletableFuture
.
runAsync
(()
->
{
try
{
System
.
out
.
println
(
"======开始发送短信======"
);
sendMasSmsContent
(
phone
,
content
);
System
.
out
.
println
(
"======发送短信结束======"
);
}
catch
(
Exception
e
)
{
log
.
error
(
"asyncSendMasSmsContent异步执行失败"
,
e
);
}
}
);
}
/**
* 构建请求体
*/
private
Map
<
String
,
String
>
buildRequestBody
(
String
phone
,
String
content
,
String
mac
)
{
Map
<
String
,
String
>
requestBody
=
new
HashMap
<>();
requestBody
.
put
(
"ecName"
,
smsConfig
.
getEcName
());
requestBody
.
put
(
"apId"
,
smsConfig
.
getApId
());
requestBody
.
put
(
"mobiles"
,
phone
);
requestBody
.
put
(
"content"
,
content
);
requestBody
.
put
(
"secretKey"
,
smsConfig
.
getSecretKey
());
requestBody
.
put
(
"sign"
,
smsConfig
.
getSign
());
requestBody
.
put
(
"addSerial"
,
smsConfig
.
getAddSerial
());
requestBody
.
put
(
"mac"
,
mac
);
return
requestBody
;
}
}
src/main/java/com/cnooc/expert/auth/service/impl/SysCaptchaServiceImpl.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
auth
.
service
.
impl
;
import
cn.hutool.core.lang.UUID
;
import
cn.hutool.core.util.StrUtil
;
import
com.cnooc.expert.common.cache.RedisKeys
;
import
com.cnooc.expert.auth.service.SysCaptchaService
;
import
lombok.AllArgsConstructor
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.stereotype.Service
;
import
com.cnooc.expert.system.entity.vo.SysCaptchaVO
;
import
com.wf.captcha.SpecCaptcha
;
import
com.wf.captcha.base.Captcha
;
import
java.util.concurrent.TimeUnit
;
@Service
public
class
SysCaptchaServiceImpl
implements
SysCaptchaService
{
private
static
final
int
EXPIRE_MINUTES
=
5
;
@Autowired
private
StringRedisTemplate
redisTemplate
;
@Override
public
SysCaptchaVO
generate
()
{
// 生成验证码key
String
key
=
UUID
.
randomUUID
().
toString
();
// 生成验证码
SpecCaptcha
captcha
=
new
SpecCaptcha
(
150
,
40
);
captcha
.
setLen
(
4
);
captcha
.
setCharType
(
Captcha
.
TYPE_DEFAULT
);
String
image
=
captcha
.
toBase64
();
// 保存到缓存
String
redisKey
=
RedisKeys
.
getCaptchaKey
(
key
);
//redisTemplate.opsForValue().set(redisKey, captcha.text(), EXPIRE_MINUTES, TimeUnit.MINUTES);
// 封装返回数据
SysCaptchaVO
captchaVO
=
new
SysCaptchaVO
();
captchaVO
.
setKey
(
key
);
captchaVO
.
setImage
(
image
);
return
captchaVO
;
}
@Override
public
boolean
validate
(
String
key
,
String
code
)
{
// 如果关闭了验证码,则直接效验通过
if
(!
isCaptchaEnabled
())
{
return
true
;
}
if
(
StrUtil
.
isBlank
(
key
)
||
StrUtil
.
isBlank
(
code
))
{
return
false
;
}
// 获取验证码
String
captcha
=
getCache
(
key
);
// 效验成功
return
code
.
equalsIgnoreCase
(
captcha
);
}
@Override
public
boolean
isCaptchaEnabled
()
{
return
true
;
}
private
String
getCache
(
String
key
)
{
key
=
RedisKeys
.
getCaptchaKey
(
key
);
String
captcha
=
redisTemplate
.
opsForValue
().
get
(
key
);
// 删除验证码
if
(
captcha
!=
null
)
{
redisTemplate
.
delete
(
key
);
}
return
captcha
;
}
}
src/main/java/com/cnooc/expert/common/cache/RedisKeys.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
cache
;
/**
* Redis Key管理
*
*/
public
class
RedisKeys
{
private
static
final
String
CAPTCHA_KEY
=
"CAPTCHA_"
;
/**
* 验证码Key
*/
public
static
String
getCaptchaKey
(
String
key
)
{
// return "sys:captcha:" + key;
return
CAPTCHA_KEY
+
key
;
}
/**
* accessToken Key
*/
public
static
String
getAccessTokenKey
(
String
accessToken
)
{
return
"sys:token:"
+
accessToken
;
}
public
static
String
getLogKey
()
{
return
"sys:log"
;
}
}
src/main/java/com/cnooc/expert/common/constant/TokenConstants.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
constant
;
/**
* Token的Key常量
*
* @author FuHongZhang
*/
public
class
TokenConstants
{
/**
* 令牌前缀
* todo 暂时不用
*/
public
static
final
String
PREFIX
=
"Bearer "
;
/**
* 令牌秘钥
*/
public
final
static
String
SECRET
=
"DjLRzlhhd/gdx6kPXtfBUSMiL8d0VzDYAtWBKpt3BuA="
;
/**
* uuid_key 用于拼接缓存token的key
*/
public
static
final
String
UUID_KEY
=
"uuid_key"
;
/**
* 用户id
*/
public
static
final
String
USER_ID
=
"user_id"
;
/**
* 用于拼接缓存token的key
*/
public
static
final
String
TOKEN_KEY_
=
"TOKEN:TOKEN_KEY_"
;
}
src/main/java/com/cnooc/expert/common/crypto/Sm3PasswordEncoder.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
crypto
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.crypto.SmUtil
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
/**
* 采用国密SM3加密算法,对系统密码进行加密
*
*/
public
class
Sm3PasswordEncoder
implements
PasswordEncoder
{
@Override
public
String
encode
(
CharSequence
rawPassword
)
{
return
SmUtil
.
sm3
(
rawPassword
.
toString
());
}
@Override
public
boolean
matches
(
CharSequence
rawPassword
,
String
encodedPassword
)
{
return
StrUtil
.
equals
(
SmUtil
.
sm3
(
rawPassword
.
toString
()),
encodedPassword
);
}
}
src/main/java/com/cnooc/expert/common/exception/BusinessException.java
View file @
4baf314d
...
@@ -2,21 +2,154 @@ package com.cnooc.expert.common.exception;
...
@@ -2,21 +2,154 @@ package com.cnooc.expert.common.exception;
import
lombok.Getter
;
import
lombok.Getter
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
java.util.Map
;
/**
* 通用业务自定义异常
* 适用于参数校验、业务规则冲突、权限校验等所有业务层面的异常场景
*/
@Getter
@Getter
@Slf4j
@Slf4j
public
class
BusinessException
extends
RuntimeException
{
public
class
BusinessException
extends
RuntimeException
{
private
final
ErrorCode
errorCode
;
// ------------------- Getter 方法(仅提供获取,不允许修改) -------------------
/**
* 错误码(标准化,如:40001=参数错误,40301=权限不足,50001=系统异常)
* 建议遵循 HTTP 状态码规范,扩展业务子码(如 400 开头为客户端错误,500 开头为服务端错误)
*/
private
final
Integer
errorCode
;
/**
* 业务场景标识(如:"user_register"=用户注册,"order_pay"=订单支付,便于定位异常来源)
*/
private
final
String
businessScene
;
/**
* 异常关联数据(可选,存储导致异常的关键业务数据,如:{"userId":"10086","phone":"13800138000"})
*/
private
final
Map
<
String
,
Object
>
errorData
;
// ------------------- 构造方法(按场景重载) -------------------
/**
* 基础构造器:仅包含错误信息(适用于简单场景)
* @param message 异常描述信息
*/
public
BusinessException
(
String
message
)
{
super
(
message
);
this
.
errorCode
=
500
;
// 默认错误码
this
.
businessScene
=
"系统错误"
;
// 默认未知场景
this
.
errorData
=
null
;
// 记录日志
log
.
error
(
"BusinessException occurred: {}"
,
message
);
}
/**
* 构造器:带错误码+错误信息(最常用,标准化异常响应)
* @param errorCode 错误码(如:"40001")
* @param message 异常描述信息
*/
public
BusinessException
(
Integer
errorCode
,
String
message
)
{
super
(
message
);
this
.
errorCode
=
errorCode
;
this
.
businessScene
=
"UNKNOWN"
;
this
.
errorData
=
null
;
// 记录日志
log
.
error
(
"BusinessException occurred - Code: {}, Message: {}"
,
errorCode
,
message
);
}
/**
* 构造器:带错误码+错误信息+业务场景(精准定位异常来源)
* @param errorCode 错误码
* @param message 异常描述信息
* @param businessScene 业务场景(如:"user_login")
*/
public
BusinessException
(
Integer
errorCode
,
String
message
,
String
businessScene
)
{
super
(
message
);
this
.
errorCode
=
errorCode
;
this
.
businessScene
=
businessScene
;
this
.
errorData
=
null
;
// 记录日志
log
.
error
(
"BusinessException occurred - Code: {}, Scene: {}, Message: {}"
,
errorCode
,
businessScene
,
message
);
}
public
BusinessException
(
ErrorCode
errorCode
)
{
/**
super
(
errorCode
.
getMsg
());
* 构造器:带完整信息(错误码+信息+场景+异常数据,便于排查)
* @param errorCode 错误码
* @param message 异常描述信息
* @param businessScene 业务场景
* @param errorData 异常关联数据(如错误的参数、用户ID等)
*/
public
BusinessException
(
Integer
errorCode
,
String
message
,
String
businessScene
,
Map
<
String
,
Object
>
errorData
)
{
super
(
message
);
this
.
errorCode
=
errorCode
;
this
.
errorCode
=
errorCode
;
this
.
businessScene
=
businessScene
;
this
.
errorData
=
errorData
;
// 记录日志
log
.
error
(
"BusinessException occurred - Code: {}, Scene: {}, Message: {}, Data: {}"
,
errorCode
,
businessScene
,
message
,
errorData
);
}
}
public
BusinessException
(
ErrorCode
errorCode
,
String
message
)
{
/**
super
(
StringUtils
.
defaultIfBlank
(
message
,
errorCode
.
getMsg
()));
* 构造器:带根因异常(用于包装底层异常,如SQL异常、IO异常)
* @param errorCode 错误码
* @param message 异常描述信息
* @param cause 根因异常(底层原始异常)
*/
public
BusinessException
(
Integer
errorCode
,
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
this
.
errorCode
=
errorCode
;
this
.
errorCode
=
errorCode
;
this
.
businessScene
=
"UNKNOWN"
;
this
.
errorData
=
null
;
// 记录日志
log
.
error
(
"BusinessException occurred - Code: {}, Message: {}, Cause: {}"
,
errorCode
,
message
,
cause
.
getClass
().
getSimpleName
());
}
/**
* 构造器:全参数(适配复杂场景)
* @param errorCode 错误码
* @param message 异常描述信息
* @param businessScene 业务场景
* @param errorData 异常关联数据
* @param cause 根因异常
*/
public
BusinessException
(
Integer
errorCode
,
String
message
,
String
businessScene
,
Map
<
String
,
Object
>
errorData
,
Throwable
cause
)
{
super
(
message
,
cause
);
this
.
errorCode
=
errorCode
;
this
.
businessScene
=
businessScene
;
this
.
errorData
=
errorData
;
// 记录日志
log
.
error
(
"BusinessException occurred - Code: {}, Scene: {}, Message: {}, Data: {}, Cause: {}"
,
errorCode
,
businessScene
,
message
,
errorData
,
cause
.
getClass
().
getSimpleName
());
}
// ------------------- 增强异常信息可读性 -------------------
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
(
"BusinessException: ["
);
sb
.
append
(
"errorCode="
).
append
(
errorCode
)
.
append
(
", businessScene="
).
append
(
businessScene
)
.
append
(
", message="
).
append
(
getMessage
()).
append
(
"]"
);
// 追加异常数据(若存在)
if
(
errorData
!=
null
&&
!
errorData
.
isEmpty
())
{
sb
.
append
(
" | errorData="
).
append
(
errorData
);
}
// 追加根因异常(若存在)
if
(
getCause
()
!=
null
)
{
sb
.
append
(
" | cause="
).
append
(
getCause
().
getClass
().
getSimpleName
());
}
return
sb
.
toString
();
}
}
}
}
\ No newline at end of file
src/main/java/com/cnooc/expert/common/exception/GlobalExceptionHandler.java
View file @
4baf314d
...
@@ -45,16 +45,12 @@ public class GlobalExceptionHandler {
...
@@ -45,16 +45,12 @@ public class GlobalExceptionHandler {
/**
/**
* 处理其他异常
* 处理其他异常
*/
*/
@ExceptionHandler
(
Exception
.
class
)
public
ApiResult
<
String
>
handleException
(
Exception
e
,
HttpServletRequest
request
)
{
log
.
error
(
"系统异常: {},请求URL: {}"
,
e
.
getMessage
(),
request
.
getRequestURI
(),
e
);
return
ApiResult
.
error
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
(),
GlobalErrorCodeConstants
.
SYSTEM_ERROR
.
getMsg
());
}
@ExceptionHandler
(
BusinessException
.
class
)
@ExceptionHandler
(
BusinessException
.
class
)
public
ApiResult
<
String
>
handleBusinessException
(
BusinessException
e
,
HttpServletRequest
request
)
{
public
ApiResult
<
String
>
handleBusinessException
(
BusinessException
e
,
HttpServletRequest
request
)
{
log
.
error
(
"业务异常: {},请求URL: {}"
,
e
.
getMessage
(),
request
.
getRequestURI
(),
e
);
log
.
error
(
"业务异常: {},请求URL: {}"
,
e
.
getMessage
(),
request
.
getRequestURI
(),
e
);
return
ApiResult
.
error
(
e
.
getErrorCode
()
.
getCode
()
,
e
.
getMessage
());
return
ApiResult
.
error
(
e
.
getErrorCode
(),
e
.
getMessage
());
}
}
@ExceptionHandler
(
NullPointerException
.
class
)
@ExceptionHandler
(
NullPointerException
.
class
)
...
@@ -62,4 +58,10 @@ public class GlobalExceptionHandler {
...
@@ -62,4 +58,10 @@ public class GlobalExceptionHandler {
log
.
error
(
"空指针异常: {},请求URL: {}"
,
e
.
getMessage
(),
request
.
getRequestURI
(),
e
);
log
.
error
(
"空指针异常: {},请求URL: {}"
,
e
.
getMessage
(),
request
.
getRequestURI
(),
e
);
return
ApiResult
.
error
(
GlobalErrorCodeConstants
.
SYSTEM_ERROR
.
getCode
(),
GlobalErrorCodeConstants
.
SYSTEM_ERROR
.
getMsg
());
return
ApiResult
.
error
(
GlobalErrorCodeConstants
.
SYSTEM_ERROR
.
getCode
(),
GlobalErrorCodeConstants
.
SYSTEM_ERROR
.
getMsg
());
}
}
@ExceptionHandler
(
Exception
.
class
)
public
ApiResult
<
String
>
handleException
(
Exception
e
,
HttpServletRequest
request
)
{
log
.
error
(
"系统异常: {},请求URL: {}"
,
e
.
getMessage
(),
request
.
getRequestURI
(),
e
);
return
ApiResult
.
error
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
(),
GlobalErrorCodeConstants
.
SYSTEM_ERROR
.
getMsg
());
}
}
}
src/main/java/com/cnooc/expert/common/interceptor/LoginInterceptor.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
interceptor
;
import
com.cnooc.expert.common.constant.TokenConstants
;
import
com.cnooc.expert.common.exception.BusinessException
;
import
com.cnooc.expert.common.exception.GlobalErrorCodeConstants
;
import
com.cnooc.expert.common.utils.JwtUtils
;
import
com.cnooc.expert.common.utils.UserUtils
;
import
com.cnooc.expert.common.utils.ValidUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.servlet.HandlerInterceptor
;
import
org.springframework.web.servlet.ModelAndView
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.util.Map
;
/**
* @author: FuHongZhang
* @date 2025-10-16 10:22
*/
@Slf4j
@Component
public
class
LoginInterceptor
implements
HandlerInterceptor
{
@Autowired
private
StringRedisTemplate
redisTemplate
;
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
throws
Exception
{
String
token
=
request
.
getHeader
(
"Authorization"
);
if
(
token
==
null
||
token
.
trim
().
isEmpty
())
{
response
.
setStatus
(
HttpServletResponse
.
SC_UNAUTHORIZED
);
throw
new
BusinessException
(
HttpServletResponse
.
SC_UNAUTHORIZED
,
GlobalErrorCodeConstants
.
LOGIN_EXPIRED
.
getMsg
());
}
try
{
Map
<
String
,
String
>
userMap
=
JwtUtils
.
getTokenInfo
(
token
);
String
userId
=
userMap
.
get
(
TokenConstants
.
USER_ID
);
String
uuidKey
=
userMap
.
get
(
TokenConstants
.
UUID_KEY
);
ValidUtils
.
isNotNull
(
uuidKey
,
"登录异常,请重新登录"
);
// String cachedToken = redisTemplate.opsForValue().get(TokenConstants.TOKEN_KEY_ + userId);
//
// if (cachedToken == null || !cachedToken.equals(token)) {
// // token不存在或不匹配,说明已退出登录或token失效
// response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
// response.getWriter().write("{\"code\":401,\"msg\":\"请先登录\"}");
// return false;
// }
// todo 通过token解析出用户id,代用UserUtils.setUserId(userId)方法进行存储
// 所有条件都满足,放行请求
return
true
;
}
catch
(
Exception
e
)
{
log
.
info
(
"token解析异常 {}"
,
e
.
getMessage
(),
e
);
response
.
setStatus
(
HttpServletResponse
.
SC_UNAUTHORIZED
);
UserUtils
.
clear
();
throw
new
BusinessException
(
401
,
"请先登录"
);
}
}
@Override
public
void
postHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
ModelAndView
modelAndView
)
throws
Exception
{
}
@Override
public
void
afterCompletion
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
,
Exception
ex
)
throws
Exception
{
UserUtils
.
clear
();
}
}
src/main/java/com/cnooc/expert/common/utils/AesUtil.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
com.cnooc.expert.common.exception.BusinessException
;
import
lombok.extern.slf4j.Slf4j
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.crypto.Cipher
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.security.MessageDigest
;
/**
* @author lyh
* 2016年10月24日 上午9:34:32
*/
@Slf4j
public
class
AesUtil
{
private
static
final
String
KEY_TYPE
=
"AES"
;
private
static
final
String
CIPHER_TYPE
=
"AES/ECB/PKCS5Padding"
;
/**
* 加密
*
* @param content
* 要加密的内容
* @param password
* 密码
* @return 加密后的字符串
*/
public
static
String
encrypt
(
String
content
,
String
password
)
{
String
realKey
=
AesUtil
.
md5Encode
(
password
);
SecretKeySpec
sks
=
new
SecretKeySpec
(
AesUtil
.
hex2byte
(
realKey
),
KEY_TYPE
);
byte
[]
cipherByte
=
null
;
try
{
Cipher
c1
=
Cipher
.
getInstance
(
CIPHER_TYPE
);
c1
.
init
(
Cipher
.
ENCRYPT_MODE
,
sks
);
cipherByte
=
c1
.
doFinal
(
content
.
getBytes
(
"UTF-8"
));
// 返回密文的十六进制形式
return
byte2hex
(
cipherByte
);
}
catch
(
Exception
e
)
{
log
.
error
(
"e:{}"
,
e
);
throw
new
BusinessException
(
"加密失败"
);
}
}
/**
* 解密
*
* @param content
* 要解密的内容
* @param password
* 密码
* @return 解密结果
*/
public
static
String
decrypt
(
String
content
,
String
password
)
{
String
realKey
=
AesUtil
.
md5Encode
(
password
);
SecretKeySpec
sks
=
new
SecretKeySpec
(
AesUtil
.
hex2byte
(
realKey
),
KEY_TYPE
);
byte
[]
cipherByte
=
null
;
try
{
Cipher
c1
=
Cipher
.
getInstance
(
CIPHER_TYPE
);
c1
.
init
(
Cipher
.
DECRYPT_MODE
,
sks
);
cipherByte
=
c1
.
doFinal
(
hex2byte
(
content
));
return
new
String
(
cipherByte
);
}
catch
(
Exception
e
)
{
log
.
error
(
"e:{}"
,
e
);
throw
new
BusinessException
(
"解密失败"
);
}
}
/**
* 生成MD5摘要
*/
public
static
String
md5Encode
(
String
info
)
{
try
{
MessageDigest
alga
=
MessageDigest
.
getInstance
(
"MD5"
);
alga
.
update
(
info
.
getBytes
(
"UTF-8"
));
return
byte2hex
(
alga
.
digest
());
}
catch
(
Exception
e
)
{
return
null
;
}
}
/**
* 将二进制转化为16进制字符串
*/
public
static
String
byte2hex
(
byte
[]
b
)
{
StringBuilder
bder
=
new
StringBuilder
();
String
stmp
=
null
;
for
(
int
n
=
0
;
n
<
b
.
length
;
n
++)
{
stmp
=
Integer
.
toHexString
(
b
[
n
]
&
0XFF
);
if
(
stmp
.
length
()
==
1
)
{
bder
.
append
(
"0"
);
}
bder
.
append
(
stmp
);
}
return
bder
.
toString
().
toUpperCase
();
}
/**
* 十六进制字符串转化为byte数组
*/
private
static
byte
[]
hex2byte
(
String
hex
)
{
if
(
hex
.
length
()
%
2
!=
0
)
{
throw
new
IllegalArgumentException
(
"参数长度不合法"
);
}
byte
[]
result
=
new
byte
[
hex
.
length
()
/
2
];
for
(
int
i
=
0
;
i
<
result
.
length
;
i
++)
{
result
[
i
]
=
uniteBytes
(
hex
.
charAt
(
i
*
2
),
hex
.
charAt
(
i
*
2
+
1
));
}
return
result
;
}
/**
* 将两个ASCII字符合成一个字节; 如:"EF"--> 0xEF
*
* @param c1
* @param c2
* @return byte
*/
private
static
byte
uniteBytes
(
char
c1
,
char
c2
)
{
byte
_b0
=
Byte
.
decode
(
"0x"
+
c1
);
_b0
=
(
byte
)
(
_b0
<<
4
);
byte
_b1
=
Byte
.
decode
(
"0x"
+
c2
);
return
(
byte
)
(
_b0
^
_b1
);
}
}
src/main/java/com/cnooc/expert/common/utils/CommonUtil.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Objects
;
/**
* 公用的工具类
* @author zhengkai
*
* @date 2015年5月25日 上午11:34:35
*/
public
class
CommonUtil
{
public
static
final
Long
SO_FAR_TINE
=
new
Long
(-
1L
);
/**
* 时间转换成字符串(采用 yyyy-MM-dd HH:mm:ss)
* @param longtime
* @return
* @author zhengkai
* @date 2015年5月9日 下午2:43:28F
*/
public
static
String
longTimeToString
(
Long
longtime
){
if
(
SO_FAR_TINE
.
equals
(
longtime
))
{
return
"至今"
;
}
if
(
longtime
!=
null
){
Date
dt
=(
new
Date
(
longtime
));
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
return
sdf
.
format
(
dt
);
}
return
""
;
}
public
static
String
LongTimeToStringOnDay
(
Long
longtime
){
if
(
SO_FAR_TINE
.
equals
(
longtime
))
{
return
"至今"
;
}
if
(
longtime
!=
null
){
Date
dt
=(
new
Date
(
longtime
));
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
);
return
sdf
.
format
(
dt
);
}
return
""
;
}
/**
* 时间转换成字符串
* @param longtime
* @param formatter
* @return
* @author zhengkai
* @date 2015年5月9日 下午2:43:28
*/
public
static
String
LongTimeToString
(
Long
longtime
,
String
formatter
){
if
(
SO_FAR_TINE
.
equals
(
longtime
))
{
return
"至今"
;
}
if
(
longtime
!=
null
){
Date
dt
=(
new
Date
(
longtime
));
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
formatter
);
return
sdf
.
format
(
dt
);
}
return
""
;
}
/**
* 字符串值是否相同
* <p>
* 注意:只比较视觉值 即null = '' = ' '
* </p>
*
* @param str1
* @param str2
* @return
*/
public
static
boolean
stringValSame
(
String
str1
,
String
str2
){
str1
=
Objects
.
toString
(
str1
,
""
).
trim
();
str2
=
Objects
.
toString
(
str2
,
""
).
trim
();
return
str1
.
equals
(
str2
);
}
/**
* 二开 - Boolean类型转成字符串展示
*
* @param val
* @return true->是;false->否
*/
public
static
String
convertBool2Str
(
Boolean
val
){
if
(
Objects
.
isNull
(
val
))
{
return
""
;
}
return
Boolean
.
TRUE
.
equals
(
val
)
?
"是"
:
"否"
;
}
}
src/main/java/com/cnooc/expert/common/utils/JsonUtils.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
cn.hutool.core.util.ArrayUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.fasterxml.jackson.core.type.TypeReference
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* JSON 工具类
*
*/
public
class
JsonUtils
{
private
static
final
ObjectMapper
objectMapper
=
new
ObjectMapper
();
static
{
objectMapper
.
registerModule
(
new
JavaTimeModule
());
// objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
objectMapper
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
}
public
static
String
toJsonString
(
Object
object
)
{
try
{
return
objectMapper
.
writeValueAsString
(
object
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
static
<
T
>
T
parseObject
(
String
text
,
Class
<
T
>
clazz
)
{
if
(
StrUtil
.
isEmpty
(
text
))
{
return
null
;
}
try
{
return
objectMapper
.
readValue
(
text
,
clazz
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
static
<
T
>
T
parseObject
(
byte
[]
bytes
,
Class
<
T
>
clazz
)
{
if
(
ArrayUtil
.
isEmpty
(
bytes
))
{
return
null
;
}
try
{
return
objectMapper
.
readValue
(
bytes
,
clazz
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
static
<
T
>
T
parseObject
(
String
text
,
TypeReference
<
T
>
typeReference
)
{
try
{
return
objectMapper
.
readValue
(
text
,
typeReference
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
static
<
T
>
List
<
T
>
parseArray
(
String
text
,
Class
<
T
>
clazz
)
{
if
(
StrUtil
.
isEmpty
(
text
))
{
return
new
ArrayList
<>();
}
try
{
return
objectMapper
.
readValue
(
text
,
objectMapper
.
getTypeFactory
().
constructCollectionType
(
List
.
class
,
clazz
));
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
}
src/main/java/com/cnooc/expert/common/utils/JwtUtils.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
com.alibaba.fastjson.JSON
;
import
io.jsonwebtoken.*
;
import
lombok.extern.slf4j.Slf4j
;
import
com.cnooc.expert.common.constant.TokenConstants
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* JWT工具类,用于生成、解析和验证token
* @author FuHongZhang
*/
@Slf4j
public
class
JwtUtils
{
// 密钥,实际项目中应放在配置文件中
private
static
final
String
SECRET_KEY
=
TokenConstants
.
SECRET
;
// Token过期时间,这里设置为48小时
private
static
final
long
EXPIRATION_TIME
=
48
*
60
*
60
*
1000
;
// private static final long EXPIRATION_TIME = 3 * 1000;
/**
* 生成token
* @return token字符串
*/
public
static
String
createToken
(
Integer
userId
,
String
uuidKey
)
{
// 生成token
return
Jwts
.
builder
()
.
setExpiration
(
new
Date
(
System
.
currentTimeMillis
()
+
EXPIRATION_TIME
))
.
setIssuedAt
(
new
Date
())
.
claim
(
TokenConstants
.
UUID_KEY
,
uuidKey
)
.
claim
(
TokenConstants
.
USER_ID
,
userId
)
.
signWith
(
SignatureAlgorithm
.
HS256
,
SECRET_KEY
)
.
compact
();
}
/**
* 从token中获取用于拼接缓存的key uuid_key 和用户 user_id
*/
public
static
Map
<
String
,
String
>
getTokenInfo
(
String
token
)
{
// 如果过期,会抛Exception
Map
<
String
,
String
>
userInfo
=
new
HashMap
<>();
Claims
claims
=
extractAllClaims
(
token
);
userInfo
.
put
(
TokenConstants
.
UUID_KEY
,
(
String
)
claims
.
get
(
TokenConstants
.
UUID_KEY
));
userInfo
.
put
(
TokenConstants
.
USER_ID
,
claims
.
get
(
TokenConstants
.
USER_ID
)
+
""
);
return
userInfo
;
}
/**
*
* @param token
* @return
*/
private
static
Claims
extractAllClaims
(
String
token
)
{
return
Jwts
.
parser
().
setSigningKey
(
SECRET_KEY
).
parseClaimsJws
(
token
).
getBody
();
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
String
portalToken
=
JwtUtils
.
createToken
(
111
,
"testtest"
);
Thread
.
sleep
(
5000
);
Map
<
String
,
String
>
claims
=
JwtUtils
.
getTokenInfo
(
portalToken
);
System
.
out
.
print
(
JSON
.
toJSONString
(
claims
,
true
));
}
}
src/main/java/com/cnooc/expert/common/utils/RestUtils.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
org.springframework.core.ParameterizedTypeReference
;
import
org.springframework.http.*
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.web.client.RestTemplate
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
RestUtils
{
private
static
final
RestTemplate
restTemplate
=
new
RestTemplate
();
/**
* 发送 Base64 编码的 JSON POST 请求
*
* @param apiUrl API 地址
* @param requestBody 请求体 Map
* @return 响应字符串
*/
public
static
<
T
>
T
sendPostRequest
(
String
apiUrl
,
Map
<
String
,
String
>
headersMap
,
String
requestBody
,
ParameterizedTypeReference
<
T
>
responseType
)
{
try
{
// 设置请求头
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
if
(!
CollectionUtils
.
isEmpty
(
headersMap
))
{
headersMap
.
forEach
(
headers:
:
set
);
}
// 构建请求实体
HttpEntity
<
String
>
requestEntity
=
new
HttpEntity
<>(
requestBody
,
headers
);
ResponseEntity
<
T
>
response
=
restTemplate
.
exchange
(
apiUrl
,
HttpMethod
.
POST
,
requestEntity
,
responseType
);
return
response
.
getBody
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"发送 POST 请求失败"
,
e
);
}
}
public
static
<
T
>
T
sendPostRequest2Expert
(
String
relativeUrl
,
String
requestBody
,
ParameterizedTypeReference
<
T
>
responseType
){
String
fullUrl
=
"http://10.xxx.xxx.xxx"
+
relativeUrl
;
Map
<
String
,
String
>
headers
=
new
HashMap
<>();
headers
.
put
(
"Access-Key"
,
"Ysy9ht"
);
return
sendPostRequest
(
fullUrl
,
headers
,
requestBody
,
responseType
);
}
}
src/main/java/com/cnooc/expert/common/utils/Sm2Util.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
cn.hutool.core.util.HexUtil
;
import
cn.hutool.crypto.SecureUtil
;
import
cn.hutool.crypto.SmUtil
;
import
cn.hutool.crypto.asymmetric.KeyType
;
import
cn.hutool.crypto.asymmetric.SM2
;
import
org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
;
import
org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey
;
import
org.bouncycastle.util.encoders.Hex
;
import
java.security.KeyPair
;
import
java.security.PrivateKey
;
import
java.security.PublicKey
;
/**
* 国密SM2加密算法
*
*/
public
class
Sm2Util
{
/**
* 公钥
*/
private
final
static
String
PUBLIC_KEY
=
"3059301306072a8648ce3d020106082a811ccf5501822d034200040a302b5e4b961afb3908a4ae191266ac5866be100fc52e3b8dba9707c8620e64ae790ceffc3bfbf262dc098d293dd3e303356cb91b54861c767997799d2f0060"
;
/**
* 私钥
*/
private
final
static
String
PRIVATE_KEY
=
"308193020100301306072a8648ce3d020106082a811ccf5501822d047930770201010420d7840173df3d6cd72cad4040dfc7dbfcde539f5b490b54f3cd5c4125544b38aea00a06082a811ccf5501822da144034200040a302b5e4b961afb3908a4ae191266ac5866be100fc52e3b8dba9707c8620e64ae790ceffc3bfbf262dc098d293dd3e303356cb91b54861c767997799d2f0060"
;
private
final
static
SM2
sm2
;
static
{
sm2
=
SmUtil
.
sm2
(
PRIVATE_KEY
,
PUBLIC_KEY
);
}
/**
* 加密
*
* @param data 明文
* @return 加密后的密文
*/
public
static
String
encrypt
(
String
data
)
{
return
sm2
.
encryptBase64
(
data
,
KeyType
.
PublicKey
);
}
/**
* 解密
*
* @param data 加密后的密文
* @return 解密后的明文
*/
public
static
String
decrypt
(
String
data
)
{
return
sm2
.
decryptStr
(
data
,
KeyType
.
PrivateKey
);
}
public
static
void
main
(
String
[]
args
)
{
KeyPair
keyPair
=
SecureUtil
.
generateKeyPair
(
"SM2"
);
System
.
out
.
println
(
"privateKey:"
+
HexUtil
.
encodeHexStr
(
keyPair
.
getPrivate
().
getEncoded
()));
System
.
out
.
println
(
"publicKey:"
+
HexUtil
.
encodeHexStr
(
keyPair
.
getPublic
().
getEncoded
()));
PublicKey
publicKey
=
keyPair
.
getPublic
();
if
(
publicKey
instanceof
BCECPublicKey
)
{
// 获取65字节非压缩缩的十六进制公钥串(0x04)
String
publicKeyHex
=
Hex
.
toHexString
(((
BCECPublicKey
)
publicKey
).
getQ
().
getEncoded
(
false
));
System
.
out
.
println
(
"SM2公钥:"
+
publicKeyHex
);
}
PrivateKey
privateKey
=
keyPair
.
getPrivate
();
if
(
privateKey
instanceof
BCECPrivateKey
)
{
// 获取32字节十六进制私钥串
String
privateKeyHex
=
((
BCECPrivateKey
)
privateKey
).
getD
().
toString
(
16
);
System
.
out
.
println
(
"SM2私钥:"
+
privateKeyHex
);
}
String
password
=
"admin"
;
String
sm2Password
=
Sm2Util
.
encrypt
(
password
);
System
.
out
.
println
(
"sm2 加密:"
+
sm2Password
);
System
.
out
.
println
(
"sm2 解密:"
+
Sm2Util
.
decrypt
(
sm2Password
));
System
.
out
.
println
(
"sm3 解密:"
+
SmUtil
.
sm3
(
"admin"
));
}
}
src/main/java/com/cnooc/expert/common/utils/SmsHttpUtil.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
org.springframework.http.HttpEntity
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.MediaType
;
import
org.springframework.web.client.RestTemplate
;
public
class
SmsHttpUtil
{
private
static
final
RestTemplate
restTemplate
=
new
RestTemplate
();
/**
* 发送 Base64 编码的 JSON POST 请求
*
* @param apiUrl API 地址
* @param requestBody 请求体 Map
* @return 响应字符串
*/
public
static
String
sendPostRequest
(
String
apiUrl
,
String
requestBody
)
{
try
{
// 设置请求头
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
// 构建请求实体
HttpEntity
<
String
>
requestEntity
=
new
HttpEntity
<>(
requestBody
,
headers
);
return
restTemplate
.
postForObject
(
apiUrl
,
requestEntity
,
String
.
class
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"发送 POST 请求失败"
,
e
);
}
}
}
src/main/java/com/cnooc/expert/common/utils/SmsUtil.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
cn.hutool.core.util.RandomUtil
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
java.nio.charset.StandardCharsets
;
import
java.security.MessageDigest
;
import
java.util.Base64
;
import
java.util.Map
;
@Slf4j
public
class
SmsUtil
{
/**
* 生成6位随机验证码
*/
public
static
String
generateVerificationCode
()
{
return
RandomUtil
.
randomNumbers
(
6
);
}
/**
* 构建 Redis 缓存键
*/
public
static
String
buildCacheKey
(
String
phone
)
{
return
"sms:code:"
+
phone
;
}
/**
* 构建短信内容
*/
public
static
String
buildSmsContent
(
String
code
)
{
return
"福建通信行业融合创新服务平台,您的验证码是:"
+
code
+
"(有效期为2分钟),请勿泄露给他人,如非本人操作,请忽略此消息。"
;
}
/**
* 将请求体转换为 Base64 编码的 JSON 字符串
*/
public
static
String
encodeRequestBodyToBase64
(
Map
<
String
,
String
>
requestBody
)
{
String
jsonString
=
JsonUtils
.
toJsonString
(
requestBody
);
return
Base64
.
getEncoder
().
encodeToString
(
jsonString
.
getBytes
(
StandardCharsets
.
UTF_8
));
}
/**
* 处理响应结果
*/
public
static
boolean
handleResponse
(
String
response
)
throws
Exception
{
JsonNode
jsonNode
=
JsonUtils
.
parseObject
(
response
,
JsonNode
.
class
);
if
(
jsonNode
.
get
(
"success"
).
asBoolean
())
{
System
.
out
.
println
(
"云MAS业务平台短信验证码发送成功"
);
log
.
info
(
"云MAS业务平台短信验证码发送成功"
);
return
true
;
}
else
{
System
.
out
.
println
(
"云MAS业务平台短信验证码发送失败"
);
log
.
info
(
"云MAS业务平台短信验证码发送失败"
);
return
false
;
}
}
public
static
String
calculateMac
(
String
ecName
,
String
apld
,
String
secretKey
,
String
mobiles
,
String
content
,
String
sign
,
String
addSerial
)
{
try
{
// 根据文档中的规则计算MAC
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
ecName
).
append
(
apld
).
append
(
secretKey
).
append
(
mobiles
).
append
(
content
).
append
(
sign
).
append
(
addSerial
);
return
DigestUtils
.
md5Hex
(
sb
.
toString
());
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"生成MAC签名失败"
,
e
);
}
}
public
static
String
generateMD5
(
String
input
)
{
try
{
MessageDigest
md
=
MessageDigest
.
getInstance
(
"MD5"
);
byte
[]
digest
=
md
.
digest
(
input
.
getBytes
());
StringBuilder
sb
=
new
StringBuilder
();
for
(
byte
b
:
digest
)
{
sb
.
append
(
String
.
format
(
"%02x"
,
b
));
}
return
sb
.
toString
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"生成MAC签名失败"
,
e
);
}
}
}
src/main/java/com/cnooc/expert/common/utils/UserUtils.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
com.cnooc.expert.system.entity.pojo.ZhuanJiaUser
;
import
org.springframework.stereotype.Component
;
/**
* 用户id获取工具类
* @author: FuHongZhang
* @date 2025-10-24 11:14:07
*/
@Component
(
"userUtils"
)
public
class
UserUtils
{
public
static
ZhuanJiaUser
getCurrentUser
()
{
ZhuanJiaUser
zhuanJiaUser
=
USER_INFO
.
get
();
if
(
zhuanJiaUser
!=
null
)
{
return
zhuanJiaUser
;
}
return
null
;
}
private
static
final
ThreadLocal
<
ZhuanJiaUser
>
USER_INFO
=
new
ThreadLocal
<>();
public
static
void
setUserId
(
ZhuanJiaUser
zhuanJiaUser
)
{
USER_INFO
.
set
(
zhuanJiaUser
);
}
public
static
ZhuanJiaUser
getUserId
()
{
return
USER_INFO
.
get
();
}
public
static
void
clear
()
{
USER_INFO
.
remove
();
}
}
\ No newline at end of file
src/main/java/com/cnooc/expert/common/utils/ValidUtils.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
com.cnooc.expert.common.exception.BusinessException
;
import
com.cnooc.expert.common.exception.ErrorCode
;
import
com.cnooc.expert.common.exception.GlobalErrorCodeConstants
;
import
java.util.Collection
;
/**
* @Author: FuHongZhang
* @CreateTime: 2025-09-18 16:11
*/
public
class
ValidUtils
{
/**
* 校验字符串是否为空
* @param text 待校验的字符串
* @param message 异常信息
*/
public
static
void
isText
(
String
text
,
String
message
)
{
if
(
text
==
null
||
text
.
trim
().
isEmpty
())
{
throw
new
BusinessException
(
GlobalErrorCodeConstants
.
PARAM_FORMAT_ERROR
.
getCode
(),
message
);
}
}
/**
* 校验对象是否为null
* @param obj 待校验的对象
* @param message 异常信息
*/
public
static
void
isNotNull
(
Object
obj
,
String
message
)
{
if
(
obj
==
null
)
{
throw
new
BusinessException
(
GlobalErrorCodeConstants
.
PARAM_FORMAT_ERROR
.
getCode
(),
message
);
}
}
/**
* 自定义错误码及错误信息
* @param obj
* @param errorCode
*/
public
static
void
isNotNull
(
Object
obj
,
ErrorCode
errorCode
)
{
if
(
obj
==
null
)
{
throw
new
BusinessException
(
errorCode
.
getCode
(),
errorCode
.
getMsg
());
}
}
/**
* 校验集合是否为空
* @param collection 待校验的集合
* @param message 异常信息
*/
public
static
void
isNullList
(
Collection
<?>
collection
,
String
message
)
{
if
(
collection
==
null
||
collection
.
isEmpty
())
{
throw
new
BusinessException
(
GlobalErrorCodeConstants
.
PARAM_FORMAT_ERROR
.
getCode
(),
message
);
}
}
/**
* 校验表达式是否为true
* @param expression 待校验的布尔表达式
* @param message 异常信息
*/
public
static
void
isTrue
(
boolean
expression
,
String
message
)
{
if
(!
expression
)
{
throw
new
BusinessException
(
GlobalErrorCodeConstants
.
PARAM_FORMAT_ERROR
.
getCode
(),
message
);
}
}
/**
* 校验表达式是否为true
* @param expression
* @param errorCode
*/
public
static
void
isTrue
(
boolean
expression
,
ErrorCode
errorCode
)
{
if
(!
expression
)
{
throw
new
BusinessException
(
errorCode
.
getCode
(),
errorCode
.
getMsg
());
}
}
/**
* 校验表达式是否为false
* @param expression 待校验的布尔表达式
* @param message 异常信息
*/
public
static
void
isFalse
(
boolean
expression
,
String
message
)
{
if
(
expression
)
{
throw
new
BusinessException
(
GlobalErrorCodeConstants
.
PARAM_FORMAT_ERROR
.
getCode
(),
message
);
}
}
}
src/main/java/com/cnooc/expert/config/PasswordConfig.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
config
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
com.cnooc.expert.common.crypto.Sm3PasswordEncoder
;
/**
* 加密配置
*
*/
@Configuration
public
class
PasswordConfig
{
@Bean
public
PasswordEncoder
passwordEncoder
()
{
// 使用国密SM3加密
return
new
Sm3PasswordEncoder
();
}
}
src/main/java/com/cnooc/expert/config/TheWebMvcConfigurer.java
View file @
4baf314d
package
com
.
cnooc
.
expert
.
config
;
package
com
.
cnooc
.
expert
.
config
;
import
com.cnooc.expert.common.interceptor.LoginInterceptor
;
import
com.cnooc.expert.common.interceptor.WebAuthInterceptor
;
import
com.cnooc.expert.common.interceptor.WebAuthInterceptor
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.web.servlet.config.annotation.InterceptorRegistry
;
import
org.springframework.web.servlet.config.annotation.InterceptorRegistry
;
...
@@ -9,8 +11,22 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
...
@@ -9,8 +11,22 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@Configuration
public
class
TheWebMvcConfigurer
implements
WebMvcConfigurer
{
public
class
TheWebMvcConfigurer
implements
WebMvcConfigurer
{
@Autowired
private
LoginInterceptor
loginInterceptor
;
@Override
@Override
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
// 注册登录拦截器,并设置拦截路径和排除路径
registry
.
addInterceptor
(
loginInterceptor
)
.
addPathPatterns
(
"/**"
)
// 拦截所有路径
.
excludePathPatterns
(
// 排除一些路径
"/sys/**"
,
"/verify/**"
,
"/person/**"
,
"/text/**"
);
registry
.
addInterceptor
(
webAuthInterceptor
());
registry
.
addInterceptor
(
webAuthInterceptor
());
}
}
...
...
src/main/java/com/cnooc/expert/external/expert/api/LoginServiceApi.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
external
.
expert
.
api
;
import
com.cnooc.expert.external.expert.model.request.ExpertInfoGetReq
;
import
com.cnooc.expert.external.expert.model.response.ExpertInfoGetResp
;
import
retrofit2.Call
;
import
retrofit2.http.Body
;
import
retrofit2.http.HeaderMap
;
import
retrofit2.http.POST
;
import
java.util.Map
;
public
interface
LoginServiceApi
{
@POST
(
"/"
)
Call
<
ExpertInfoGetResp
>
expertDetailUpDate
(
@HeaderMap
Map
<
String
,
Object
>
headers
,
@Body
ExpertInfoGetReq
user
);
}
src/main/java/com/cnooc/expert/external/expert/auth/service/LoginServicesClient.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
external
.
expert
.
auth
.
service
;
import
com.cnooc.expert.external.common.AbstractRetrofitManager
;
import
com.cnooc.expert.system.entity.vo.ZhuanJiaInfoVo
;
import
com.cnooc.expert.system.entity.vo.ZhuanJiaInfoAppVo
;
import
org.springframework.stereotype.Service
;
@Service
public
class
LoginServicesClient
extends
AbstractRetrofitManager
{
public
ZhuanJiaInfoVo
querySingleByShengFenZhengOrMobile
(
ZhuanJiaInfoVo
zhuanJiaInfoVo
){
ZhuanJiaInfoVo
res
=
new
ZhuanJiaInfoVo
();
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/querySingleByShengFenZhengOrMobile",jsonString,null);
*/
return
res
;
}
public
ZhuanJiaInfoAppVo
getZhuanJiaInfoAppById
(
ZhuanJiaInfoAppVo
zhuanJiaInfoAppVo
){
ZhuanJiaInfoAppVo
res
=
new
ZhuanJiaInfoAppVo
();
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoAppVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/getZhuanJiaInfoAppById",jsonString,null);*/
return
res
;
}
public
ZhuanJiaInfoAppVo
saveZhuanJiaInfoApp
(
ZhuanJiaInfoAppVo
zhuanJiaInfoAppVo
){
ZhuanJiaInfoAppVo
res
=
new
ZhuanJiaInfoAppVo
();
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoAppVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/saveZhuanJiaInfoApp",jsonString,null);*/
return
res
;
}
public
ZhuanJiaInfoAppVo
updateZhuanJiaInfoApp
(
ZhuanJiaInfoAppVo
zhuanJiaInfoAppVo
){
ZhuanJiaInfoAppVo
res
=
new
ZhuanJiaInfoAppVo
();
/* String jsonString = JsonUtils.toJsonString(zhuanJiaInfoAppVo);
res = RestUtils.sendPostRequest2Expert("/zjfw/zggrxxgl/updateZhuanJiaInfoApp",jsonString,null);*/
return
res
;
}
}
src/main/java/com/cnooc/expert/external/expert/auth/service/Test.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
external
.
expert
.
auth
.
service
;
public
class
Test
{
}
src/main/java/com/cnooc/expert/system/entity/pojo/ZhuanJiaUser.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
system
.
entity
.
pojo
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
/**
* @author: FuHongZhang
* @date 2025-10-30 18:00
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public
class
ZhuanJiaUser
{
private
static
final
long
serialVersionUID
=
-
1L
;
private
String
zhuanJiaGuid
;
private
String
zhuanJiaShiXiangGuid
;
private
String
zhuanJiaName
;
private
String
zhuanJiaCode
;
private
String
shenFenZheng
;
private
String
mobile
;
private
Short
zhuanJiaZhuangTai
;
private
Boolean
shiFouYiFaZhuanJia
;
private
String
suoShuBuMeng
;
//所在部门
}
src/main/java/com/cnooc/expert/system/entity/vo/LoginVO.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
system
.
entity
.
vo
;
import
lombok.*
;
import
javax.validation.constraints.Max
;
import
javax.validation.constraints.Min
;
/**
* 接收登录的form表单数据
* @Author: FuHongZhang
* @CreateTime: 2025-09-18 15:11
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public
class
LoginVO
{
private
String
phoneNumber
;
private
String
phoneCode
;
private
String
idNumber
;
private
String
password
;
@Max
(
value
=
2
,
message
=
"登录类型只能是1,手机验证码登录 2.身份证密码登录"
)
@Min
(
value
=
1
)
private
Integer
loginType
;
//图形验证码的key
private
String
key
;
//图片验证码
private
String
captcha
;
}
src/main/java/com/cnooc/expert/system/entity/vo/SmsConfig.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
system
.
entity
.
vo
;
import
lombok.Data
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
@Data
@Component
@ConfigurationProperties
(
prefix
=
"sms.config"
)
public
class
SmsConfig
{
private
String
apiUrl
;
private
String
ecName
;
private
String
apId
;
private
String
secretKey
;
private
String
sign
;
private
String
addSerial
;
}
src/main/java/com/cnooc/expert/system/entity/vo/SysCaptchaVO.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
system
.
entity
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
@Data
public
class
SysCaptchaVO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
String
key
;
//image base64
private
String
image
;
}
\ No newline at end of file
src/main/java/com/cnooc/expert/system/entity/vo/VerifyCodeVO.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
system
.
entity
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
/**
* @author: FuHongZhang
* @date 2025-10-22 17:03
*/
@Data
public
class
VerifyCodeVO
implements
Serializable
{
private
String
phoneNumber
;
private
String
phoneCode
;
}
src/main/java/com/cnooc/expert/system/entity/vo/ZhuanJiaInfoAppVo.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
system
.
entity
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
@Data
public
class
ZhuanJiaInfoAppVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
String
baseGuid
;
private
String
password
;
}
src/main/java/com/cnooc/expert/system/entity/vo/ZhuanJiaInfoVo.java
0 → 100644
View file @
4baf314d
package
com
.
cnooc
.
expert
.
system
.
entity
.
vo
;
import
lombok.Data
;
import
java.io.Serializable
;
@Data
public
class
ZhuanJiaInfoVo
implements
Serializable
{
private
String
baseGuid
;
private
String
mobile
;
private
String
shengfenzheng
;
private
String
password
;
}
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