Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
查尔斯-BUG万象集
Continew Admin
提交
05cb6097
Continew Admin
项目概览
查尔斯-BUG万象集
/
Continew Admin
11 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
分析
仓库
DevOps
项目成员
Pages
Continew Admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
05cb6097
编写于
10月 14, 2023
作者:
查尔斯-BUG万象集
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 支持第三方账号登录
Just Auth(开箱即用的整合第三方登录的开源组件,脱离繁琐的第三方登录 SDK,让登录变得 So easy!)
上级
71e20e9f
变更
41
隐藏空白更改
内联
并排
Showing
41 changed file
with
826 addition
and
49 deletion
+826
-49
README.md
README.md
+2
-1
continew-admin-common/pom.xml
continew-admin-common/pom.xml
+10
-0
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/justauth/JustAuthRedisStateCache.java
...admin/common/config/justauth/JustAuthRedisStateCache.java
+88
-0
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/justauth/JustAuthStateConfiguration.java
...in/common/config/justauth/JustAuthStateConfiguration.java
+40
-0
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/CacheConsts.java
...va/top/charles7c/cnadmin/common/constant/CacheConsts.java
+5
-0
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/SysConsts.java
...java/top/charles7c/cnadmin/common/constant/SysConsts.java
+10
-0
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/helper/LoginHelper.java
...top/charles7c/cnadmin/common/util/helper/LoginHelper.java
+5
-2
continew-admin-monitor/src/main/java/top/charles7c/cnadmin/monitor/interceptor/LogInterceptor.java
...charles7c/cnadmin/monitor/interceptor/LogInterceptor.java
+7
-2
continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/LoginService.java
...java/top/charles7c/cnadmin/auth/service/LoginService.java
+11
-0
continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java
...charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java
+80
-15
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserSocialMapper.java
...top/charles7c/cnadmin/system/mapper/UserSocialMapper.java
+42
-0
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserSocialDO.java
...p/charles7c/cnadmin/system/model/entity/UserSocialDO.java
+70
-0
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/RoleService.java
...ava/top/charles7c/cnadmin/system/service/RoleService.java
+10
-0
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java
...ava/top/charles7c/cnadmin/system/service/UserService.java
+9
-0
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserSocialService.java
...p/charles7c/cnadmin/system/service/UserSocialService.java
+47
-0
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/RoleServiceImpl.java
...harles7c/cnadmin/system/service/impl/RoleServiceImpl.java
+5
-0
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java
...harles7c/cnadmin/system/service/impl/UserServiceImpl.java
+8
-3
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserSocialServiceImpl.java
...7c/cnadmin/system/service/impl/UserSocialServiceImpl.java
+57
-0
continew-admin-system/src/main/resources/mapper/UserSocialMapper.xml
...min-system/src/main/resources/mapper/UserSocialMapper.xml
+11
-0
continew-admin-ui/src/api/auth/login.ts
continew-admin-ui/src/api/auth/login.ts
+8
-0
continew-admin-ui/src/router/constants.ts
continew-admin-ui/src/router/constants.ts
+1
-0
continew-admin-ui/src/router/guard/userLoginInfo.ts
continew-admin-ui/src/router/guard/userLoginInfo.ts
+1
-1
continew-admin-ui/src/router/index.ts
continew-admin-ui/src/router/index.ts
+8
-0
continew-admin-ui/src/store/modules/login/index.ts
continew-admin-ui/src/store/modules/login/index.ts
+12
-0
continew-admin-ui/src/utils/avatar.ts
continew-admin-ui/src/utils/avatar.ts
+8
-1
continew-admin-ui/src/views/login/index.vue
continew-admin-ui/src/views/login/index.vue
+22
-17
continew-admin-ui/src/views/login/locale/en-US.ts
continew-admin-ui/src/views/login/locale/en-US.ts
+1
-0
continew-admin-ui/src/views/login/locale/zh-CN.ts
continew-admin-ui/src/views/login/locale/zh-CN.ts
+1
-0
continew-admin-ui/src/views/login/social/index.vue
continew-admin-ui/src/views/login/social/index.vue
+67
-0
continew-admin-ui/src/views/system/user/index.vue
continew-admin-ui/src/views/system/user/index.vue
+1
-1
continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/AuthController.java
...rles7c/cnadmin/webapi/controller/auth/AuthController.java
+4
-3
continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/SocialAuthController.java
.../cnadmin/webapi/controller/auth/SocialAuthController.java
+89
-0
continew-admin-webapi/src/main/resources/config/application-dev.yml
...dmin-webapi/src/main/resources/config/application-dev.yml
+20
-0
continew-admin-webapi/src/main/resources/config/application-prod.yml
...min-webapi/src/main/resources/config/application-prod.yml
+20
-0
continew-admin-webapi/src/main/resources/config/application.yml
...ew-admin-webapi/src/main/resources/config/application.yml
+0
-2
continew-admin-webapi/src/main/resources/db/changelog/db.changelog-master.yaml
.../src/main/resources/db/changelog/db.changelog-master.yaml
+6
-0
continew-admin-webapi/src/main/resources/db/changelog/v1.0.0/continew-admin_table.sql
...in/resources/db/changelog/v1.0.0/continew-admin_table.sql
+1
-1
continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_column.sql
...n/resources/db/changelog/v1.3.0/continew-admin_column.sql
+2
-0
continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_data.sql
...ain/resources/db/changelog/v1.3.0/continew-admin_data.sql
+2
-0
continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_table.sql
...in/resources/db/changelog/v1.3.0/continew-admin_table.sql
+12
-0
pom.xml
pom.xml
+23
-0
未找到文件。
README.md
浏览文件 @
05cb6097
...
...
@@ -72,7 +72,7 @@ ContiNew Admin (Continue New Admin)中后台管理框架/脚手架,持续
> **Note**
> 更多功能和优化正在赶来💦,最新项目计划和进展请关注 [GitHub Project](https://github.com/Charles7c/continew-admin/projects) 和 [CHANGELOG.md](https://github.com/Charles7c/continew-admin/blob/dev/CHANGELOG.md)。
-
用户管理:提供用户的相关配置,新增用户后,默认密码为 123456
-
用户管理:提供用户的相关配置,新增用户后,默认密码为 123456
,且支持第三方账号登录
-
部门管理:可配置系统组织架构,树形表格展示
-
角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限
-
菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单
...
...
@@ -235,6 +235,7 @@ pnpm dev
|
<a
href=
"https://github.com/liquibase/liquibase"
target=
"_blank"
>
Liquibase
</a>
| 4.9.1 | 用于管理数据库版本,跟踪、管理和应用数据库变化。 |
|
<a
href=
"https://redis.io/"
target=
"_blank"
>
Redis
</a>
| 6.2.7 | 高性能的 key-value 数据库。 |
|
<a
href=
"https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D"
target=
"_blank"
>
Redisson
</a>
| 3.20.1 | 不仅仅是一个 Redis Java 客户端,同其他 Redis Java 客户端有着很大的区别,相比之下其他客户端提供的功能还仅仅停留在作为数据库驱动层面上,比如仅针对 Redis 提供连接方式,发送命令和处理返回结果等。而 Redisson 充分的利用了 Redis 键值数据库提供的一系列优势,基于 Java 实用工具包中常用接口,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。 |
|
<a
href=
"https://justauth.cn/"
target=
"_blank"
>
Just Auth
</a>
| 1.16.5 | 开箱即用的整合第三方登录的开源组件,脱离繁琐的第三方登录 SDK,让登录变得 So easy! |
|
<a
href=
"https://easyexcel.opensource.alibaba.com/"
target=
"_blank"
>
Easy Excel
</a>
| 3.3.2 | 一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。 |
| Easy Captcha | 1.6.2 | Java 图形验证码,支持 gif、中文、算术等类型,可用于 Java Web、JavaSE 等项目。 |
|
<a
href=
"https://doc.xiaominfo.com/"
target=
"_blank"
>
Knife4j
</a>
| 4.3.0 | 前身是 swagger-bootstrap-ui,集 Swagger2 和 OpenAPI3 为一体的增强解决方案。本项目使用的是
<a
href=
"https://gitee.com/xiaoym/swagger-bootstrap-ui-demo/tree/master/knife4j-springdoc-openapi-demo"
target=
"_blank"
>
knife4j-openapi3-spring-boot-starter
</a>
基于 OpenAPI3 规范,在 Spring Boot < 3.0.0-M1 的单体架构下可以直接引用此 starter,该模块包含了 UI 部分,底层基于 springdoc-openapi 项目。 |
...
...
continew-admin-common/pom.xml
浏览文件 @
05cb6097
...
...
@@ -115,6 +115,16 @@ limitations under the License.
</dependency>
<!-- ################ 工具库相关 ################ -->
<!-- Just Auth(开箱即用的整合第三方登录的开源组件,脱离繁琐的第三方登录 SDK,让登录变得 So easy!) -->
<dependency>
<groupId>
com.xkcoding.justauth
</groupId>
<artifactId>
justauth-spring-boot-starter
</artifactId>
</dependency>
<dependency>
<groupId>
me.zhyd.oauth
</groupId>
<artifactId>
JustAuth
</artifactId>
</dependency>
<!-- Easy Excel(一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具) -->
<dependency>
<groupId>
com.alibaba
</groupId>
...
...
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/justauth/JustAuthRedisStateCache.java
0 → 100644
浏览文件 @
05cb6097
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
top.charles7c.cnadmin.common.config.justauth
;
import
java.time.Duration
;
import
top.charles7c.cnadmin.common.constant.CacheConsts
;
import
top.charles7c.cnadmin.common.util.RedisUtils
;
import
me.zhyd.oauth.cache.AuthStateCache
;
/**
* Just Auth 自定义 State 缓存实现(Redis)
*
* @author Charles7c
* @since 2023/10/8 22:17
*/
public
class
JustAuthRedisStateCache
implements
AuthStateCache
{
/**
* 存入缓存
*
* @param key
* 缓存 key
* @param value
* 缓存内容
*/
@Override
public
void
cache
(
String
key
,
String
value
)
{
// 参考:在 JustAuth 中,内置了一个基于 map 的 state 缓存器,默认缓存有效期为 3 分钟
RedisUtils
.
setCacheObject
(
RedisUtils
.
formatKey
(
CacheConsts
.
SOCIAL_AUTH_STATE_KEY_PREFIX
,
key
),
value
,
Duration
.
ofMinutes
(
3
));
}
/**
* 存入缓存
*
* @param key
* 缓存 key
* @param value
* 缓存内容
* @param timeout
* 指定缓存过期时间(毫秒)
*/
@Override
public
void
cache
(
String
key
,
String
value
,
long
timeout
)
{
RedisUtils
.
setCacheObject
(
RedisUtils
.
formatKey
(
CacheConsts
.
SOCIAL_AUTH_STATE_KEY_PREFIX
,
key
),
value
,
Duration
.
ofMillis
(
timeout
));
}
/**
* 获取缓存内容
*
* @param key
* 缓存 key
* @return 缓存内容
*/
@Override
public
String
get
(
String
key
)
{
return
RedisUtils
.
getCacheObject
(
RedisUtils
.
formatKey
(
CacheConsts
.
SOCIAL_AUTH_STATE_KEY_PREFIX
,
key
));
}
/**
* 是否存在 key,如果对应 key 的 value 值已过期,也返回 false
*
* @param key
* 缓存 key
* @return true:存在 key,并且 value 没过期;false:key 不存在或者已过期
*/
@Override
public
boolean
containsKey
(
String
key
)
{
return
RedisUtils
.
hasKey
(
RedisUtils
.
formatKey
(
CacheConsts
.
SOCIAL_AUTH_STATE_KEY_PREFIX
,
key
));
}
}
\ No newline at end of file
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/config/justauth/JustAuthStateConfiguration.java
0 → 100644
浏览文件 @
05cb6097
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
top.charles7c.cnadmin.common.config.justauth
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
me.zhyd.oauth.cache.AuthStateCache
;
/**
* Just Auth State 缓存配置
*
* @author Charles7c
* @since 2023/10/8 22:17
*/
@Configuration
public
class
JustAuthStateConfiguration
{
/**
* Just Auth State 缓存 Redis 适配
*/
@Bean
public
AuthStateCache
authStateCache
()
{
return
new
JustAuthRedisStateCache
();
}
}
\ No newline at end of file
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/CacheConsts.java
浏览文件 @
05cb6097
...
...
@@ -67,4 +67,9 @@ public class CacheConsts {
* 仪表盘缓存键前缀
*/
public
static
final
String
DASHBOARD_KEY_PREFIX
=
"DASHBOARD"
;
/**
* 社交身份认证状态键前缀
*/
public
static
final
String
SOCIAL_AUTH_STATE_KEY_PREFIX
=
"SOCIAL_AUTH_STATE"
;
}
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/SysConsts.java
浏览文件 @
05cb6097
...
...
@@ -33,6 +33,11 @@ public class SysConsts {
*/
public
static
final
String
ADMIN_ROLE_CODE
=
"admin"
;
/**
* 顶级部门 ID
*/
public
static
final
Long
SUPER_DEPT_ID
=
1L
;
/**
* 顶级父 ID
*/
...
...
@@ -53,6 +58,11 @@ public class SysConsts {
*/
public
static
final
String
LOGIN_URI
=
"/auth/login"
;
/**
* 退出 URI
*/
public
static
final
String
LOGOUT_URI
=
"/auth/logout"
;
/**
* VO 描述类字段后缀
*/
...
...
continew-admin-common/src/main/java/top/charles7c/cnadmin/common/util/helper/LoginHelper.java
浏览文件 @
05cb6097
...
...
@@ -53,8 +53,9 @@ public class LoginHelper {
*
* @param loginUser
* 登录用户信息
* @return 令牌
*/
public
static
void
login
(
LoginUser
loginUser
)
{
public
static
String
login
(
LoginUser
loginUser
)
{
// 记录登录信息
HttpServletRequest
request
=
ServletUtils
.
getRequest
();
loginUser
.
setClientIp
(
ServletUtil
.
getClientIP
(
request
));
...
...
@@ -65,8 +66,10 @@ public class LoginHelper {
// 登录并缓存用户信息
StpUtil
.
login
(
loginUser
.
getId
());
SaHolder
.
getStorage
().
set
(
CacheConsts
.
LOGIN_USER_KEY
,
loginUser
);
loginUser
.
setToken
(
StpUtil
.
getTokenValue
());
String
tokenValue
=
StpUtil
.
getTokenValue
();
loginUser
.
setToken
(
tokenValue
);
StpUtil
.
getTokenSession
().
set
(
CacheConsts
.
LOGIN_USER_KEY
,
loginUser
);
return
tokenValue
;
}
/**
...
...
continew-admin-monitor/src/main/java/top/charles7c/cnadmin/monitor/interceptor/LogInterceptor.java
浏览文件 @
05cb6097
...
...
@@ -215,11 +215,16 @@ public class LogInterceptor implements HandlerInterceptor {
private
void
logRequest
(
LogDO
logDO
,
HttpServletRequest
request
)
{
logDO
.
setRequestUrl
(
StrUtil
.
isBlank
(
request
.
getQueryString
())
?
request
.
getRequestURL
().
toString
()
:
request
.
getRequestURL
().
append
(
StringConsts
.
QUESTION_MARK
).
append
(
request
.
getQueryString
()).
toString
());
logDO
.
setRequestMethod
(
request
.
getMethod
());
String
method
=
request
.
getMethod
();
logDO
.
setRequestMethod
(
method
);
logDO
.
setRequestHeaders
(
this
.
desensitize
(
ServletUtil
.
getHeaderMap
(
request
)));
String
requestBody
=
this
.
getRequestBody
(
request
);
logDO
.
setCreateUser
(
ObjectUtil
.
defaultIfNull
(
logDO
.
getCreateUser
(),
LoginHelper
.
getUserId
()));
if
(
null
==
logDO
.
getCreateUser
()
&&
SysConsts
.
LOGIN_URI
.
equals
(
request
.
getRequestURI
()))
{
String
requestURI
=
request
.
getRequestURI
();
if
(
requestURI
.
startsWith
(
"/auth"
)
&&
!
SysConsts
.
LOGOUT_URI
.
equals
(
requestURI
))
{
logDO
.
setCreateUser
(
null
);
}
if
(
null
==
logDO
.
getCreateUser
()
&&
SysConsts
.
LOGIN_URI
.
equals
(
requestURI
))
{
LoginRequest
loginRequest
=
JSONUtil
.
toBean
(
requestBody
,
LoginRequest
.
class
);
logDO
.
setCreateUser
(
ExceptionUtils
.
exToNull
(()
->
userService
.
getByUsername
(
loginRequest
.
getUsername
()).
getId
()));
...
...
continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/LoginService.java
浏览文件 @
05cb6097
...
...
@@ -20,6 +20,8 @@ import java.util.List;
import
top.charles7c.cnadmin.auth.model.vo.RouteVO
;
import
me.zhyd.oauth.model.AuthUser
;
/**
* 登录业务接口
*
...
...
@@ -39,6 +41,15 @@ public interface LoginService {
*/
String
login
(
String
username
,
String
password
);
/**
* 社交身份登录
*
* @param authUser
* 社交身份信息
* @return 令牌
*/
String
socialLogin
(
AuthUser
authUser
);
/**
* 构建路由树
*
...
...
continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java
浏览文件 @
05cb6097
...
...
@@ -16,6 +16,7 @@
package
top.charles7c.cnadmin.auth.service.impl
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.stream.Collectors
;
...
...
@@ -23,32 +24,38 @@ import lombok.RequiredArgsConstructor;
import
org.springframework.stereotype.Service
;
import
cn.dev33.satoken.stp.StpUtil
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.lang.tree.Tree
;
import
cn.hutool.core.lang.tree.TreeNodeConfig
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.RandomUtil
;
import
cn.hutool.core.util.ReUtil
;
import
cn.hutool.json.JSONUtil
;
import
top.charles7c.cnadmin.auth.model.vo.MetaVO
;
import
top.charles7c.cnadmin.auth.model.vo.RouteVO
;
import
top.charles7c.cnadmin.auth.service.LoginService
;
import
top.charles7c.cnadmin.auth.service.PermissionService
;
import
top.charles7c.cnadmin.common.annotation.TreeField
;
import
top.charles7c.cnadmin.common.constant.RegexConsts
;
import
top.charles7c.cnadmin.common.constant.SysConsts
;
import
top.charles7c.cnadmin.common.enums.DisEnableStatusEnum
;
import
top.charles7c.cnadmin.common.enums.GenderEnum
;
import
top.charles7c.cnadmin.common.enums.MenuTypeEnum
;
import
top.charles7c.cnadmin.common.model.dto.LoginUser
;
import
top.charles7c.cnadmin.common.util.SecureUtils
;
import
top.charles7c.cnadmin.common.util.TreeUtils
;
import
top.charles7c.cnadmin.common.util.helper.LoginHelper
;
import
top.charles7c.cnadmin.common.util.validate.CheckUtils
;
import
top.charles7c.cnadmin.system.model.entity.RoleDO
;
import
top.charles7c.cnadmin.system.model.entity.UserDO
;
import
top.charles7c.cnadmin.system.model.entity.UserSocialDO
;
import
top.charles7c.cnadmin.system.model.vo.DeptDetailVO
;
import
top.charles7c.cnadmin.system.model.vo.MenuVO
;
import
top.charles7c.cnadmin.system.service.DeptService
;
import
top.charles7c.cnadmin.system.service.MenuService
;
import
top.charles7c.cnadmin.system.service.RoleService
;
import
top.charles7c.cnadmin.system.service.UserService
;
import
top.charles7c.cnadmin.system.service.*
;
import
me.zhyd.oauth.model.AuthUser
;
/**
* 登录业务实现
...
...
@@ -65,6 +72,8 @@ public class LoginServiceImpl implements LoginService {
private
final
RoleService
roleService
;
private
final
MenuService
menuService
;
private
final
PermissionService
permissionService
;
private
final
UserRoleService
userRoleService
;
private
final
UserSocialService
userSocialService
;
@Override
public
String
login
(
String
username
,
String
password
)
{
...
...
@@ -72,16 +81,44 @@ public class LoginServiceImpl implements LoginService {
CheckUtils
.
throwIfNull
(
user
,
"用户名或密码错误"
);
Long
userId
=
user
.
getId
();
CheckUtils
.
throwIfNotEqual
(
SecureUtils
.
md5Salt
(
password
,
userId
.
toString
()),
user
.
getPassword
(),
"用户名或密码错误"
);
CheckUtils
.
throwIfEqual
(
DisEnableStatusEnum
.
DISABLE
,
user
.
getStatus
(),
"此账号已被禁用,如有疑问,请联系管理员"
);
DeptDetailVO
deptDetailVO
=
deptService
.
get
(
user
.
getDeptId
());
CheckUtils
.
throwIfEqual
(
DisEnableStatusEnum
.
DISABLE
,
deptDetailVO
.
getStatus
(),
"此账号部门已被禁用,如有疑问,请联系管理员"
);
// 登录并缓存用户信息
LoginUser
loginUser
=
BeanUtil
.
copyProperties
(
user
,
LoginUser
.
class
);
loginUser
.
setPermissions
(
permissionService
.
listPermissionByUserId
(
userId
));
loginUser
.
setRoleCodes
(
permissionService
.
listRoleCodeByUserId
(
userId
));
loginUser
.
setRoles
(
roleService
.
listByUserId
(
userId
));
LoginHelper
.
login
(
loginUser
);
return
StpUtil
.
getTokenValue
();
this
.
checkUserStatus
(
user
);
return
this
.
login
(
user
);
}
@Override
public
String
socialLogin
(
AuthUser
authUser
)
{
String
source
=
authUser
.
getSource
();
String
openId
=
authUser
.
getUuid
();
UserSocialDO
userSocial
=
userSocialService
.
getBySourceAndOpenId
(
source
,
openId
);
UserDO
user
;
if
(
null
==
userSocial
)
{
String
username
=
authUser
.
getUsername
();
boolean
isMatch
=
ReUtil
.
isMatch
(
RegexConsts
.
USERNAME
,
username
);
UserDO
existsUser
=
userService
.
getByUsername
(
username
);
if
(
null
!=
existsUser
||
!
isMatch
)
{
username
=
RandomUtil
.
randomString
(
RandomUtil
.
BASE_CHAR
,
5
)
+
IdUtil
.
fastSimpleUUID
();
}
user
=
new
UserDO
();
user
.
setUsername
(
username
);
user
.
setNickname
(
authUser
.
getNickname
());
user
.
setGender
(
GenderEnum
.
valueOf
(
authUser
.
getGender
().
name
()));
user
.
setAvatar
(
authUser
.
getAvatar
());
user
.
setDeptId
(
SysConsts
.
SUPER_DEPT_ID
);
Long
userId
=
userService
.
save
(
user
);
RoleDO
role
=
roleService
.
getByCode
(
SysConsts
.
ADMIN_ROLE_CODE
);
userRoleService
.
save
(
Collections
.
singletonList
(
role
.
getId
()),
userId
);
userSocial
=
new
UserSocialDO
();
userSocial
.
setUserId
(
userId
);
userSocial
.
setSource
(
source
);
userSocial
.
setOpenId
(
openId
);
}
else
{
user
=
BeanUtil
.
toBean
(
userService
.
get
(
userSocial
.
getUserId
()),
UserDO
.
class
);
}
this
.
checkUserStatus
(
user
);
userSocial
.
setMetaJson
(
JSONUtil
.
toJsonStr
(
authUser
));
userSocial
.
setLastLoginTime
(
LocalDateTime
.
now
());
userSocialService
.
saveOrUpdate
(
userSocial
);
return
this
.
login
(
user
);
}
@Override
...
...
@@ -120,4 +157,32 @@ public class LoginServiceImpl implements LoginService {
});
return
BeanUtil
.
copyToList
(
treeList
,
RouteVO
.
class
);
}
/**
* 登录并缓存用户信息
*
* @param user
* 用户信息
* @return 令牌
*/
private
String
login
(
UserDO
user
)
{
Long
userId
=
user
.
getId
();
LoginUser
loginUser
=
BeanUtil
.
copyProperties
(
user
,
LoginUser
.
class
);
loginUser
.
setPermissions
(
permissionService
.
listPermissionByUserId
(
userId
));
loginUser
.
setRoleCodes
(
permissionService
.
listRoleCodeByUserId
(
userId
));
loginUser
.
setRoles
(
roleService
.
listByUserId
(
userId
));
return
LoginHelper
.
login
(
loginUser
);
}
/**
* 检查用户状态
*
* @param user
* 用户信息
*/
private
void
checkUserStatus
(
UserDO
user
)
{
CheckUtils
.
throwIfEqual
(
DisEnableStatusEnum
.
DISABLE
,
user
.
getStatus
(),
"此账号已被禁用,如有疑问,请联系管理员"
);
DeptDetailVO
deptDetailVO
=
deptService
.
get
(
user
.
getDeptId
());
CheckUtils
.
throwIfEqual
(
DisEnableStatusEnum
.
DISABLE
,
deptDetailVO
.
getStatus
(),
"此账号部门已被禁用,如有疑问,请联系管理员"
);
}
}
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/UserSocialMapper.java
0 → 100644
浏览文件 @
05cb6097
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
top.charles7c.cnadmin.system.mapper
;
import
org.apache.ibatis.annotations.Param
;
import
top.charles7c.cnadmin.common.base.BaseMapper
;
import
top.charles7c.cnadmin.system.model.entity.UserSocialDO
;
/**
* 用户社会化关联 Mapper
*
* @author Charles7c
* @since 2023/10/11 22:10
*/
public
interface
UserSocialMapper
extends
BaseMapper
<
UserSocialDO
>
{
/**
* 根据来源和开放 ID 查询
*
* @param source
* 来源
* @param openId
* 开放 ID
* @return 用户社会化关联信息
*/
UserSocialDO
selectBySourceAndOpenId
(
@Param
(
"source"
)
String
source
,
@Param
(
"openId"
)
String
openId
);
}
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/UserSocialDO.java
0 → 100644
浏览文件 @
05cb6097
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
top.charles7c.cnadmin.system.model.entity
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
import
lombok.Data
;
import
com.baomidou.mybatisplus.annotation.FieldFill
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableName
;
/**
* 用户社会化关联实体
*
* @author Charles7c
* @since 2023/10/11 22:10
*/
@Data
@TableName
(
"sys_user_social"
)
public
class
UserSocialDO
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 用户 ID
*/
private
Long
userId
;
/**
* 来源
*/
private
String
source
;
/**
* 开放 ID
*/
private
String
openId
;
/**
* 附加信息
*/
private
String
metaJson
;
/**
* 最后登录时间
*/
private
LocalDateTime
lastLoginTime
;
/**
* 创建时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
private
LocalDateTime
createTime
;
}
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/RoleService.java
浏览文件 @
05cb6097
...
...
@@ -22,6 +22,7 @@ import java.util.Set;
import
top.charles7c.cnadmin.common.base.BaseService
;
import
top.charles7c.cnadmin.common.model.dto.RoleDTO
;
import
top.charles7c.cnadmin.common.model.vo.LabelValueVO
;
import
top.charles7c.cnadmin.system.model.entity.RoleDO
;
import
top.charles7c.cnadmin.system.model.query.RoleQuery
;
import
top.charles7c.cnadmin.system.model.request.RoleRequest
;
import
top.charles7c.cnadmin.system.model.vo.RoleDetailVO
;
...
...
@@ -70,4 +71,13 @@ public interface RoleService extends BaseService<RoleVO, RoleDetailVO, RoleQuery
* @return 角色集合
*/
Set
<
RoleDTO
>
listByUserId
(
Long
userId
);
/**
* 根据角色编码查询
*
* @param code
* 角色编码
* @return 角色信息
*/
RoleDO
getByCode
(
String
code
);
}
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserService.java
浏览文件 @
05cb6097
...
...
@@ -37,6 +37,15 @@ import top.charles7c.cnadmin.system.model.vo.UserVO;
*/
public
interface
UserService
extends
BaseService
<
UserVO
,
UserDetailVO
,
UserQuery
,
UserRequest
>
{
/**
* 保存用户信息
*
* @param user
* 用户信息
* @return ID
*/
Long
save
(
UserDO
user
);
/**
* 上传头像
*
...
...
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/UserSocialService.java
0 → 100644
浏览文件 @
05cb6097
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
top.charles7c.cnadmin.system.service
;
import
top.charles7c.cnadmin.system.model.entity.UserSocialDO
;
/**
* 用户社会化关联业务接口
*
* @author Charles7c
* @since 2023/10/11 22:10
*/
public
interface
UserSocialService
{
/**
* 根据来源和开放 ID 查询
*
* @param source
* 来源
* @param openId
* 开放 ID
* @return 用户社会化关联信息
*/
UserSocialDO
getBySourceAndOpenId
(
String
source
,
String
openId
);
/**
* 保存
*
* @param userSocial
* 用户社会化关联信息
*/
void
saveOrUpdate
(
UserSocialDO
userSocial
);
}
\ No newline at end of file
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/RoleServiceImpl.java
浏览文件 @
05cb6097
...
...
@@ -178,6 +178,11 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
return
new
HashSet
<>(
BeanUtil
.
copyToList
(
roleList
,
RoleDTO
.
class
));
}
@Override
public
RoleDO
getByCode
(
String
code
)
{
return
baseMapper
.
lambdaQuery
().
eq
(
RoleDO:
:
getCode
,
code
).
one
();
}
/**
* 检查名称是否存在
*
...
...
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserServiceImpl.java
浏览文件 @
05cb6097
...
...
@@ -18,9 +18,7 @@ package top.charles7c.cnadmin.system.service.impl;
import
java.io.File
;
import
java.time.LocalDateTime
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.*
;
import
javax.annotation.Resource
;
...
...
@@ -82,6 +80,13 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
@Resource
private
DeptService
deptService
;
@Override
public
Long
save
(
UserDO
user
)
{
user
.
setStatus
(
DisEnableStatusEnum
.
ENABLE
);
baseMapper
.
insert
(
user
);
return
user
.
getId
();
}
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
Long
add
(
UserRequest
request
)
{
...
...
continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/UserSocialServiceImpl.java
0 → 100644
浏览文件 @
05cb6097
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
top.charles7c.cnadmin.system.service.impl
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
top.charles7c.cnadmin.system.mapper.UserSocialMapper
;
import
top.charles7c.cnadmin.system.model.entity.UserSocialDO
;
import
top.charles7c.cnadmin.system.service.UserSocialService
;
/**
* 用户社会化关联业务实现
*
* @author Charles7c
* @since 2023/10/11 22:10
*/
@Service
@RequiredArgsConstructor
public
class
UserSocialServiceImpl
implements
UserSocialService
{
private
final
UserSocialMapper
baseMapper
;
@Override
public
UserSocialDO
getBySourceAndOpenId
(
String
source
,
String
openId
)
{
return
baseMapper
.
selectBySourceAndOpenId
(
source
,
openId
);
}
@Override
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
saveOrUpdate
(
UserSocialDO
userSocial
)
{
if
(
null
==
userSocial
.
getCreateTime
())
{
baseMapper
.
insert
(
userSocial
);
}
else
{
baseMapper
.
lambdaUpdate
().
set
(
UserSocialDO:
:
getMetaJson
,
userSocial
.
getMetaJson
())
.
set
(
UserSocialDO:
:
getLastLoginTime
,
userSocial
.
getLastLoginTime
())
.
eq
(
UserSocialDO:
:
getSource
,
userSocial
.
getSource
()).
eq
(
UserSocialDO:
:
getOpenId
,
userSocial
.
getOpenId
())
.
update
();
}
}
}
continew-admin-system/src/main/resources/mapper/UserSocialMapper.xml
0 → 100644
浏览文件 @
05cb6097
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper
namespace=
"top.charles7c.cnadmin.system.mapper.UserSocialMapper"
>
<select
id=
"selectBySourceAndOpenId"
resultType=
"top.charles7c.cnadmin.system.model.entity.UserSocialDO"
>
SELECT t1.*
FROM `sys_user_social` AS t1
LEFT JOIN `sys_user` AS t2 ON t2.`id` = t1.`user_id`
WHERE t1.`source` = #{source} AND t1.`open_id` = #{openId}
</select>
</mapper>
\ No newline at end of file
continew-admin-ui/src/api/auth/login.ts
浏览文件 @
05cb6097
...
...
@@ -32,3 +32,11 @@ export function getUserInfo() {
export
function
listRoute
()
{
return
axios
.
get
<
RouteRecordNormalized
[]
>
(
`
${
BASE_URL
}
/route`
);
}
export
function
socialAuth
(
source
:
string
)
{
return
axios
.
get
<
string
>
(
`
${
BASE_URL
}
/
${
source
}
`
);
}
export
function
socialLogin
(
source
:
string
,
req
:
any
)
{
return
axios
.
post
<
LoginRes
>
(
`
${
BASE_URL
}
/
${
source
}
`
,
req
);
}
continew-admin-ui/src/router/constants.ts
浏览文件 @
05cb6097
export
const
WHITE_LIST
=
[
{
name
:
'
notFound
'
,
children
:
[]
},
{
name
:
'
login
'
,
children
:
[]
},
{
name
:
'
SocialCallback
'
,
children
:
[]
},
];
export
const
NOT_FOUND
=
{
...
...
continew-admin-ui/src/router/guard/userLoginInfo.ts
浏览文件 @
05cb6097
...
...
@@ -29,7 +29,7 @@ export default function setupUserLoginInfoGuard(router: Router) {
}
}
}
else
{
if
(
to
.
name
===
'
login
'
)
{
if
(
to
.
name
===
'
login
'
||
to
.
name
===
'
SocialCallback
'
)
{
next
();
return
;
}
...
...
continew-admin-ui/src/router/index.ts
浏览文件 @
05cb6097
...
...
@@ -29,6 +29,14 @@ const router = createRouter({
requiresAuth
:
false
,
},
},
{
path
:
'
/social/callback
'
,
name
:
'
SocialCallback
'
,
component
:
()
=>
import
(
'
@/views/login/social/index.vue
'
),
meta
:
{
requiresAuth
:
false
,
},
},
...
appRoutes
,
...
fixedRoutes
,
...
demoRoutes
,
...
...
continew-admin-ui/src/store/modules/login/index.ts
浏览文件 @
05cb6097
import
{
defineStore
}
from
'
pinia
'
;
import
{
login
as
userLogin
,
socialLogin
as
userSocialLogin
,
logout
as
userLogout
,
getUserInfo
,
LoginReq
,
...
...
@@ -52,6 +53,17 @@ const useLoginStore = defineStore('user', {
}
},
// 社交身份登录
async
socialLogin
(
source
:
string
,
req
:
any
)
{
try
{
const
res
=
await
userSocialLogin
(
source
,
req
);
setToken
(
res
.
data
.
token
);
}
catch
(
err
)
{
clearToken
();
throw
err
;
}
},
// 用户退出
async
logout
()
{
try
{
...
...
continew-admin-ui/src/utils/avatar.ts
浏览文件 @
05cb6097
...
...
@@ -8,7 +8,14 @@ export default function getAvatar(
)
{
if
(
avatar
)
{
const
baseUrl
=
import
.
meta
.
env
.
VITE_API_BASE_URL
;
return
`
${
baseUrl
}
/avatar/
${
avatar
}
`
;
if
(
!
avatar
.
startsWith
(
'
http://
'
)
&&
!
avatar
.
startsWith
(
'
https://
'
)
&&
!
avatar
.
startsWith
(
'
blob:
'
)
)
{
return
`
${
baseUrl
}
/avatar/
${
avatar
}
`
;
}
return
avatar
;
}
if
(
gender
===
1
)
{
...
...
continew-admin-ui/src/views/login/index.vue
浏览文件 @
05cb6097
...
...
@@ -11,21 +11,15 @@
<div
class=
"container"
>
<div
class=
"left-banner"
></div>
<div
class=
"login-card"
>
<div
class=
"title"
>
{{
$t
(
'
login.welcome
'
)
}}
{{
appStore
.
getTitle
}}
</div
>
<div
class=
"title"
>
{{
$t
(
'
login.welcome
'
)
}}
{{
appStore
.
getTitle
}}
</div
>
<EmailLogin
v-if=
"isEmailLogin"
/>
<a-tabs
v-else
class=
"account-tab"
default-active-key=
"1"
>
<a-tab-pane
key=
"1"
:title=
"$t('login.account')"
>
<a-tab-pane
key=
"1"
:title=
"$t('login.account')"
>
<AccountLogin
/>
</a-tab-pane>
<a-tab-pane
key=
"2"
:title=
"$t('login.phone')"
>
<a-tab-pane
key=
"2"
:title=
"$t('login.phone')"
>
<PhoneLogin
/>
</a-tab-pane>
</a-tabs>
...
...
@@ -40,8 +34,8 @@
<div
v-else
class=
"account app"
@
click=
"toggleLoginMode"
>
<icon-user
/>
{{
$t
(
'
login.account.txt
'
)
}}
</div>
<a-tooltip
content=
"Gitee
(即将开放)
"
mini
>
<a
href=
"javascript: void(0);"
class=
"app
"
>
<a-tooltip
content=
"Gitee"
mini
>
<a
-link
class=
"app"
@
click=
"handleSocialAuth('gitee')
"
>
<svg
class=
"icon"
fill=
"#C71D23"
...
...
@@ -53,10 +47,10 @@
d=
"M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.016 0zm6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.592.592 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296Z"
/>
</svg>
</a>
</a
-link
>
</a-tooltip>
<a-tooltip
content=
"GitHub
(即将开放)
"
mini
>
<a
href=
"javascript: void(0);"
class=
"app
"
>
<a-tooltip
content=
"GitHub"
mini
>
<a
-link
class=
"app"
@
click=
"handleSocialAuth('github')
"
>
<svg
class=
"icon"
role=
"img"
...
...
@@ -67,7 +61,7 @@
d=
"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
</a>
</a
-link
>
</a-tooltip>
</div>
</div>
...
...
@@ -87,6 +81,7 @@
import
{
useAppStore
}
from
'
@/store
'
;
import
getFile
from
'
@/utils/file
'
;
import
useResponsive
from
'
@/hooks/responsive
'
;
import
{
socialAuth
}
from
'
@/api/auth/login
'
;
import
AccountLogin
from
'
./components/account-login.vue
'
;
import
PhoneLogin
from
'
./components/phone-login.vue
'
;
import
EmailLogin
from
'
./components/email-login.vue
'
;
...
...
@@ -96,6 +91,16 @@
useResponsive
(
true
);
const
isEmailLogin
=
ref
(
false
);
/**
* 第三方登录授权
*
* @param source 来源
*/
const
handleSocialAuth
=
async
(
source
:
string
)
=>
{
const
{
data
}
=
await
socialAuth
(
source
);
window
.
location
.
href
=
data
;
};
const
toggleLoginMode
=
()
=>
{
isEmailLogin
.
value
=
!
isEmailLogin
.
value
;
};
...
...
continew-admin-ui/src/views/login/locale/en-US.ts
浏览文件 @
05cb6097
...
...
@@ -4,6 +4,7 @@ export default {
'
login.phone
'
:
'
Phone Login
'
,
'
login.email
'
:
'
Email Login
'
,
'
login.other
'
:
'
Other Login
'
,
'
login.ing
'
:
'
Login...
'
,
'
login.account.placeholder.username
'
:
'
Please enter username
'
,
'
login.account.placeholder.password
'
:
'
Please enter password
'
,
...
...
continew-admin-ui/src/views/login/locale/zh-CN.ts
浏览文件 @
05cb6097
...
...
@@ -4,6 +4,7 @@ export default {
'
login.phone
'
:
'
手机号登录
'
,
'
login.email
'
:
'
邮箱登录
'
,
'
login.other
'
:
'
其他登录方式
'
,
'
login.ing
'
:
'
登录中...
'
,
'
login.account.placeholder.username
'
:
'
请输入用户名
'
,
'
login.account.placeholder.password
'
:
'
请输入密码
'
,
...
...
continew-admin-ui/src/views/login/social/index.vue
0 → 100644
浏览文件 @
05cb6097
<
template
>
<a-spin
:loading=
"loading"
:tip=
"$t('login.ing')"
>
<div></div>
</a-spin>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
getCurrentInstance
,
ref
}
from
'
vue
'
;
import
{
useRoute
,
useRouter
}
from
'
vue-router
'
;
import
{
useLoginStore
}
from
'
@/store
'
;
import
{
useI18n
}
from
'
vue-i18n
'
;
const
{
proxy
}
=
getCurrentInstance
()
as
any
;
const
{
t
}
=
useI18n
();
const
route
=
useRoute
();
const
router
=
useRouter
();
const
loginStore
=
useLoginStore
();
const
loading
=
ref
(
false
);
const
source
=
route
.
query
.
source
as
string
;
/**
* 社会化身份登录
*/
const
handleSocialLogin
=
()
=>
{
if
(
loading
.
value
)
return
;
loading
.
value
=
true
;
const
{
redirect
,
...
othersQuery
}
=
router
.
currentRoute
.
value
.
query
;
loginStore
.
socialLogin
(
source
,
othersQuery
)
.
then
(()
=>
{
router
.
push
({
name
:
(
redirect
as
string
)
||
'
Workplace
'
,
});
proxy
.
$notification
.
success
(
t
(
'
login.success
'
));
})
.
catch
(()
=>
{
router
.
push
({
name
:
'
login
'
,
query
:
{
...
othersQuery
,
},
});
})
.
finally
(()
=>
{
loading
.
value
=
false
;
});
};
handleSocialLogin
();
</
script
>
<
script
lang=
"ts"
>
export
default
{
name
:
'
SocialCallback
'
,
};
</
script
>
<
style
scoped
lang=
"less"
>
div {
width: 150px;
height: 150px;
position: absolute;
left: 50%;
top: 45%;
margin-left: -50px;
margin-top: -50px;
}
</
style
>
continew-admin-ui/src/views/system/user/index.vue
浏览文件 @
05cb6097
...
...
@@ -147,7 +147,7 @@
>
<
template
#columns
>
<a-table-column
title=
"ID"
data-index=
"id"
/>
<a-table-column
title=
"用户名"
:width=
"1
15"
>
<a-table-column
title=
"用户名"
:width=
"1
20"
ellipsis
tooltip
>
<template
#cell
="
{ record }">
<a-link
@
click=
"toDetail(record.id)"
>
{{
record
.
username
...
...
continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/
Login
Controller.java
→
continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/
Auth
Controller.java
浏览文件 @
05cb6097
...
...
@@ -49,16 +49,17 @@ import top.charles7c.cnadmin.system.model.vo.UserDetailVO;
import
top.charles7c.cnadmin.system.service.UserService
;
/**
*
登录
API
*
认证
API
*
* @author Charles7c
* @since 2022/12/21 20:37
*/
@Tag
(
name
=
"登录 API"
)
@Log
(
module
=
"登录"
)
@Tag
(
name
=
"认证 API"
)
@RestController
@RequiredArgsConstructor
@RequestMapping
(
"/auth"
)
public
class
Login
Controller
{
public
class
Auth
Controller
{
private
final
LoginService
loginService
;
private
final
UserService
userService
;
...
...
continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/auth/SocialAuthController.java
0 → 100644
浏览文件 @
05cb6097
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
top.charles7c.cnadmin.webapi.controller.auth
;
import
lombok.RequiredArgsConstructor
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.enums.ParameterIn
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
org.springframework.web.bind.annotation.*
;
import
com.xkcoding.justauth.AuthRequestFactory
;
import
cn.dev33.satoken.annotation.SaIgnore
;
import
top.charles7c.cnadmin.auth.model.vo.LoginVO
;
import
top.charles7c.cnadmin.auth.service.LoginService
;
import
top.charles7c.cnadmin.common.exception.BadRequestException
;
import
top.charles7c.cnadmin.common.model.vo.R
;
import
top.charles7c.cnadmin.common.util.validate.ValidationUtils
;
import
top.charles7c.cnadmin.monitor.annotation.Log
;
import
me.zhyd.oauth.model.AuthCallback
;
import
me.zhyd.oauth.model.AuthResponse
;
import
me.zhyd.oauth.model.AuthUser
;
import
me.zhyd.oauth.request.AuthRequest
;
import
me.zhyd.oauth.utils.AuthStateUtils
;
/**
* 社交身份认证 API
*
* @author Charles7c
* @since 2023/10/8 22:52
*/
@Log
(
module
=
"登录"
)
@Tag
(
name
=
"社交身份认证 API"
)
@SaIgnore
@RestController
@RequiredArgsConstructor
@RequestMapping
(
"/auth"
)
public
class
SocialAuthController
{
private
final
LoginService
loginService
;
private
final
AuthRequestFactory
authRequestFactory
;
@Operation
(
summary
=
"社交身份登录授权"
,
description
=
"社交身份登录授权"
)
@Parameter
(
name
=
"source"
,
description
=
"来源"
,
example
=
"gitee"
,
in
=
ParameterIn
.
PATH
)
@GetMapping
(
"/{source}"
)
public
R
authorize
(
@PathVariable
String
source
)
{
AuthRequest
authRequest
=
this
.
getAuthRequest
(
source
);
return
R
.
ok
(
"操作成功"
,
authRequest
.
authorize
(
AuthStateUtils
.
createState
()));
}
@Operation
(
summary
=
"社交身份登录"
,
description
=
"社交身份登录"
)
@Parameter
(
name
=
"source"
,
description
=
"来源"
,
example
=
"gitee"
,
in
=
ParameterIn
.
PATH
)
@PostMapping
(
"/{source}"
)
public
LoginVO
login
(
@PathVariable
String
source
,
@RequestBody
AuthCallback
callback
)
{
AuthRequest
authRequest
=
this
.
getAuthRequest
(
source
);
AuthResponse
<
AuthUser
>
response
=
authRequest
.
login
(
callback
);
ValidationUtils
.
throwIf
(!
response
.
ok
(),
response
.
getMsg
());
AuthUser
authUser
=
response
.
getData
();
String
token
=
loginService
.
socialLogin
(
authUser
);
return
LoginVO
.
builder
().
token
(
token
).
build
();
}
private
AuthRequest
getAuthRequest
(
String
source
)
{
try
{
return
authRequestFactory
.
get
(
source
);
}
catch
(
Exception
e
)
{
throw
new
BadRequestException
(
String
.
format
(
"暂不支持 [%s] 登录"
,
source
));
}
}
}
\ No newline at end of file
continew-admin-webapi/src/main/resources/config/application-dev.yml
浏览文件 @
05cb6097
---
### 项目配置
project
:
# URL
url
:
http://localhost:5173
---
### 服务器配置
server
:
# HTTP 端口(默认 8080)
...
...
@@ -73,6 +78,21 @@ spring:
# 是否允许缓存空值(默认 true,表示允许,可以解决缓存穿透问题)
cache-null-values
:
true
---
### Just Auth 配置
justauth
:
enabled
:
true
type
:
GITEE
:
client-id
:
5d271b7f638941812aaf8bfc2e2f08f06d6235ef934e0e39537e2364eb8452c4
client-secret
:
1f7d08**********5b7**********29e
redirect-uri
:
${project.url}/social/callback?source=gitee
GITHUB
:
client-id
:
38080dad08cfbdfacca9
client-secret
:
1f7d08**********5b7**********29e
redirect-uri
:
${project.url}/social/callback?source=github
cache
:
type
:
custom
---
### 邮件配置
spring.mail
:
# 根据需要更换
...
...
continew-admin-webapi/src/main/resources/config/application-prod.yml
浏览文件 @
05cb6097
---
### 项目配置
project
:
# URL
url
:
https://cnadmin.charles7c.top
---
### 服务器配置
server
:
# HTTP 端口(默认 8080)
...
...
@@ -73,6 +78,21 @@ spring:
# 是否允许缓存空值(默认 true,表示允许,可以解决缓存穿透问题)
cache-null-values
:
true
---
### Just Auth 配置
justauth
:
enabled
:
true
type
:
GITEE
:
client-id
:
5d271b7f638941812aaf8bfc2e2f08f06d6235ef934e0e39537e2364eb8452c4
client-secret
:
1f7d08**********5b7**********29e
redirect-uri
:
${project.url}/social/callback?source=gitee
GITHUB
:
client-id
:
38080dad08cfbdfacca9
client-secret
:
1f7d08**********5b7**********29e
redirect-uri
:
${project.url}/social/callback?source=github
cache
:
type
:
custom
---
### 邮件配置
spring.mail
:
# 根据需要更换
...
...
continew-admin-webapi/src/main/resources/config/application.yml
浏览文件 @
05cb6097
...
...
@@ -8,8 +8,6 @@ project:
version
:
1.3.0-SNAPSHOT
# 描述
description
:
ContiNew Admin 中后台管理框架/脚手架,Continue New Admin,持续以最新流行技术栈构建,拥抱变化,迭代优化。
# URL
url
:
https://cnadmin.charles7c.top
# 基本包
basePackage
:
top.charles7c.cnadmin
## 作者信息配置
...
...
continew-admin-webapi/src/main/resources/db/changelog/db.changelog-master.yaml
浏览文件 @
05cb6097
...
...
@@ -17,3 +17,9 @@ databaseChangeLog:
file
:
db/changelog/v1.2.0/continew-admin_column.sql
-
include
:
file
:
db/changelog/v1.2.0/continew-admin_data.sql
-
include
:
file
:
db/changelog/v1.3.0/continew-admin_table.sql
-
include
:
file
:
db/changelog/v1.3.0/continew-admin_column.sql
-
include
:
file
:
db/changelog/v1.3.0/continew-admin_data.sql
continew-admin-webapi/src/main/resources/db/changelog/v1.0.0/continew-admin_table.sql
浏览文件 @
05cb6097
...
...
@@ -93,7 +93,7 @@ CREATE TABLE IF NOT EXISTS `sys_user` (
`is_system`
bit
(
1
)
NOT
NULL
DEFAULT
b
'0'
COMMENT
'是否为系统内置数据'
,
`pwd_reset_time`
datetime
DEFAULT
NULL
COMMENT
'最后一次修改密码时间'
,
`dept_id`
bigint
(
20
)
NOT
NULL
COMMENT
'部门ID'
,
`create_user`
bigint
(
20
)
NOT
NULL
COMMENT
'创建人'
,
`create_user`
bigint
(
20
)
DEFAULT
NULL
COMMENT
'创建人'
,
`create_time`
datetime
NOT
NULL
COMMENT
'创建时间'
,
`update_user`
bigint
(
20
)
DEFAULT
NULL
COMMENT
'修改人'
,
`update_time`
datetime
DEFAULT
NULL
COMMENT
'修改时间'
,
...
...
continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_column.sql
0 → 100644
浏览文件 @
05cb6097
-- liquibase formatted sql
continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_data.sql
0 → 100644
浏览文件 @
05cb6097
-- liquibase formatted sql
continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_table.sql
0 → 100644
浏览文件 @
05cb6097
-- liquibase formatted sql
-- changeset Charles7c:1
CREATE
TABLE
IF
NOT
EXISTS
`sys_user_social`
(
`source`
varchar
(
255
)
NOT
NULL
COMMENT
'来源'
,
`open_id`
varchar
(
255
)
NOT
NULL
COMMENT
'开放ID'
,
`user_id`
bigint
(
20
)
NOT
NULL
COMMENT
'用户ID'
,
`meta_json`
text
DEFAULT
NULL
COMMENT
'附加信息'
,
`last_login_time`
datetime
DEFAULT
NULL
COMMENT
'最后登录时间'
,
`create_time`
datetime
NOT
NULL
COMMENT
'创建时间'
,
UNIQUE
INDEX
`uk_source_open_id`
(
`source`
,
`open_id`
)
USING
BTREE
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COMMENT
=
'用户社会化关联表'
;
\ No newline at end of file
pom.xml
浏览文件 @
05cb6097
...
...
@@ -52,6 +52,7 @@ limitations under the License.
<p6spy.version>
3.9.1
</p6spy.version>
<!-- ### 工具库相关 ### -->
<justauth.version>
1.16.5
</justauth.version>
<easyexcel.version>
3.3.2
</easyexcel.version>
<ip2region.version>
2.7.15
</ip2region.version>
<knife4j.version>
4.3.0
</knife4j.version>
...
...
@@ -115,6 +116,28 @@ limitations under the License.
</dependency>
<!-- ################ 工具库相关 ################ -->
<!-- Just Auth(开箱即用的整合第三方登录的开源组件,脱离繁琐的第三方登录 SDK,让登录变得 So easy!) -->
<dependency>
<groupId>
com.xkcoding.justauth
</groupId>
<artifactId>
justauth-spring-boot-starter
</artifactId>
<version>
1.4.0
</version>
<exclusions>
<exclusion>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-core
</artifactId>
</exclusion>
<exclusion>
<groupId>
me.zhyd.oauth
</groupId>
<artifactId>
JustAuth
</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
me.zhyd.oauth
</groupId>
<artifactId>
JustAuth
</artifactId>
<version>
${justauth.version}
</version>
</dependency>
<!-- Easy Excel(一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具) -->
<dependency>
<groupId>
com.alibaba
</groupId>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录