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
73c193bb
Commit
73c193bb
authored
Nov 13, 2025
by
weisong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
merge login code to this project
parent
a90b10d0
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
509 additions
and
6 deletions
+509
-6
src/main/java/com/cnooc/expert/common/constant/TokenConstants.java
+36
-0
src/main/java/com/cnooc/expert/common/exception/BusinessException.java
+140
-6
src/main/java/com/cnooc/expert/common/interceptor/LoginInterceptor.java
+76
-0
src/main/java/com/cnooc/expert/common/utils/JwtUtils.java
+71
-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/TheWebMvcConfigurer.java
+16
-0
src/main/java/com/cnooc/expert/system/entity/pojo/ZhuanJiaUser.java
+40
-0
No files found.
src/main/java/com/cnooc/expert/common/constant/TokenConstants.java
0 → 100644
View file @
73c193bb
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/exception/BusinessException.java
View file @
73c193bb
...
...
@@ -2,21 +2,154 @@ package com.cnooc.expert.common.exception;
import
lombok.Getter
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
java.util.Map
;
/**
* 通用业务自定义异常
* 适用于参数校验、业务规则冲突、权限校验等所有业务层面的异常场景
*/
@Getter
@Slf4j
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
.
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
.
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/interceptor/LoginInterceptor.java
0 → 100644
View file @
73c193bb
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/JwtUtils.java
0 → 100644
View file @
73c193bb
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
com.alibaba.fastjson.JSON
;
import
com.cnooc.expertmanageminiapp.common.constant.TokenConstants
;
import
io.jsonwebtoken.*
;
import
lombok.extern.slf4j.Slf4j
;
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/UserUtils.java
0 → 100644
View file @
73c193bb
package
com
.
cnooc
.
expert
.
common
.
utils
;
import
com.cnooc.expertmanageminiapp.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 @
73c193bb
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/TheWebMvcConfigurer.java
View file @
73c193bb
package
com
.
cnooc
.
expert
.
config
;
import
com.cnooc.expert.common.interceptor.LoginInterceptor
;
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.Configuration
;
import
org.springframework.web.servlet.config.annotation.InterceptorRegistry
;
...
...
@@ -9,8 +11,22 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public
class
TheWebMvcConfigurer
implements
WebMvcConfigurer
{
@Autowired
private
LoginInterceptor
loginInterceptor
;
@Override
public
void
addInterceptors
(
InterceptorRegistry
registry
)
{
// 注册登录拦截器,并设置拦截路径和排除路径
registry
.
addInterceptor
(
loginInterceptor
)
.
addPathPatterns
(
"/**"
)
// 拦截所有路径
.
excludePathPatterns
(
// 排除一些路径
"/sys/**"
,
"/verify/**"
,
"/person/**"
,
"/text/**"
);
registry
.
addInterceptor
(
webAuthInterceptor
());
}
...
...
src/main/java/com/cnooc/expert/system/entity/pojo/ZhuanJiaUser.java
0 → 100644
View file @
73c193bb
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
;
//所在部门
}
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