init
This commit is contained in:
152
jeelowcode-service/jeelowcode-service-system-biz/pom.xml
Normal file
152
jeelowcode-service/jeelowcode-service-system-biz/pom.xml
Normal file
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>jeelowcode-service</artifactId>
|
||||
<version>${jeelowcode.version}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jeelowcode-service-system-biz</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
system 模块下,我们放通用业务,支撑上层的核心业务。
|
||||
例如说:用户、部门、权限、数据字典等等
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>jeelowcode-service-system-api</artifactId>
|
||||
<version>${jeelowcode.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>jeelowcode-service-infra-api</artifactId>
|
||||
<version>${jeelowcode.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-biz-operatelog</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-biz-dict</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-biz-data-permission</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-biz-ip</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Job 定时任务相关 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-job</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息队列相关 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-mq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>tool-spring-boot-starter-captcha</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 三方云服务相关 -->
|
||||
<dependency>
|
||||
<groupId>com.xingyuv</groupId>
|
||||
<artifactId>spring-boot-starter-justauth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>wx-java-mp-spring-boot-starter</artifactId> <!-- 微信登录(公众号) -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId> <!-- 微信登录(小程序) -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId> <!-- 短信(阿里云) -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-dysmsapi</artifactId> <!-- 短信(阿里云) -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-sms</artifactId> <!-- 短信(腾讯云) -->
|
||||
</dependency>
|
||||
|
||||
<!-- 低代码 -->
|
||||
<dependency>
|
||||
<groupId>com.jeelowcode</groupId>
|
||||
<artifactId>jeelowcode-module-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.stuxuhai</groupId>
|
||||
<artifactId>jpinyin</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.dto.AdminUserRespDTO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import com.jeelowcode.service.system.service.IDeptService;
|
||||
import com.jeelowcode.service.system.service.IAdminUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
/**
|
||||
* Admin 用户 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiAdminUserApiImpl implements IApiAdminUserApi {
|
||||
|
||||
@Resource
|
||||
private IAdminUserService userService;
|
||||
@Resource
|
||||
private IDeptService deptService;
|
||||
|
||||
@Override
|
||||
public AdminUserRespDTO getUser(Long id) {
|
||||
AdminUserDO user = userService.getUser(id);
|
||||
return BeanUtils.toBean(user, AdminUserRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AdminUserRespDTO> getUserList(Collection<Long> ids) {
|
||||
List<AdminUserDO> users = userService.getUserList(ids);
|
||||
return BeanUtils.toBean(users, AdminUserRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AdminUserRespDTO> getUserListByDeptIds(Collection<Long> deptIds) {
|
||||
List<AdminUserDO> users = userService.getUserListByDeptIds(deptIds);
|
||||
return BeanUtils.toBean(users, AdminUserRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AdminUserRespDTO> getUserListByPostIds(Collection<Long> postIds) {
|
||||
List<AdminUserDO> users = userService.getUserListByPostIds(postIds);
|
||||
return BeanUtils.toBean(users, AdminUserRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateUserList(Collection<Long> ids) {
|
||||
userService.validateUserList(ids);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.dto.DeptRespDTO;
|
||||
import com.jeelowcode.service.system.entity.DeptDO;
|
||||
import com.jeelowcode.service.system.service.IDeptService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiDeptApiImpl implements IApiDeptApi {
|
||||
|
||||
@Resource
|
||||
private IDeptService deptService;
|
||||
|
||||
@Override
|
||||
public DeptRespDTO getDept(Long id) {
|
||||
DeptDO dept = deptService.getDept(id);
|
||||
return BeanUtils.toBean(dept, DeptRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeptRespDTO> getDeptList(Collection<Long> ids) {
|
||||
List<DeptDO> depts = deptService.getDeptList(ids);
|
||||
return BeanUtils.toBean(depts, DeptRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateDeptList(Collection<Long> ids) {
|
||||
deptService.validateDeptList(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeptRespDTO> getChildDeptList(Long id) {
|
||||
List<DeptDO> childDeptList = deptService.getChildDeptList(id);
|
||||
return BeanUtils.toBean(childDeptList, DeptRespDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.dto.DictDataRespDTO;
|
||||
import com.jeelowcode.service.system.entity.DictDataDO;
|
||||
import com.jeelowcode.service.system.service.IDictDataService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 字典数据 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiDictDataApiImpl implements IApiDictDataApi {
|
||||
|
||||
@Resource
|
||||
private IDictDataService dictDataService;
|
||||
|
||||
@Override
|
||||
public void validateDictDataList(String dictType, Collection<String> values) {
|
||||
dictDataService.validateDictDataList(dictType, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictDataRespDTO getDictData(String dictType, String value) {
|
||||
DictDataDO dictData = dictDataService.getDictData(dictType, value);
|
||||
return BeanUtils.toBean(dictData, DictDataRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictDataRespDTO parseDictData(String dictType, String label) {
|
||||
DictDataDO dictData = dictDataService.parseDictData(dictType, label);
|
||||
return BeanUtils.toBean(dictData, DictDataRespDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.ErrorCodeAutoGenerateReqDTO;
|
||||
import com.jeelowcode.service.system.dto.ErrorCodeRespDTO;
|
||||
import com.jeelowcode.service.system.service.IErrorCodeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 错误码 Api 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiErrorCodeApiImpl implements IApiErrorCodeApi {
|
||||
|
||||
@Resource
|
||||
private IErrorCodeService errorCodeService;
|
||||
|
||||
@Override
|
||||
public void autoGenerateErrorCodeList(List<ErrorCodeAutoGenerateReqDTO> autoGenerateDTOs) {
|
||||
errorCodeService.autoGenerateErrorCodes(autoGenerateDTOs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ErrorCodeRespDTO> getErrorCodeList(String applicationName, LocalDateTime minUpdateTime) {
|
||||
return errorCodeService.getErrorCodeList(applicationName, minUpdateTime);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.LoginLogCreateReqDTO;
|
||||
import com.jeelowcode.service.system.service.ILoginLogService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 登录日志的 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ApiLoginLogApiImpl implements IApiLoginLogApi {
|
||||
|
||||
@Resource
|
||||
private ILoginLogService loginLogService;
|
||||
|
||||
@Override
|
||||
public void createLoginLog(LoginLogCreateReqDTO reqDTO) {
|
||||
loginLogService.createLoginLog(reqDTO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.MailSendSingleToUserReqDTO;
|
||||
import com.jeelowcode.service.system.service.IMailSendService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 邮件发送 API 实现类
|
||||
*
|
||||
* @author wangjingyi
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ApiMailSendApiImpl implements IApiMailSendApi {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.NotifySendSingleToUserReqDTO;
|
||||
import com.jeelowcode.service.system.service.INotifySendService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 站内信发送 API 实现类
|
||||
*
|
||||
* @author xrcoder
|
||||
*/
|
||||
@Service
|
||||
public class ApiNotifyMessageSendApiImpl implements IApiNotifyMessageSendApi {
|
||||
|
||||
@Resource
|
||||
private INotifySendService notifySendService;
|
||||
|
||||
@Override
|
||||
public void sendSingleMessageToAdmin(NotifySendSingleToUserReqDTO reqDTO) {
|
||||
notifySendService.sendSingleNotifyToAdmin(reqDTO.getUserId(),
|
||||
reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.dto.OAuth2AccessTokenCheckRespDTO;
|
||||
import com.jeelowcode.service.system.dto.OAuth2AccessTokenCreateReqDTO;
|
||||
import com.jeelowcode.service.system.dto.OAuth2AccessTokenRespDTO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2AccessTokenDO;
|
||||
import com.jeelowcode.service.system.service.IOAuth2TokenService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* OAuth2.0 Token API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiOAuth2TokenApiImpl implements IApiOAuth2TokenApi {
|
||||
|
||||
@Resource
|
||||
private IOAuth2TokenService oauth2TokenService;
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenRespDTO createAccessToken(OAuth2AccessTokenCreateReqDTO reqDTO) {
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(
|
||||
reqDTO.getUserId(),reqDTO.getLoginDeptId(),reqDTO.getLoginRoleId(), reqDTO.getUserType(), reqDTO.getClientId(), reqDTO.getScopes());
|
||||
return BeanUtils.toBean(accessTokenDO, OAuth2AccessTokenRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenCheckRespDTO checkAccessToken(String accessToken) {
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.checkAccessToken(accessToken);
|
||||
return BeanUtils.toBean(accessTokenDO, OAuth2AccessTokenCheckRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenRespDTO removeAccessToken(String accessToken) {
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(accessToken);
|
||||
return BeanUtils.toBean(accessTokenDO, OAuth2AccessTokenRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenRespDTO refreshAccessToken(String refreshToken, String clientId) {
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, clientId);
|
||||
return BeanUtils.toBean(accessTokenDO, OAuth2AccessTokenRespDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.service.system.dto.OperateLogCreateReqDTO;
|
||||
import com.jeelowcode.service.system.dto.OperateLogV2CreateReqDTO;
|
||||
import com.jeelowcode.service.system.dto.OperateLogV2PageReqDTO;
|
||||
import com.jeelowcode.service.system.dto.OperateLogV2RespDTO;
|
||||
import com.jeelowcode.service.system.config.convert.logger.OperateLogConvert;
|
||||
import com.jeelowcode.service.system.entity.OperateLogV2DO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import com.jeelowcode.service.system.service.IAdminUserService;
|
||||
import com.jeelowcode.service.system.service.IOperateLogService;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
/**
|
||||
* 操作日志 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ApiOperateLogApiImpl implements IApiOperateLogApi {
|
||||
|
||||
@Resource
|
||||
private IOperateLogService operateLogService;
|
||||
@Resource
|
||||
private IAdminUserService adminUserService;
|
||||
|
||||
@Override
|
||||
public void createOperateLog(OperateLogCreateReqDTO createReqDTO) {
|
||||
operateLogService.createOperateLog(createReqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Async
|
||||
public void createOperateLogV2(OperateLogV2CreateReqDTO createReqDTO) {
|
||||
operateLogService.createOperateLogV2(createReqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<OperateLogV2RespDTO> getOperateLogPage(OperateLogV2PageReqDTO pageReqVO) {
|
||||
PageResult<OperateLogV2DO> operateLogPage = operateLogService.getOperateLogPage(pageReqVO);
|
||||
if (CollUtil.isEmpty(operateLogPage.getList())) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
|
||||
// 获取用户
|
||||
List<AdminUserDO> userList = adminUserService.getUserList(
|
||||
convertSet(operateLogPage.getList(), OperateLogV2DO::getUserId));
|
||||
return OperateLogConvert.INSTANCE.convertPage(operateLogPage, userList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.DeptDataPermissionRespDTO;
|
||||
import com.jeelowcode.service.system.service.IPermissionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 权限 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiPermissionApiImpl implements IApiPermissionApi {
|
||||
|
||||
@Resource
|
||||
private IPermissionService permissionService;
|
||||
|
||||
@Override
|
||||
public Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds) {
|
||||
return permissionService.getUserRoleIdListByRoleId(roleIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnyPermissions(Long userId, String... permissions) {
|
||||
return permissionService.hasAnyPermissions(userId, permissions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnyRoles(Long userId, String... roles) {
|
||||
return permissionService.hasAnyRoles(userId, roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeptDataPermissionRespDTO getDeptDataPermission(Long userId) {
|
||||
return permissionService.getDeptDataPermission(userId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.dto.PostRespDTO;
|
||||
import com.jeelowcode.service.system.entity.PostDO;
|
||||
import com.jeelowcode.service.system.service.IPostService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 岗位 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiPostApiImpl implements IApiPostApi {
|
||||
|
||||
@Resource
|
||||
private IPostService postService;
|
||||
|
||||
@Override
|
||||
public void validPostList(Collection<Long> ids) {
|
||||
postService.validatePostList(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PostRespDTO> getPostList(Collection<Long> ids) {
|
||||
List<PostDO> list = postService.getPostList(ids);
|
||||
return BeanUtils.toBean(list, PostRespDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.service.IRoleService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 角色 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiRoleApiImpl implements IApiRoleApi {
|
||||
|
||||
@Resource
|
||||
private IRoleService roleService;
|
||||
|
||||
@Override
|
||||
public void validRoleList(Collection<Long> ids) {
|
||||
roleService.validateRoleList(ids);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.service.ISensitiveWordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 敏感词 API 实现类
|
||||
*
|
||||
* @author 永不言败
|
||||
*/
|
||||
@Service
|
||||
public class ApiSensitiveWordApiImpl implements IApiSensitiveWordApi {
|
||||
|
||||
@Resource
|
||||
private ISensitiveWordService sensitiveWordService;
|
||||
|
||||
@Override
|
||||
public List<String> validateText(String text, List<String> tags) {
|
||||
return sensitiveWordService.validateText(text, tags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTextValid(String text, List<String> tags) {
|
||||
return sensitiveWordService.isTextValid(text, tags);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.SmsCodeValidateReqDTO;
|
||||
import com.jeelowcode.service.system.dto.SmsCodeSendReqDTO;
|
||||
import com.jeelowcode.service.system.dto.SmsCodeUseReqDTO;
|
||||
import com.jeelowcode.service.system.service.ISmsCodeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 短信验证码 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ApiSmsCodeApiImpl implements IApiSmsCodeApi {
|
||||
|
||||
@Resource
|
||||
private ISmsCodeService smsCodeService;
|
||||
|
||||
@Override
|
||||
public void sendSmsCode(SmsCodeSendReqDTO reqDTO) {
|
||||
smsCodeService.sendSmsCode(reqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useSmsCode(SmsCodeUseReqDTO reqDTO) {
|
||||
smsCodeService.useSmsCode(reqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateSmsCode(SmsCodeValidateReqDTO reqDTO) {
|
||||
smsCodeService.validateSmsCode(reqDTO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.SmsSendSingleToUserReqDTO;
|
||||
import com.jeelowcode.service.system.service.ISmsSendService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 短信发送 API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ApiSmsSendApiImpl implements IApiSmsSendApi {
|
||||
|
||||
@Resource
|
||||
private ISmsSendService smsSendService;
|
||||
|
||||
@Override
|
||||
public Long sendSingleSmsToAdmin(SmsSendSingleToUserReqDTO reqDTO) {
|
||||
return smsSendService.sendSingleSmsToAdmin(reqDTO.getMobile(), reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.dto.SocialWxJsapiSignatureRespDTO;
|
||||
import com.jeelowcode.service.system.dto.SocialWxPhoneNumberInfoRespDTO;
|
||||
import com.jeelowcode.service.system.service.ISocialClientService;
|
||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 社交应用的 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ApiSocialClientApiImpl implements IApiSocialClientApi {
|
||||
|
||||
@Resource
|
||||
private ISocialClientService socialClientService;
|
||||
|
||||
@Override
|
||||
public String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri) {
|
||||
return socialClientService.getAuthorizeUrl(socialType, userType, redirectUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocialWxJsapiSignatureRespDTO createWxMpJsapiSignature(Integer userType, String url) {
|
||||
WxJsapiSignature signature = socialClientService.createWxMpJsapiSignature(userType, url);
|
||||
return BeanUtils.toBean(signature, SocialWxJsapiSignatureRespDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocialWxPhoneNumberInfoRespDTO getWxMaPhoneNumberInfo(Integer userType, String phoneCode) {
|
||||
WxMaPhoneNumberInfo info = socialClientService.getWxMaPhoneNumberInfo(userType, phoneCode);
|
||||
return BeanUtils.toBean(info, SocialWxPhoneNumberInfoRespDTO.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.dto.SocialUserBindReqDTO;
|
||||
import com.jeelowcode.service.system.dto.SocialUserRespDTO;
|
||||
import com.jeelowcode.service.system.dto.SocialUserUnbindReqDTO;
|
||||
import com.jeelowcode.service.system.service.ISocialUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 社交用户的 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ApiSocialUserApiImpl implements IApiSocialUserApi {
|
||||
|
||||
@Resource
|
||||
private ISocialUserService socialUserService;
|
||||
|
||||
@Override
|
||||
public String bindSocialUser(SocialUserBindReqDTO reqDTO) {
|
||||
return socialUserService.bindSocialUser(reqDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbindSocialUser(SocialUserUnbindReqDTO reqDTO) {
|
||||
socialUserService.unbindSocialUser(reqDTO.getUserId(), reqDTO.getUserType(),
|
||||
reqDTO.getSocialType(), reqDTO.getOpenid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocialUserRespDTO getSocialUserByUserId(Integer userType, Long userId, Integer socialType) {
|
||||
return socialUserService.getSocialUserByUserId(userType, userId, socialType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state) {
|
||||
return socialUserService.getSocialUserByCode(userType, socialType, code, state);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.jeelowcode.service.system.api;
|
||||
|
||||
import com.jeelowcode.service.system.service.ITenantService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 多租户的 API 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
public class ApiTenantApiImpl implements IApiTenantApi {
|
||||
|
||||
@Resource
|
||||
private ITenantService tenantService;
|
||||
|
||||
@Override
|
||||
public List<Long> getTenantIdList() {
|
||||
return tenantService.getTenantIdList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateTenant(Long id) {
|
||||
tenantService.validTenant(id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.jeelowcode.service.system.config.convert.auth;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.jeelowcode.service.system.controller.vo.auth.*;
|
||||
import com.jeelowcode.service.system.dto.SmsCodeSendReqDTO;
|
||||
import com.jeelowcode.service.system.dto.SmsCodeUseReqDTO;
|
||||
import com.jeelowcode.service.system.dto.SocialUserBindReqDTO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import com.jeelowcode.service.system.entity.MenuDO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2AccessTokenDO;
|
||||
import com.jeelowcode.service.system.entity.RoleDO;
|
||||
import com.jeelowcode.service.system.enums.MenuTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.jeelowcode.service.system.entity.MenuDO.ID_ROOT;
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.filterList;
|
||||
|
||||
@Mapper
|
||||
public interface AuthConvert {
|
||||
|
||||
AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class);
|
||||
|
||||
AuthLoginRespVO convert(OAuth2AccessTokenDO bean);
|
||||
|
||||
default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList, Set<String> allPermissions) {
|
||||
Set<String> myPermissions = convertSet(menuList, MenuDO::getPermission);
|
||||
|
||||
Map<String,Boolean> permissionMap=new HashMap<>();
|
||||
|
||||
for(String allPermission:allPermissions){
|
||||
Boolean hasRole=false;
|
||||
if(myPermissions.contains(allPermission)){
|
||||
hasRole=true;
|
||||
}
|
||||
permissionMap.put(allPermission,hasRole);
|
||||
}
|
||||
|
||||
return AuthPermissionInfoRespVO.builder()
|
||||
.user(BeanUtils.toBean(user, AuthPermissionInfoRespVO.UserVO.class))
|
||||
.roles(convertSet(roleList, RoleDO::getCode))
|
||||
// 权限标识信息
|
||||
.permissions(permissionMap)
|
||||
// 菜单树
|
||||
.menus(buildMenuTree(menuList))
|
||||
.build();
|
||||
}
|
||||
|
||||
AuthPermissionInfoRespVO.MenuVO convertTreeNode(MenuDO menu);
|
||||
|
||||
/**
|
||||
* 将菜单列表,构建成菜单树
|
||||
*
|
||||
* @param menuList 菜单列表
|
||||
* @return 菜单树
|
||||
*/
|
||||
default List<AuthPermissionInfoRespVO.MenuVO> buildMenuTree(List<MenuDO> menuList) {
|
||||
if (CollUtil.isEmpty(menuList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 移除按钮
|
||||
menuList.removeIf(menu -> menu.getType().equals(MenuTypeEnum.BUTTON.getType()));
|
||||
// 排序,保证菜单的有序性
|
||||
menuList.sort(Comparator.comparing(MenuDO::getSort));
|
||||
|
||||
// 构建菜单树
|
||||
// 使用 LinkedHashMap 的原因,是为了排序 。实际也可以用 Stream API ,就是太丑了。
|
||||
Map<Long, AuthPermissionInfoRespVO.MenuVO> treeNodeMap = new LinkedHashMap<>();
|
||||
menuList.forEach(menu -> treeNodeMap.put(menu.getId(), AuthConvert.INSTANCE.convertTreeNode(menu)));
|
||||
// 处理父子关系
|
||||
treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(ID_ROOT)).forEach(childNode -> {
|
||||
// 获得父节点
|
||||
AuthPermissionInfoRespVO.MenuVO parentNode = treeNodeMap.get(childNode.getParentId());
|
||||
if (parentNode == null) {
|
||||
LoggerFactory.getLogger(getClass()).error("[buildRouterTree][resource({}) 找不到父资源({})]",
|
||||
childNode.getId(), childNode.getParentId());
|
||||
return;
|
||||
}
|
||||
// 将自己添加到父节点中
|
||||
if (parentNode.getChildren() == null) {
|
||||
parentNode.setChildren(new ArrayList<>());
|
||||
}
|
||||
parentNode.getChildren().add(childNode);
|
||||
});
|
||||
// 获得到所有的根节点
|
||||
return filterList(treeNodeMap.values(), node -> ID_ROOT.equals(node.getParentId()));
|
||||
}
|
||||
|
||||
SocialUserBindReqDTO convert(Long userId, Integer userType, AuthSocialLoginReqVO reqVO);
|
||||
|
||||
SmsCodeSendReqDTO convert(AuthSmsSendReqVO reqVO);
|
||||
|
||||
SmsCodeUseReqDTO convert(AuthSmsLoginReqVO reqVO, Integer scene, String usedIp);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.jeelowcode.service.system.config.convert.logger;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.CollectionUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.MapUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.dto.OperateLogV2RespDTO;
|
||||
import com.jeelowcode.service.system.controller.vo.logger.operatelog.OperateLogRespVO;
|
||||
import com.jeelowcode.service.system.entity.OperateLogDO;
|
||||
import com.jeelowcode.service.system.entity.OperateLogV2DO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.MapUtils.findAndThen;
|
||||
|
||||
@Mapper
|
||||
public interface OperateLogConvert {
|
||||
|
||||
OperateLogConvert INSTANCE = Mappers.getMapper(OperateLogConvert.class);
|
||||
|
||||
default List<OperateLogRespVO> convertList(List<OperateLogDO> list, Map<Long, AdminUserDO> userMap) {
|
||||
return CollectionUtils.convertList(list, log -> {
|
||||
OperateLogRespVO logVO = BeanUtils.toBean(log, OperateLogRespVO.class);
|
||||
MapUtils.findAndThen(userMap, log.getUserId(), user -> logVO.setUserNickname(user.getNickname()));
|
||||
return logVO;
|
||||
});
|
||||
}
|
||||
|
||||
default PageResult<OperateLogV2RespDTO> convertPage(PageResult<OperateLogV2DO> operateLogPage, List<AdminUserDO> userList) {
|
||||
return BeanUtils.toBean(operateLogPage, OperateLogV2RespDTO.class).setList(setUserInfo(operateLogPage.getList(), userList));
|
||||
}
|
||||
|
||||
OperateLogV2RespDTO convert(OperateLogV2DO operateLogV2DO);
|
||||
|
||||
default List<OperateLogV2RespDTO> setUserInfo(List<OperateLogV2DO> logList, List<AdminUserDO> userList) {
|
||||
Map<Long, AdminUserDO> userMap = convertMap(userList, AdminUserDO::getId);
|
||||
return CollectionUtils.convertList(logList, item -> {
|
||||
OperateLogV2RespDTO respDTO = convert(item);
|
||||
findAndThen(userMap, item.getUserId(), user -> respDTO.setUserName(user.getNickname()));
|
||||
return respDTO;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.jeelowcode.service.system.config.convert.mail;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.mail.MailAccount;
|
||||
import com.jeelowcode.service.system.entity.MailAccountDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface MailAccountConvert {
|
||||
|
||||
MailAccountConvert INSTANCE = Mappers.getMapper(MailAccountConvert.class);
|
||||
|
||||
default MailAccount convert(MailAccountDO account, String nickname) {
|
||||
String from = StrUtil.isNotEmpty(nickname) ? nickname + " <" + account.getMail() + ">" : account.getMail();
|
||||
return new MailAccount().setFrom(from).setAuth(true)
|
||||
.setUser(account.getUsername()).setPass(account.getPassword())
|
||||
.setHost(account.getHost()).setPort(account.getPort()).setSslEnable(account.getSslEnable());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.jeelowcode.service.system.config.convert.oauth2;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import com.jeelowcode.tool.framework.common.core.KeyValue;
|
||||
import com.jeelowcode.tool.framework.common.enums.UserTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.CollectionUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.open.OAuth2OpenAccessTokenRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.open.OAuth2OpenAuthorizeInfoRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.open.OAuth2OpenCheckTokenRespVO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2AccessTokenDO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2ApproveDO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2ClientDO;
|
||||
import com.jeelowcode.service.system.util.OAuth2Utils;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface OAuth2OpenConvert {
|
||||
|
||||
OAuth2OpenConvert INSTANCE = Mappers.getMapper(OAuth2OpenConvert.class);
|
||||
|
||||
default OAuth2OpenAccessTokenRespVO convert(OAuth2AccessTokenDO bean) {
|
||||
OAuth2OpenAccessTokenRespVO respVO = BeanUtils.toBean(bean, OAuth2OpenAccessTokenRespVO.class);
|
||||
respVO.setTokenType(SecurityFrameworkUtils.AUTHORIZATION_BEARER.toLowerCase());
|
||||
respVO.setExpiresIn(OAuth2Utils.getExpiresIn(bean.getExpiresTime()));
|
||||
respVO.setScope(OAuth2Utils.buildScopeStr(bean.getScopes()));
|
||||
return respVO;
|
||||
}
|
||||
|
||||
default OAuth2OpenCheckTokenRespVO convert2(OAuth2AccessTokenDO bean) {
|
||||
OAuth2OpenCheckTokenRespVO respVO = BeanUtils.toBean(bean, OAuth2OpenCheckTokenRespVO.class);
|
||||
respVO.setExp(LocalDateTimeUtil.toEpochMilli(bean.getExpiresTime()) / 1000L);
|
||||
respVO.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
return respVO;
|
||||
}
|
||||
|
||||
default OAuth2OpenAuthorizeInfoRespVO convert(OAuth2ClientDO client, List<OAuth2ApproveDO> approves) {
|
||||
// 构建 scopes
|
||||
List<KeyValue<String, Boolean>> scopes = new ArrayList<>(client.getScopes().size());
|
||||
Map<String, OAuth2ApproveDO> approveMap = CollectionUtils.convertMap(approves, OAuth2ApproveDO::getScope);
|
||||
client.getScopes().forEach(scope -> {
|
||||
OAuth2ApproveDO approve = approveMap.get(scope);
|
||||
scopes.add(new KeyValue<>(scope, approve != null ? approve.getApproved() : false));
|
||||
});
|
||||
// 拼接返回
|
||||
return new OAuth2OpenAuthorizeInfoRespVO(
|
||||
new OAuth2OpenAuthorizeInfoRespVO.Client(client.getName(), client.getLogo()), scopes);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 提供 POJO 类的实体转换
|
||||
*
|
||||
* 目前使用 MapStruct 框架
|
||||
*/
|
||||
package com.jeelowcode.service.system.config.convert;
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.jeelowcode.service.system.config.convert.social;
|
||||
|
||||
import com.jeelowcode.service.system.dto.SocialUserBindReqDTO;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.user.SocialUserBindReqVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface SocialUserConvert {
|
||||
|
||||
SocialUserConvert INSTANCE = Mappers.getMapper(SocialUserConvert.class);
|
||||
|
||||
@Mapping(source = "reqVO.type", target = "socialType")
|
||||
SocialUserBindReqDTO convert(Long userId, Integer userType, SocialUserBindReqVO reqVO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.jeelowcode.service.system.config.convert.tenant;
|
||||
|
||||
import com.jeelowcode.service.system.controller.vo.tenant.tenant.TenantSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.user.user.UserSaveReqVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 租户 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface TenantConvert {
|
||||
|
||||
TenantConvert INSTANCE = Mappers.getMapper(TenantConvert.class);
|
||||
|
||||
default UserSaveReqVO convert02(TenantSaveReqVO bean) {
|
||||
UserSaveReqVO reqVO = new UserSaveReqVO();
|
||||
reqVO.setUsername(bean.getUsername());
|
||||
reqVO.setPassword(bean.getPassword());
|
||||
reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile());
|
||||
return reqVO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.jeelowcode.service.system.config.convert.user;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.util.collection.CollectionUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.user.profile.UserProfileRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.user.user.UserRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.user.user.UserSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.SocialUserDO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface UserConvert {
|
||||
|
||||
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
|
||||
|
||||
default List<UserRespVO> convertList(List<AdminUserDO> list) {
|
||||
return CollectionUtils.convertList(list, user -> convert(user));
|
||||
}
|
||||
|
||||
default UserRespVO convert(AdminUserDO user) {
|
||||
UserRespVO userVO = BeanUtils.toBean(user, UserRespVO.class);
|
||||
return userVO;
|
||||
}
|
||||
|
||||
default List<UserSimpleRespVO> convertSimpleList(List<AdminUserDO> list) {
|
||||
return CollectionUtils.convertList(list, user -> {
|
||||
UserSimpleRespVO userVO = BeanUtils.toBean(user, UserSimpleRespVO.class);
|
||||
return userVO;
|
||||
});
|
||||
}
|
||||
|
||||
default UserProfileRespVO convert(List<SocialUserDO> socialUsers,
|
||||
AdminUserDO user) {
|
||||
UserProfileRespVO userVO = BeanUtils.toBean(user, UserProfileRespVO.class);
|
||||
userVO.setSocialUsers(BeanUtils.toBean(socialUsers, UserProfileRespVO.SocialUser.class));
|
||||
return userVO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.jeelowcode.service.system.config.framework.datapermission.config;
|
||||
|
||||
import com.jeelowcode.tool.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* system 模块的数据权限 Configuration
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class DataPermissionConfiguration {
|
||||
|
||||
@Bean
|
||||
public DeptDataPermissionRuleCustomizer sysDeptDataPermissionRuleCustomizer() {
|
||||
return rule -> {
|
||||
|
||||
/*
|
||||
暂时不做系统表
|
||||
rule.addDeptColumn(AdminUserDO.class);
|
||||
rule.addDeptColumn(DeptDO.class, "id");
|
||||
// user
|
||||
rule.addUserColumn(AdminUserDO.class, "id");*/
|
||||
// dept
|
||||
|
||||
//rule.addJeeLowCodeColumn("test_form_dictionary");
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* system 模块的数据权限配置
|
||||
*/
|
||||
package com.jeelowcode.service.system.config.framework.datapermission;
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.jeelowcode.service.system.config.framework.operatelog.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.service.system.api.IApiAdminUserApi;
|
||||
import com.jeelowcode.service.system.dto.AdminUserRespDTO;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 管理员名字的 {@link IParseFunction} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AdminUserParseFunction implements IParseFunction {
|
||||
|
||||
public static final String NAME = "getAdminUserById";
|
||||
|
||||
@Resource
|
||||
private IApiAdminUserApi apiAdminUserApi;
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (StrUtil.isEmptyIfStr(value)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
AdminUserRespDTO user = apiAdminUserApi.getUser(Long.parseLong(value.toString()));
|
||||
if (user == null) {
|
||||
log.warn("[apply][获取用户{{}}为空", value);
|
||||
return "";
|
||||
}
|
||||
// 返回格式 芋道源码(13888888888)
|
||||
String nickname = user.getNickname();
|
||||
if (StrUtil.isEmpty(user.getMobile())) {
|
||||
return nickname;
|
||||
}
|
||||
return StrUtil.format("{}({})", nickname, user.getMobile());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.jeelowcode.service.system.config.framework.operatelog.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.tool.framework.ip.core.utils.AreaUtils;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 地名的 {@link IParseFunction} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AreaParseFunction implements IParseFunction {
|
||||
|
||||
public static final String NAME = "getArea";
|
||||
|
||||
@Override
|
||||
public boolean executeBefore() {
|
||||
return true; // 先转换值后对比
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (StrUtil.isEmptyIfStr(value)) {
|
||||
return "";
|
||||
}
|
||||
return AreaUtils.format(Integer.parseInt(value.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.jeelowcode.service.system.config.framework.operatelog.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.tool.framework.dict.core.util.DictFrameworkUtils;
|
||||
import com.jeelowcode.service.infra.enums.DictTypeConstants;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 是否类型的 {@link IParseFunction} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class BooleanParseFunction implements IParseFunction {
|
||||
|
||||
public static final String NAME = "getBoolean";
|
||||
|
||||
@Override
|
||||
public boolean executeBefore() {
|
||||
return true; // 先转换值后对比
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (StrUtil.isEmptyIfStr(value)) {
|
||||
return "";
|
||||
}
|
||||
return DictFrameworkUtils.getDictDataLabel(DictTypeConstants.BOOLEAN_STRING, value.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.jeelowcode.service.system.config.framework.operatelog.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.service.system.api.IApiDeptApi;
|
||||
import com.jeelowcode.service.system.dto.DeptRespDTO;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 管理员名字的 {@link IParseFunction} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DeptParseFunction implements IParseFunction {
|
||||
|
||||
public static final String NAME = "getDeptById";
|
||||
|
||||
@Resource
|
||||
private IApiDeptApi apiDeptApi;
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (StrUtil.isEmptyIfStr(value)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 获取部门信息
|
||||
DeptRespDTO dept = apiDeptApi.getDept(Long.parseLong(value.toString()));
|
||||
if (dept == null) {
|
||||
log.warn("[apply][获取部门{{}}为空", value);
|
||||
return "";
|
||||
}
|
||||
return dept.getName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.jeelowcode.service.system.config.framework.operatelog.core;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.tool.framework.dict.core.util.DictFrameworkUtils;
|
||||
import com.jeelowcode.service.system.constant.DictTypeConstants;
|
||||
import com.mzt.logapi.service.IParseFunction;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 行业的 {@link IParseFunction} 实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SexParseFunction implements IParseFunction {
|
||||
|
||||
public static final String NAME = "getSex";
|
||||
|
||||
@Override
|
||||
public boolean executeBefore() {
|
||||
return true; // 先转换值后对比
|
||||
}
|
||||
|
||||
@Override
|
||||
public String functionName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(Object value) {
|
||||
if (StrUtil.isEmptyIfStr(value)) {
|
||||
return "";
|
||||
}
|
||||
return DictFrameworkUtils.getDictDataLabel(DictTypeConstants.USER_SEX, value.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package com.jeelowcode.service.system.config.framework.operatelog;
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 属于 system 模块的 framework 封装
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package com.jeelowcode.service.system.config.framework;
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.Duration;
|
||||
|
||||
@ConfigurationProperties(prefix = "jeelowcode.sms-code")
|
||||
@Validated
|
||||
@Data
|
||||
public class SmsCodeProperties {
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*/
|
||||
@NotNull(message = "过期时间不能为空")
|
||||
private Duration expireTimes;
|
||||
/**
|
||||
* 短信发送频率
|
||||
*/
|
||||
@NotNull(message = "短信发送频率不能为空")
|
||||
private Duration sendFrequency;
|
||||
/**
|
||||
* 每日发送最大数量
|
||||
*/
|
||||
@NotNull(message = "每日发送最大数量不能为空")
|
||||
private Integer sendMaximumQuantityPerDay;
|
||||
/**
|
||||
* 验证码最小值
|
||||
*/
|
||||
@NotNull(message = "验证码最小值不能为空")
|
||||
private Integer beginCode;
|
||||
/**
|
||||
* 验证码最大值
|
||||
*/
|
||||
@NotNull(message = "验证码最大值不能为空")
|
||||
private Integer endCode;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.config;
|
||||
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.SmsClientFactory;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.impl.SmsClientFactoryImpl;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 短信配置类,包括短信客户端、短信验证码两部分
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(SmsCodeProperties.class)
|
||||
public class SmsConfiguration {
|
||||
|
||||
@Bean
|
||||
public SmsClientFactory smsClientFactory() {
|
||||
return new SmsClientFactoryImpl();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.core.KeyValue;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信客户端,用于对接各短信平台的 SDK,实现短信发送等功能
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021/1/25 14:14
|
||||
*/
|
||||
public interface SmsClient {
|
||||
|
||||
/**
|
||||
* 获得渠道编号
|
||||
*
|
||||
* @return 渠道编号
|
||||
*/
|
||||
Long getId();
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param logId 日志编号
|
||||
* @param mobile 手机号
|
||||
* @param apiTemplateId 短信 API 的模板编号
|
||||
* @param templateParams 短信模板参数。通过 List 数组,保证参数的顺序
|
||||
* @return 短信发送结果
|
||||
*/
|
||||
SmsSendRespDTO sendSms(Long logId, String mobile, String apiTemplateId,
|
||||
List<KeyValue<String, Object>> templateParams) throws Throwable;
|
||||
|
||||
/**
|
||||
* 解析接收短信的接收结果
|
||||
*
|
||||
* @param text 结果
|
||||
* @return 结果内容
|
||||
* @throws Throwable 当解析 text 发生异常时,则会抛出异常
|
||||
*/
|
||||
List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) throws Throwable;
|
||||
|
||||
/**
|
||||
* 查询指定的短信模板
|
||||
*
|
||||
* @param apiTemplateId 短信 API 的模板编号
|
||||
* @return 短信模板
|
||||
*/
|
||||
SmsTemplateRespDTO getSmsTemplate(String apiTemplateId) throws Throwable;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client;
|
||||
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.property.SmsChannelProperties;
|
||||
|
||||
/**
|
||||
* 短信客户端的工厂接口
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021/1/28 14:01
|
||||
*/
|
||||
public interface SmsClientFactory {
|
||||
|
||||
/**
|
||||
* 获得短信 Client
|
||||
*
|
||||
* @param channelId 渠道编号
|
||||
* @return 短信 Client
|
||||
*/
|
||||
SmsClient getSmsClient(Long channelId);
|
||||
|
||||
/**
|
||||
* 获得短信 Client
|
||||
*
|
||||
* @param channelCode 渠道编码
|
||||
* @return 短信 Client
|
||||
*/
|
||||
SmsClient getSmsClient(String channelCode);
|
||||
|
||||
/**
|
||||
* 创建短信 Client
|
||||
*
|
||||
* @param properties 配置对象
|
||||
*/
|
||||
void createOrUpdateSmsClient(SmsChannelProperties properties);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 消息接收 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class SmsReceiveRespDTO {
|
||||
|
||||
/**
|
||||
* 是否接收成功
|
||||
*/
|
||||
private Boolean success;
|
||||
/**
|
||||
* API 接收结果的编码
|
||||
*/
|
||||
private String errorCode;
|
||||
/**
|
||||
* API 接收结果的说明
|
||||
*/
|
||||
private String errorMsg;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 用户接收时间
|
||||
*/
|
||||
private LocalDateTime receiveTime;
|
||||
|
||||
/**
|
||||
* 短信 API 发送返回的序号
|
||||
*/
|
||||
private String serialNo;
|
||||
/**
|
||||
* 短信日志编号
|
||||
*
|
||||
* 对应 SysSmsLogDO 的编号
|
||||
*/
|
||||
private Long logId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 短信发送 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class SmsSendRespDTO {
|
||||
|
||||
/**
|
||||
* 是否成功
|
||||
*/
|
||||
private Boolean success;
|
||||
|
||||
/**
|
||||
* API 请求编号
|
||||
*/
|
||||
private String apiRequestId;
|
||||
|
||||
// ==================== 成功时字段 ====================
|
||||
|
||||
/**
|
||||
* 短信 API 发送返回的序号
|
||||
*/
|
||||
private String serialNo;
|
||||
|
||||
// ==================== 失败时字段 ====================
|
||||
|
||||
/**
|
||||
* API 返回错误码
|
||||
*
|
||||
* 由于第三方的错误码可能是字符串,所以使用 String 类型
|
||||
*/
|
||||
private String apiCode;
|
||||
/**
|
||||
* API 返回提示
|
||||
*/
|
||||
private String apiMsg;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.dto;
|
||||
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 短信模板 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class SmsTemplateRespDTO {
|
||||
|
||||
/**
|
||||
* 模板编号
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 短信内容
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 审核状态
|
||||
*
|
||||
* 枚举 {@link SmsTemplateAuditStatusEnum}
|
||||
*/
|
||||
private Integer auditStatus;
|
||||
/**
|
||||
* 审核未通过的理由
|
||||
*/
|
||||
private String auditReason;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.impl;
|
||||
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.SmsClient;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.property.SmsChannelProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 短信客户端的抽象类,提供模板方法,减少子类的冗余代码
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021/2/1 9:28
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AbstractSmsClient implements SmsClient {
|
||||
|
||||
/**
|
||||
* 短信渠道配置
|
||||
*/
|
||||
protected volatile SmsChannelProperties properties;
|
||||
|
||||
public AbstractSmsClient(SmsChannelProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
public final void init() {
|
||||
doInit();
|
||||
log.debug("[init][配置({}) 初始化完成]", properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义初始化
|
||||
*/
|
||||
protected abstract void doInit();
|
||||
|
||||
public final void refresh(SmsChannelProperties properties) {
|
||||
// 判断是否更新
|
||||
if (properties.equals(this.properties)) {
|
||||
return;
|
||||
}
|
||||
log.info("[refresh][配置({})发生变化,重新初始化]", properties);
|
||||
this.properties = properties;
|
||||
// 初始化
|
||||
this.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return properties.getId();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.jeelowcode.tool.framework.common.core.KeyValue;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.MapUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.json.JsonUtils;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.aliyuncs.DefaultAcsClient;
|
||||
import com.aliyuncs.IAcsClient;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateResponse;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
|
||||
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
|
||||
import com.aliyuncs.profile.DefaultProfile;
|
||||
import com.aliyuncs.profile.IClientProfile;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static com.jeelowcode.tool.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import static com.jeelowcode.tool.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||
|
||||
/**
|
||||
* 阿里短信客户端的实现类
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021/1/25 14:17
|
||||
*/
|
||||
@Slf4j
|
||||
public class AliyunSmsClient extends AbstractSmsClient {
|
||||
|
||||
/**
|
||||
* 调用成功 code
|
||||
*/
|
||||
public static final String API_CODE_SUCCESS = "OK";
|
||||
|
||||
/**
|
||||
* REGION, 使用杭州
|
||||
*/
|
||||
private static final String ENDPOINT = "cn-hangzhou";
|
||||
|
||||
/**
|
||||
* 阿里云客户端
|
||||
*/
|
||||
private volatile IAcsClient client;
|
||||
|
||||
public AliyunSmsClient(SmsChannelProperties properties) {
|
||||
super(properties);
|
||||
Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
|
||||
Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInit() {
|
||||
IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, properties.getApiKey(), properties.getApiSecret());
|
||||
client = new DefaultAcsClient(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsSendRespDTO sendSms(Long sendLogId, String mobile, String apiTemplateId,
|
||||
List<KeyValue<String, Object>> templateParams) throws Throwable {
|
||||
// 构建请求
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
request.setPhoneNumbers(mobile);
|
||||
request.setSignName(properties.getSignature());
|
||||
request.setTemplateCode(apiTemplateId);
|
||||
request.setTemplateParam(JsonUtils.toJsonString(MapUtils.convertMap(templateParams)));
|
||||
request.setOutId(String.valueOf(sendLogId));
|
||||
// 执行请求
|
||||
SendSmsResponse response = client.getAcsResponse(request);
|
||||
return new SmsSendRespDTO().setSuccess(Objects.equals(response.getCode(), API_CODE_SUCCESS)).setSerialNo(response.getBizId())
|
||||
.setApiRequestId(response.getRequestId()).setApiCode(response.getCode()).setApiMsg(response.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) {
|
||||
List<SmsReceiveStatus> statuses = JsonUtils.parseArray(text, SmsReceiveStatus.class);
|
||||
return convertList(statuses, status -> new SmsReceiveRespDTO().setSuccess(status.getSuccess())
|
||||
.setErrorCode(status.getErrCode()).setErrorMsg(status.getErrMsg())
|
||||
.setMobile(status.getPhoneNumber()).setReceiveTime(status.getReportTime())
|
||||
.setSerialNo(status.getBizId()).setLogId(Long.valueOf(status.getOutId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsTemplateRespDTO getSmsTemplate(String apiTemplateId) throws Throwable {
|
||||
// 构建请求
|
||||
QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();
|
||||
request.setTemplateCode(apiTemplateId);
|
||||
// 执行请求
|
||||
QuerySmsTemplateResponse response = client.getAcsResponse(request);
|
||||
if (response.getTemplateStatus() == null) {
|
||||
return null;
|
||||
}
|
||||
return new SmsTemplateRespDTO().setId(response.getTemplateCode()).setContent(response.getTemplateContent())
|
||||
.setAuditStatus(convertSmsTemplateAuditStatus(response.getTemplateStatus())).setAuditReason(response.getReason());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Integer convertSmsTemplateAuditStatus(Integer templateStatus) {
|
||||
switch (templateStatus) {
|
||||
case 0: return SmsTemplateAuditStatusEnum.CHECKING.getStatus();
|
||||
case 1: return SmsTemplateAuditStatusEnum.SUCCESS.getStatus();
|
||||
case 2: return SmsTemplateAuditStatusEnum.FAIL.getStatus();
|
||||
default: throw new IllegalArgumentException(String.format("未知审核状态(%d)", templateStatus));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 短信接收状态
|
||||
*
|
||||
* 参见 <a href="https://help.aliyun.com/document_detail/101867.html">文档</a>
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public static class SmsReceiveStatus {
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@JsonProperty("phone_number")
|
||||
private String phoneNumber;
|
||||
/**
|
||||
* 发送时间
|
||||
*/
|
||||
@JsonProperty("send_time")
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime sendTime;
|
||||
/**
|
||||
* 状态报告时间
|
||||
*/
|
||||
@JsonProperty("report_time")
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime reportTime;
|
||||
/**
|
||||
* 是否接收成功
|
||||
*/
|
||||
private Boolean success;
|
||||
/**
|
||||
* 状态报告说明
|
||||
*/
|
||||
@JsonProperty("err_msg")
|
||||
private String errMsg;
|
||||
/**
|
||||
* 状态报告编码
|
||||
*/
|
||||
@JsonProperty("err_code")
|
||||
private String errCode;
|
||||
/**
|
||||
* 发送序列号
|
||||
*/
|
||||
@JsonProperty("biz_id")
|
||||
private String bizId;
|
||||
/**
|
||||
* 用户序列号
|
||||
*
|
||||
* 这里我们传递的是 SysSmsLogDO 的日志编号
|
||||
*/
|
||||
@JsonProperty("out_id")
|
||||
private String outId;
|
||||
/**
|
||||
* 短信长度,例如说 1、2、3
|
||||
*
|
||||
* 140 字节算一条短信,短信长度超过 140 字节时会拆分成多条短信发送
|
||||
*/
|
||||
@JsonProperty("sms_size")
|
||||
private Integer smsSize;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.impl;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import cn.hutool.crypto.digest.HmacAlgorithm;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.jeelowcode.tool.framework.common.core.KeyValue;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.MapUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.json.JsonUtils;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.property.SmsChannelProperties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 基于钉钉 WebHook 实现的调试的短信客户端实现类
|
||||
*
|
||||
* 考虑到省钱,我们使用钉钉 WebHook 模拟发送短信,方便调试。
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class DebugDingTalkSmsClient extends AbstractSmsClient {
|
||||
|
||||
public DebugDingTalkSmsClient(SmsChannelProperties properties) {
|
||||
super(properties);
|
||||
Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
|
||||
Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsSendRespDTO sendSms(Long sendLogId, String mobile,
|
||||
String apiTemplateId, List<KeyValue<String, Object>> templateParams) throws Throwable {
|
||||
// 构建请求
|
||||
String url = buildUrl("robot/send");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("msgtype", "text");
|
||||
String content = String.format("【模拟短信】\n手机号:%s\n短信日志编号:%d\n模板参数:%s",
|
||||
mobile, sendLogId, MapUtils.convertMap(templateParams));
|
||||
params.put("text", MapUtil.builder().put("content", content).build());
|
||||
// 执行请求
|
||||
String responseText = HttpUtil.post(url, JsonUtils.toJsonString(params));
|
||||
// 解析结果
|
||||
Map<?, ?> responseObj = JsonUtils.parseObject(responseText, Map.class);
|
||||
String errorCode = MapUtil.getStr(responseObj, "errcode");
|
||||
return new SmsSendRespDTO().setSuccess(Objects.equals(errorCode, "0")).setSerialNo(StrUtil.uuid())
|
||||
.setApiCode(errorCode).setApiMsg(MapUtil.getStr(responseObj, "errorMsg"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求地址
|
||||
*
|
||||
* 参见 <a href="https://developers.dingtalk.com/document/app/custom-robot-access/title-nfv-794-g71">文档</a>
|
||||
*
|
||||
* @param path 请求路径
|
||||
* @return 请求地址
|
||||
*/
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private String buildUrl(String path) {
|
||||
// 生成 timestamp
|
||||
long timestamp = System.currentTimeMillis();
|
||||
// 生成 sign
|
||||
String secret = properties.getApiSecret();
|
||||
String stringToSign = timestamp + "\n" + secret;
|
||||
byte[] signData = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, StrUtil.bytes(secret)).digest(stringToSign);
|
||||
String sign = Base64.encode(signData);
|
||||
// 构建最终 URL
|
||||
return String.format("https://oapi.dingtalk.com/%s?access_token=%s×tamp=%d&sign=%s",
|
||||
path, properties.getApiKey(), timestamp, sign);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) {
|
||||
throw new UnsupportedOperationException("模拟短信客户端,暂时无需解析回调");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsTemplateRespDTO getSmsTemplate(String apiTemplateId) {
|
||||
return new SmsTemplateRespDTO().setId(apiTemplateId).setContent("")
|
||||
.setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getStatus()).setAuditReason("");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.impl;
|
||||
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.SmsClient;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.SmsClientFactory;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.enums.SmsChannelEnum;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.property.SmsChannelProperties;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* 短信客户端工厂接口
|
||||
*
|
||||
* @author zzf
|
||||
*/
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class SmsClientFactoryImpl implements SmsClientFactory {
|
||||
|
||||
/**
|
||||
* 短信客户端 Map
|
||||
* key:渠道编号,使用 {@link SmsChannelProperties#getId()}
|
||||
*/
|
||||
private final ConcurrentMap<Long, AbstractSmsClient> channelIdClients = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 短信客户端 Map
|
||||
* key:渠道编码,使用 {@link SmsChannelProperties#getCode()} ()}
|
||||
*
|
||||
* 注意,一些场景下,需要获得某个渠道类型的客户端,所以需要使用它。
|
||||
* 例如说,解析短信接收结果,是相对通用的,不需要使用某个渠道编号的 {@link #channelIdClients}
|
||||
*/
|
||||
private final ConcurrentMap<String, AbstractSmsClient> channelCodeClients = new ConcurrentHashMap<>();
|
||||
|
||||
public SmsClientFactoryImpl() {
|
||||
// 初始化 channelCodeClients 集合
|
||||
Arrays.stream(SmsChannelEnum.values()).forEach(channel -> {
|
||||
// 创建一个空的 SmsChannelProperties 对象
|
||||
SmsChannelProperties properties = new SmsChannelProperties().setCode(channel.getCode())
|
||||
.setApiKey("default default").setApiSecret("default");
|
||||
// 创建 Sms 客户端
|
||||
AbstractSmsClient smsClient = createSmsClient(properties);
|
||||
channelCodeClients.put(channel.getCode(), smsClient);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsClient getSmsClient(Long channelId) {
|
||||
return channelIdClients.get(channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsClient getSmsClient(String channelCode) {
|
||||
return channelCodeClients.get(channelCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOrUpdateSmsClient(SmsChannelProperties properties) {
|
||||
AbstractSmsClient client = channelIdClients.get(properties.getId());
|
||||
if (client == null) {
|
||||
client = this.createSmsClient(properties);
|
||||
client.init();
|
||||
channelIdClients.put(client.getId(), client);
|
||||
} else {
|
||||
client.refresh(properties);
|
||||
}
|
||||
}
|
||||
|
||||
private AbstractSmsClient createSmsClient(SmsChannelProperties properties) {
|
||||
SmsChannelEnum channelEnum = SmsChannelEnum.getByCode(properties.getCode());
|
||||
Assert.notNull(channelEnum, String.format("渠道类型(%s) 为空", channelEnum));
|
||||
// 创建客户端
|
||||
switch (channelEnum) {
|
||||
case ALIYUN: return new AliyunSmsClient(properties);
|
||||
case DEBUG_DING_TALK: return new DebugDingTalkSmsClient(properties);
|
||||
case TENCENT: return new TencentSmsClient(properties);
|
||||
}
|
||||
// 创建失败,错误日志 + 抛出异常
|
||||
log.error("[createSmsClient][配置({}) 找不到合适的客户端实现]", properties);
|
||||
throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", properties));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.client.impl;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.tool.framework.common.core.KeyValue;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.ArrayUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.json.JsonUtils;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||
import com.tencentcloudapi.sms.v20210111.models.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static com.jeelowcode.tool.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import static com.jeelowcode.tool.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||
|
||||
/**
|
||||
* 腾讯云短信功能实现
|
||||
*
|
||||
* 参见 <a href="https://cloud.tencent.com/document/product/382/52077">文档</a>
|
||||
*
|
||||
* @author shiwp
|
||||
*/
|
||||
public class TencentSmsClient extends AbstractSmsClient {
|
||||
|
||||
/**
|
||||
* 调用成功 code
|
||||
*/
|
||||
public static final String API_CODE_SUCCESS = "Ok";
|
||||
|
||||
/**
|
||||
* REGION,使用南京
|
||||
*/
|
||||
private static final String ENDPOINT = "ap-nanjing";
|
||||
|
||||
/**
|
||||
* 是否国际/港澳台短信:
|
||||
*
|
||||
* 0:表示国内短信。
|
||||
* 1:表示国际/港澳台短信。
|
||||
*/
|
||||
private static final long INTERNATIONAL_CHINA = 0L;
|
||||
|
||||
private SmsClient client;
|
||||
|
||||
public TencentSmsClient(SmsChannelProperties properties) {
|
||||
super(properties);
|
||||
Assert.notEmpty(properties.getApiSecret(), "apiSecret 不能为空");
|
||||
validateSdkAppId(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInit() {
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户密钥对 secretId,secretKey
|
||||
Credential credential = new Credential(getApiKey(), properties.getApiSecret());
|
||||
client = new SmsClient(credential, ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数校验腾讯云的 SDK AppId
|
||||
*
|
||||
* 原因是:腾讯云发放短信的时候,需要额外的参数 sdkAppId
|
||||
*
|
||||
* 解决方案:考虑到不破坏原有的 apiKey + apiSecret 的结构,所以将 secretId 拼接到 apiKey 字段中,格式为 "secretId sdkAppId"。
|
||||
*
|
||||
* @param properties 配置
|
||||
*/
|
||||
private static void validateSdkAppId(SmsChannelProperties properties) {
|
||||
String combineKey = properties.getApiKey();
|
||||
Assert.notEmpty(combineKey, "apiKey 不能为空");
|
||||
String[] keys = combineKey.trim().split(" ");
|
||||
Assert.isTrue(keys.length == 2, "腾讯云短信 apiKey 配置格式错误,请配置 为[secretId sdkAppId]");
|
||||
}
|
||||
|
||||
private String getSdkAppId() {
|
||||
return StrUtil.subAfter(properties.getApiKey(), " ", true);
|
||||
}
|
||||
|
||||
private String getApiKey() {
|
||||
return StrUtil.subBefore(properties.getApiKey(), " ", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsSendRespDTO sendSms(Long sendLogId, String mobile,
|
||||
String apiTemplateId, List<KeyValue<String, Object>> templateParams) throws Throwable {
|
||||
// 构建请求
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
request.setSmsSdkAppId(getSdkAppId());
|
||||
request.setPhoneNumberSet(new String[]{mobile});
|
||||
request.setSignName(properties.getSignature());
|
||||
request.setTemplateId(apiTemplateId);
|
||||
request.setTemplateParamSet(ArrayUtils.toArray(templateParams, e -> String.valueOf(e.getValue())));
|
||||
request.setSessionContext(JsonUtils.toJsonString(new SessionContext().setLogId(sendLogId)));
|
||||
// 执行请求
|
||||
SendSmsResponse response = client.SendSms(request);
|
||||
SendStatus status = response.getSendStatusSet()[0];
|
||||
return new SmsSendRespDTO().setSuccess(Objects.equals(status.getCode(), API_CODE_SUCCESS)).setSerialNo(status.getSerialNo())
|
||||
.setApiRequestId(response.getRequestId()).setApiCode(status.getCode()).setApiMsg(status.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) {
|
||||
List<SmsReceiveStatus> callback = JsonUtils.parseArray(text, SmsReceiveStatus.class);
|
||||
return convertList(callback, status -> new SmsReceiveRespDTO()
|
||||
.setSuccess(SmsReceiveStatus.SUCCESS_CODE.equalsIgnoreCase(status.getStatus()))
|
||||
.setErrorCode(status.getErrCode()).setErrorMsg(status.getDescription())
|
||||
.setMobile(status.getMobile()).setReceiveTime(status.getReceiveTime())
|
||||
.setSerialNo(status.getSerialNo()).setLogId(status.getSessionContext().getLogId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsTemplateRespDTO getSmsTemplate(String apiTemplateId) throws Throwable {
|
||||
// 构建请求
|
||||
DescribeSmsTemplateListRequest request = new DescribeSmsTemplateListRequest();
|
||||
request.setTemplateIdSet(new Long[]{Long.parseLong(apiTemplateId)});
|
||||
request.setInternational(INTERNATIONAL_CHINA);
|
||||
// 执行请求
|
||||
DescribeSmsTemplateListResponse response = client.DescribeSmsTemplateList(request);
|
||||
DescribeTemplateListStatus status = response.getDescribeTemplateStatusSet()[0];
|
||||
if (status == null || status.getStatusCode() == null) {
|
||||
return null;
|
||||
}
|
||||
return new SmsTemplateRespDTO().setId(status.getTemplateId().toString()).setContent(status.getTemplateContent())
|
||||
.setAuditStatus(convertSmsTemplateAuditStatus(status.getStatusCode().intValue())).setAuditReason(status.getReviewReply());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Integer convertSmsTemplateAuditStatus(int templateStatus) {
|
||||
switch (templateStatus) {
|
||||
case 1: return SmsTemplateAuditStatusEnum.CHECKING.getStatus();
|
||||
case 0: return SmsTemplateAuditStatusEnum.SUCCESS.getStatus();
|
||||
case -1: return SmsTemplateAuditStatusEnum.FAIL.getStatus();
|
||||
default: throw new IllegalArgumentException(String.format("未知审核状态(%d)", templateStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class SmsReceiveStatus {
|
||||
|
||||
/**
|
||||
* 短信接受成功 code
|
||||
*/
|
||||
public static final String SUCCESS_CODE = "SUCCESS";
|
||||
|
||||
/**
|
||||
* 用户实际接收到短信的时间
|
||||
*/
|
||||
@JsonProperty("user_receive_time")
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private LocalDateTime receiveTime;
|
||||
|
||||
/**
|
||||
* 国家(或地区)码
|
||||
*/
|
||||
@JsonProperty("nationcode")
|
||||
private String nationCode;
|
||||
|
||||
/**
|
||||
* 手机号码
|
||||
*/
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* 实际是否收到短信接收状态,SUCCESS(成功)、FAIL(失败)
|
||||
*/
|
||||
@JsonProperty("report_status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 用户接收短信状态码错误信息
|
||||
*/
|
||||
@JsonProperty("errmsg")
|
||||
private String errCode;
|
||||
|
||||
/**
|
||||
* 用户接收短信状态描述
|
||||
*/
|
||||
@JsonProperty("description")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 本次发送标识 ID(与发送接口返回的SerialNo对应)
|
||||
*/
|
||||
@JsonProperty("sid")
|
||||
private String serialNo;
|
||||
|
||||
/**
|
||||
* 用户的 session 内容(与发送接口的请求参数 SessionContext 一致)
|
||||
*/
|
||||
@JsonProperty("ext")
|
||||
private SessionContext sessionContext;
|
||||
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Data
|
||||
static class SessionContext {
|
||||
|
||||
/**
|
||||
* 发送短信记录id
|
||||
*/
|
||||
private Long logId;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.enums;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 短信渠道枚举
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021/1/25 10:56
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SmsChannelEnum {
|
||||
|
||||
DEBUG_DING_TALK("DEBUG_DING_TALK", "调试(钉钉)"),
|
||||
ALIYUN("ALIYUN", "阿里云"),
|
||||
TENCENT("TENCENT", "腾讯云"),
|
||||
// HUA_WEI("HUA_WEI", "华为云"),
|
||||
;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
private final String code;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
public static SmsChannelEnum getByCode(String code) {
|
||||
return ArrayUtil.firstMatch(o -> o.getCode().equals(code), values());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 短信模板的审核状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum SmsTemplateAuditStatusEnum {
|
||||
|
||||
CHECKING(1),
|
||||
SUCCESS(2),
|
||||
FAIL(3);
|
||||
|
||||
private final Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.jeelowcode.service.system.config.framework.sms.core.property;
|
||||
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.enums.SmsChannelEnum;
|
||||
import lombok.Data;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 短信渠道配置类
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021/1/25 17:01
|
||||
*/
|
||||
@Data
|
||||
@Validated
|
||||
public class SmsChannelProperties {
|
||||
|
||||
/**
|
||||
* 渠道编号
|
||||
*/
|
||||
@NotNull(message = "短信渠道 ID 不能为空")
|
||||
private Long id;
|
||||
/**
|
||||
* 短信签名
|
||||
*/
|
||||
@NotEmpty(message = "短信签名不能为空")
|
||||
private String signature;
|
||||
/**
|
||||
* 渠道编码
|
||||
*
|
||||
* 枚举 {@link SmsChannelEnum}
|
||||
*/
|
||||
@NotEmpty(message = "渠道编码不能为空")
|
||||
private String code;
|
||||
/**
|
||||
* 短信 API 的账号
|
||||
*/
|
||||
@NotEmpty(message = "短信 API 的账号不能为空")
|
||||
private String apiKey;
|
||||
/**
|
||||
* 短信 API 的密钥
|
||||
*/
|
||||
@NotEmpty(message = "短信 API 的密钥不能为空")
|
||||
private String apiSecret;
|
||||
/**
|
||||
* 短信发送回调 URL
|
||||
*/
|
||||
private String callbackUrl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.jeelowcode.service.system.config.framework.web.config;
|
||||
|
||||
import com.jeelowcode.tool.framework.swagger.config.SwaggerAutoConfiguration;
|
||||
import org.springdoc.core.GroupedOpenApi;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* system 模块的 web 组件的 Configuration
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class SystemWebConfiguration {
|
||||
|
||||
/**
|
||||
* system 模块的 API 分组
|
||||
*/
|
||||
@Bean
|
||||
public GroupedOpenApi systemGroupedOpenApi() {
|
||||
return SwaggerAutoConfiguration.buildGroupedOpenApi("system");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* system 模块的 web 配置
|
||||
*/
|
||||
package com.jeelowcode.service.system.config.framework.web;
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.jeelowcode.service.system.config.handler;
|
||||
|
||||
import com.jeelowcode.service.system.entity.TenantDO;
|
||||
|
||||
/**
|
||||
* 租户信息处理
|
||||
* 目的:尽量减少租户逻辑耦合到系统中
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface TenantInfoHandler {
|
||||
|
||||
/**
|
||||
* 基于传入的租户信息,进行相关逻辑的执行
|
||||
* 例如说,创建用户时,超过最大账户配额
|
||||
*
|
||||
* @param tenant 租户信息
|
||||
*/
|
||||
void handle(TenantDO tenant);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.jeelowcode.service.system.config.handler;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 租户菜单处理
|
||||
* 目的:尽量减少租户逻辑耦合到系统中
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface TenantMenuHandler {
|
||||
|
||||
/**
|
||||
* 基于传入的租户菜单【全】列表,进行相关逻辑的执行
|
||||
* 例如说,返回可分配菜单的时候,可以移除多余的
|
||||
*
|
||||
* @param menuIds 菜单列表
|
||||
*/
|
||||
void handle(Set<Long> menuIds);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.jeelowcode.service.system.config.job;
|
||||
|
||||
import com.jeelowcode.tool.framework.quartz.core.handler.JobHandler;
|
||||
import com.jeelowcode.tool.framework.tenant.core.context.TenantContextHolder;
|
||||
import com.jeelowcode.tool.framework.tenant.core.job.TenantJob;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import com.jeelowcode.service.system.mapper.AdminUserMapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DemoJob implements JobHandler {
|
||||
|
||||
@Resource
|
||||
private AdminUserMapper adminUserMapper;
|
||||
|
||||
@Override
|
||||
@TenantJob // 标记多租户
|
||||
public String execute(String param) {
|
||||
System.out.println("当前租户:" + TenantContextHolder.getTenantId());
|
||||
List<AdminUserDO> users = adminUserMapper.selectList();
|
||||
return "用户数量:" + users.size();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package com.jeelowcode.service.system.config.job;
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.jeelowcode.service.system.config.mq.consumer.mail;
|
||||
|
||||
import com.jeelowcode.service.system.config.mq.message.mail.MailSendMessage;
|
||||
import com.jeelowcode.service.system.service.IMailSendService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 针对 {@link MailSendMessage} 的消费者
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MailSendConsumer {
|
||||
|
||||
@Resource
|
||||
private IMailSendService mailSendService;
|
||||
|
||||
@EventListener
|
||||
@Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
|
||||
public void onMessage(MailSendMessage message) {
|
||||
log.info("[onMessage][消息内容({})]", message);
|
||||
mailSendService.doSendMail(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.jeelowcode.service.system.config.mq.consumer.sms;
|
||||
|
||||
import com.jeelowcode.service.system.config.mq.message.sms.SmsSendMessage;
|
||||
import com.jeelowcode.service.system.service.ISmsSendService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 针对 {@link SmsSendMessage} 的消费者
|
||||
*
|
||||
* @author zzf
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class SmsSendConsumer {
|
||||
|
||||
@Resource
|
||||
private ISmsSendService smsSendService;
|
||||
|
||||
@EventListener
|
||||
@Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
|
||||
public void onMessage(SmsSendMessage message) {
|
||||
log.info("[onMessage][消息内容({})]", message);
|
||||
smsSendService.doSendSms(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.jeelowcode.service.system.config.mq.message.mail;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 邮箱发送消息
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class MailSendMessage {
|
||||
|
||||
/**
|
||||
* 邮件日志编号
|
||||
*/
|
||||
@NotNull(message = "邮件日志编号不能为空")
|
||||
private Long logId;
|
||||
/**
|
||||
* 接收邮件地址
|
||||
*/
|
||||
@NotNull(message = "接收邮件地址不能为空")
|
||||
private String mail;
|
||||
/**
|
||||
* 邮件账号编号
|
||||
*/
|
||||
@NotNull(message = "邮件账号编号不能为空")
|
||||
private Long accountId;
|
||||
|
||||
/**
|
||||
* 邮件发件人
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 邮件标题
|
||||
*/
|
||||
@NotEmpty(message = "邮件标题不能为空")
|
||||
private String title;
|
||||
/**
|
||||
* 邮件内容
|
||||
*/
|
||||
@NotEmpty(message = "邮件内容不能为空")
|
||||
private String content;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.jeelowcode.service.system.config.mq.message.sms;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.core.KeyValue;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 短信发送消息
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class SmsSendMessage {
|
||||
|
||||
/**
|
||||
* 短信日志编号
|
||||
*/
|
||||
@NotNull(message = "短信日志编号不能为空")
|
||||
private Long logId;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
@NotNull(message = "手机号不能为空")
|
||||
private String mobile;
|
||||
/**
|
||||
* 短信渠道编号
|
||||
*/
|
||||
@NotNull(message = "短信渠道编号不能为空")
|
||||
private Long channelId;
|
||||
/**
|
||||
* 短信 API 的模板编号
|
||||
*/
|
||||
@NotNull(message = "短信 API 的模板编号不能为空")
|
||||
private String apiTemplateId;
|
||||
/**
|
||||
* 短信模板参数
|
||||
*/
|
||||
private List<KeyValue<String, Object>> templateParams;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.jeelowcode.service.system.config.mq.producer.mail;
|
||||
|
||||
import com.jeelowcode.service.system.config.mq.message.mail.MailSendMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Mail 邮件相关消息的 Producer
|
||||
*
|
||||
* @author wangjingyi
|
||||
* @since 2021/4/19 13:33
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MailProducer {
|
||||
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 发送 {@link MailSendMessage} 消息
|
||||
*
|
||||
* @param sendLogId 发送日志编码
|
||||
* @param mail 接收邮件地址
|
||||
* @param accountId 邮件账号编号
|
||||
* @param nickname 邮件发件人
|
||||
* @param title 邮件标题
|
||||
* @param content 邮件内容
|
||||
*/
|
||||
public void sendMailSendMessage(Long sendLogId, String mail, Long accountId,
|
||||
String nickname, String title, String content) {
|
||||
MailSendMessage message = new MailSendMessage()
|
||||
.setLogId(sendLogId).setMail(mail).setAccountId(accountId)
|
||||
.setNickname(nickname).setTitle(title).setContent(content);
|
||||
applicationContext.publishEvent(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.jeelowcode.service.system.config.mq.producer.sms;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.core.KeyValue;
|
||||
import com.jeelowcode.service.system.config.mq.message.sms.SmsSendMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sms 短信相关消息的 Producer
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021/3/9 16:35
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SmsProducer {
|
||||
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 发送 {@link SmsSendMessage} 消息
|
||||
*
|
||||
* @param logId 短信日志编号
|
||||
* @param mobile 手机号
|
||||
* @param channelId 渠道编号
|
||||
* @param apiTemplateId 短信模板编号
|
||||
* @param templateParams 短信模板参数
|
||||
*/
|
||||
public void sendSmsSendMessage(Long logId, String mobile,
|
||||
Long channelId, String apiTemplateId, List<KeyValue<String, Object>> templateParams) {
|
||||
SmsSendMessage message = new SmsSendMessage().setLogId(logId).setMobile(mobile);
|
||||
message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams);
|
||||
applicationContext.publishEvent(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.jeelowcode.service.system.config.redis;
|
||||
|
||||
import com.jeelowcode.service.system.entity.OAuth2AccessTokenDO;
|
||||
|
||||
/**
|
||||
* System Redis Key 枚举类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface RedisKeyConstants {
|
||||
|
||||
/**
|
||||
* 指定部门的所有子部门编号数组的缓存
|
||||
* <p>
|
||||
* KEY 格式:dept_children_ids:{id}
|
||||
* VALUE 数据类型:String 子部门编号集合
|
||||
*/
|
||||
String DEPT_CHILDREN_ID_LIST = "dept_children_ids";
|
||||
|
||||
/**
|
||||
* 角色的缓存
|
||||
* <p>
|
||||
* KEY 格式:role:{id}
|
||||
* VALUE 数据类型:String 角色信息
|
||||
*/
|
||||
String ROLE = "role";
|
||||
|
||||
/**
|
||||
* 用户拥有的角色编号的缓存
|
||||
* <p>
|
||||
* KEY 格式:user_role_ids:{userId}
|
||||
* VALUE 数据类型:String 角色编号集合
|
||||
*/
|
||||
String USER_ROLE_ID_LIST = "user_role_ids";
|
||||
|
||||
/**
|
||||
* 拥有指定菜单的角色编号的缓存
|
||||
* <p>
|
||||
* KEY 格式:user_role_ids:{menuId}
|
||||
* VALUE 数据类型:String 角色编号集合
|
||||
*/
|
||||
String MENU_ROLE_ID_LIST = "menu_role_ids";
|
||||
|
||||
/**
|
||||
* 拥有权限对应的菜单编号数组的缓存
|
||||
* <p>
|
||||
* KEY 格式:permission_menu_ids:{permission}
|
||||
* VALUE 数据类型:String 菜单编号数组
|
||||
*/
|
||||
String PERMISSION_MENU_ID_LIST = "permission_menu_ids";
|
||||
|
||||
/**
|
||||
* OAuth2 客户端的缓存
|
||||
* <p>
|
||||
* KEY 格式:user:{id}
|
||||
* VALUE 数据类型:String 客户端信息
|
||||
*/
|
||||
String OAUTH_CLIENT = "oauth_client";
|
||||
|
||||
/**
|
||||
* 访问令牌的缓存
|
||||
* <p>
|
||||
* KEY 格式:oauth2_access_token:{token}
|
||||
* VALUE 数据类型:String 访问令牌信息 {@link OAuth2AccessTokenDO}
|
||||
* <p>
|
||||
* 由于动态过期时间,使用 RedisTemplate 操作
|
||||
*/
|
||||
String OAUTH2_ACCESS_TOKEN = "oauth2_access_token:%s";
|
||||
|
||||
/**
|
||||
* 站内信模版的缓存
|
||||
* <p>
|
||||
* KEY 格式:notify_template:{code}
|
||||
* VALUE 数据格式:String 模版信息
|
||||
*/
|
||||
String NOTIFY_TEMPLATE = "notify_template";
|
||||
|
||||
/**
|
||||
* 邮件账号的缓存
|
||||
* <p>
|
||||
* KEY 格式:sms_template:{id}
|
||||
* VALUE 数据格式:String 账号信息
|
||||
*/
|
||||
String MAIL_ACCOUNT = "mail_account";
|
||||
|
||||
/**
|
||||
* 邮件模版的缓存
|
||||
* <p>
|
||||
* KEY 格式:mail_template:{code}
|
||||
* VALUE 数据格式:String 模版信息
|
||||
*/
|
||||
String MAIL_TEMPLATE = "mail_template";
|
||||
|
||||
/**
|
||||
* 短信模版的缓存
|
||||
* <p>
|
||||
* KEY 格式:sms_template:{id}
|
||||
* VALUE 数据格式:String 模版信息
|
||||
*/
|
||||
String SMS_TEMPLATE = "sms_template";
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.jeelowcode.service.system.config.redis.oauth2;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.CollectionUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.json.JsonUtils;
|
||||
import com.jeelowcode.service.system.entity.OAuth2AccessTokenDO;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.jeelowcode.service.system.config.redis.RedisKeyConstants.OAUTH2_ACCESS_TOKEN;
|
||||
|
||||
/**
|
||||
* {@link OAuth2AccessTokenDO} 的 RedisDAO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Repository
|
||||
public class OAuth2AccessTokenRedisDAO {
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
public OAuth2AccessTokenDO get(String accessToken) {
|
||||
String redisKey = formatKey(accessToken);
|
||||
return JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(redisKey), OAuth2AccessTokenDO.class);
|
||||
}
|
||||
|
||||
public void set(OAuth2AccessTokenDO accessTokenDO) {
|
||||
String redisKey = formatKey(accessTokenDO.getAccessToken());
|
||||
// 清理多余字段,避免缓存
|
||||
accessTokenDO.setUpdater(null).setUpdateTime(null).setCreateTime(null).setCreator(null).setDeleted(null);
|
||||
long time = LocalDateTimeUtil.between(LocalDateTime.now(), accessTokenDO.getExpiresTime(), ChronoUnit.SECONDS);
|
||||
if (time > 0) {
|
||||
stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(accessTokenDO), time, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public void delete(String accessToken) {
|
||||
String redisKey = formatKey(accessToken);
|
||||
stringRedisTemplate.delete(redisKey);
|
||||
}
|
||||
|
||||
public void deleteList(Collection<String> accessTokens) {
|
||||
List<String> redisKeys = CollectionUtils.convertList(accessTokens, OAuth2AccessTokenRedisDAO::formatKey);
|
||||
stringRedisTemplate.delete(redisKeys);
|
||||
}
|
||||
|
||||
private static String formatKey(String accessToken) {
|
||||
return String.format(OAUTH2_ACCESS_TOKEN, accessToken);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.jeelowcode.service.system.config.social;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.jeelowcode.service.system.util.SshUtils;
|
||||
import com.xingyuv.jushauth.cache.AuthStateCache;
|
||||
import com.xingyuv.jushauth.config.AuthConfig;
|
||||
import com.xingyuv.jushauth.config.AuthSource;
|
||||
import com.xingyuv.jushauth.exception.AuthException;
|
||||
import com.xingyuv.jushauth.model.AuthCallback;
|
||||
import com.xingyuv.jushauth.model.AuthToken;
|
||||
import com.xingyuv.jushauth.model.AuthUser;
|
||||
import com.xingyuv.jushauth.request.AuthDefaultRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Description: 中国星网认证
|
||||
* Author: JeeLow
|
||||
* Date: 2021/11/23 16:05
|
||||
*/
|
||||
@Slf4j
|
||||
public class ChinaSatelliteAuthRequest extends AuthDefaultRequest {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param config 配置
|
||||
* @param source 源
|
||||
*/
|
||||
public ChinaSatelliteAuthRequest(AuthConfig config, AuthSource source) {
|
||||
super(config, ChinaSatelliteAuthSource.CHINA_SATELLITE_NET);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param config 配置
|
||||
* @param authStateCache 缓存
|
||||
*/
|
||||
public ChinaSatelliteAuthRequest(AuthConfig config, AuthStateCache authStateCache) {
|
||||
super(config, ChinaSatelliteAuthSource.CHINA_SATELLITE_NET, authStateCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthToken getAccessToken(AuthCallback authCallback) {
|
||||
// 1.首先使用授权码获取token
|
||||
String responseStr = doPostAuthorizationCode(authCallback.getCode());
|
||||
JSONObject responseObj = JSONObject.parseObject(responseStr);
|
||||
|
||||
// 2.检查响应结果是否包含错误信息
|
||||
this.checkResponse(responseObj);
|
||||
|
||||
// 3.解析响应结果,获取token信息
|
||||
return AuthToken.builder()
|
||||
.accessToken(responseObj.getString("access_token"))
|
||||
.refreshToken(responseObj.getString("refresh_token"))
|
||||
.expireIn(responseObj.getInteger("expires_in"))
|
||||
.tokenType(responseObj.getString("token_type"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthUser getUserInfo(AuthToken authToken) {
|
||||
// 1.使用token获取用户信息
|
||||
String responseStr = doGetUserInfo(authToken);
|
||||
JSONObject responseObj = JSONObject.parseObject(responseStr);
|
||||
|
||||
// 2.检查响应结果是否包含错误信息
|
||||
this.checkResponse(responseObj);
|
||||
|
||||
// 3.解析响应结果,获取用户信息
|
||||
JSONObject result = responseObj.getJSONObject("result");
|
||||
Assert.notNull(result, () -> new AuthException("响应结果 result 不能为空"));
|
||||
return AuthUser.builder()
|
||||
.uuid(result.getString("id"))
|
||||
.nickname(result.getString("displayName"))
|
||||
.rawUserInfo(result)
|
||||
.token(authToken)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查响应结果是否包含错误信息
|
||||
*
|
||||
* @param response 响应结果
|
||||
*/
|
||||
private void checkResponse(JSONObject response) {
|
||||
if (response.containsKey("error")) {
|
||||
throw new AuthException(response.getString("error"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doPostAuthorizationCode(String code) {
|
||||
try {
|
||||
return HttpRequest.post(this.accessTokenUrl(code))
|
||||
.setSSLSocketFactory(SshUtils.createTrustAllSSLFactory())
|
||||
.execute().body();
|
||||
} catch (Exception e) {
|
||||
log.error("[getAccessToken][code({}) 获取token失败]", code, e);
|
||||
throw new AuthException("获取token失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doGetUserInfo(AuthToken authToken) {
|
||||
try {
|
||||
return HttpRequest.get(this.userInfoUrl(authToken))
|
||||
.header("Authorization", authToken.getAccessToken())
|
||||
.setSSLSocketFactory(SshUtils.createTrustAllSSLFactory())
|
||||
.execute().body();
|
||||
} catch (Exception e) {
|
||||
log.error("[getUserInfo][accessToken({}) 获取用户信息失败]", authToken.getAccessToken(), e);
|
||||
throw new AuthException("获取用户信息失败");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.jeelowcode.service.system.config.social;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.xingyuv.jushauth.config.AuthSource;
|
||||
import com.xingyuv.jushauth.request.AuthDefaultRequest;
|
||||
|
||||
/**
|
||||
* 中国星网办公网认证源
|
||||
* <p>
|
||||
* author: shelly chan
|
||||
* date: 2025/09/19
|
||||
*/
|
||||
public enum ChinaSatelliteAuthSource implements AuthSource {
|
||||
|
||||
/**
|
||||
* 获取认证授权地址
|
||||
*/
|
||||
CHINA_SATELLITE_NET {
|
||||
@Override
|
||||
public String authorize() {
|
||||
String profile = SpringUtil.getActiveProfile();
|
||||
if ("test".equals(profile)) {
|
||||
return "https://sso-sy.chinasatnet.com.cn/authn-api/v5/oauth/authorize";
|
||||
}
|
||||
// 默认返回生产环境地址
|
||||
return "https://sso-new.chinasatnet.com.cn/authn-api/v5/oauth/authorize";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String accessToken() {
|
||||
String profile = SpringUtil.getActiveProfile();
|
||||
if ("test".equals(profile)) {
|
||||
return "https://sso-sy.chinasatnet.com.cn/authn-api/v5/oauth/token";
|
||||
}
|
||||
return "https://sso-new.chinasatnet.com.cn/authn-api/v5/oauth/token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String userInfo() {
|
||||
String profile = SpringUtil.getActiveProfile();
|
||||
if ("test".equals(profile)) {
|
||||
return "https://sso-sy.chinasatnet.com.cn/authn-api/v5/oauth/user-info";
|
||||
}
|
||||
return "https://sso-new.chinasatnet.com.cn/authn-api/v5/oauth/user-info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends AuthDefaultRequest> getTargetClass() {
|
||||
return ChinaSatelliteAuthRequest.class;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.ip.core.Area;
|
||||
import com.jeelowcode.tool.framework.ip.core.utils.AreaUtils;
|
||||
import com.jeelowcode.tool.framework.ip.core.utils.IPUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.ip.AreaNodeRespVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 地区")
|
||||
@RestController
|
||||
@RequestMapping("/system/area")
|
||||
@Validated
|
||||
public class AreaController {
|
||||
|
||||
@GetMapping("/tree")
|
||||
@Operation(tags = "地区管理",summary = "获得地区树")
|
||||
public CommonResult<List<AreaNodeRespVO>> getAreaTree() {
|
||||
Area area = AreaUtils.getArea(Area.ID_CHINA);
|
||||
Assert.notNull(area, "获取不到中国");
|
||||
return success(BeanUtils.toBean(area.getChildren(), AreaNodeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-by-ip")
|
||||
@Operation(tags = "地区管理",summary = "获得 IP 对应的地区名")
|
||||
@Parameter(name = "ip", description = "IP", required = true)
|
||||
public CommonResult<String> getAreaByIp(
|
||||
@Valid
|
||||
@Pattern(regexp = "^(?:(\\\\d{1,2}|1\\\\d{2}|2[0-4]\\\\d|25[0-5])\\\\.){3}(\\\\d{1,2}|1\\\\d{2}|2[0-4]\\\\d|25[0-5])$", message = "ip格式不正确")
|
||||
@RequestParam("ip")
|
||||
String ip) {
|
||||
// 获得城市
|
||||
Area area = IPUtils.getArea(ip);
|
||||
if (area == null) {
|
||||
return success("未知");
|
||||
}
|
||||
// 格式化返回
|
||||
return success(AreaUtils.format(area.getId()));
|
||||
}
|
||||
|
||||
//------------------ jeelowcode --------------------
|
||||
@GetMapping("/tree-by-id")
|
||||
@Operation(tags = "地区管理",summary = "获得地区树")
|
||||
public CommonResult<List<AreaNodeRespVO>> getAreaTreeById(Integer pid) {
|
||||
Area area = AreaUtils.getArea(pid);
|
||||
Assert.notNull(area, "获取不到中国");
|
||||
|
||||
List<AreaNodeRespVO> resultList=new ArrayList<>();
|
||||
List<Area> children = area.getChildren();
|
||||
for(Area areaTmp:children){
|
||||
AreaNodeRespVO areaVo=new AreaNodeRespVO();
|
||||
areaVo.setId(areaTmp.getId());
|
||||
areaVo.setName(areaTmp.getName());
|
||||
areaVo.setLeaf(CollectionUtil.isEmpty(areaTmp.getChildren()));
|
||||
resultList.add(areaVo);
|
||||
}
|
||||
return success(resultList);
|
||||
}
|
||||
|
||||
@PostMapping("/view-parent-list")
|
||||
@Operation(tags = "地区管理",summary = "获取所有父级")
|
||||
public CommonResult<Map<Integer,List<AreaNodeRespVO>>> viewParentList(@RequestBody List<Integer> idList) {
|
||||
Map<Integer,List<AreaNodeRespVO>> resultMap=new HashMap<>();
|
||||
for(Integer id:idList){
|
||||
List<Area> areaList = AreaUtils.getAllParentList(id);
|
||||
|
||||
resultMap.put(id,BeanUtils.toBean(areaList, AreaNodeRespVO.class));
|
||||
}
|
||||
return success(resultMap);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.service.system.config.convert.auth.AuthConvert;
|
||||
import com.jeelowcode.service.system.constant.ErrorCodeConstants;
|
||||
import com.jeelowcode.service.system.controller.vo.auth.*;
|
||||
import com.jeelowcode.service.system.controller.vo.user.user.UserRespVO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import com.jeelowcode.service.system.entity.MenuDO;
|
||||
import com.jeelowcode.service.system.entity.RoleDO;
|
||||
import com.jeelowcode.service.system.entity.UserRoleDO;
|
||||
import com.jeelowcode.service.system.enums.LoginLogTypeEnum;
|
||||
import com.jeelowcode.service.system.service.*;
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.enums.UserTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.util.collection.CollectionUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.string.StrUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.tool.framework.security.config.SecurityProperties;
|
||||
import com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.jeelowcode.tool.framework.tenant.core.context.TenantContextHolder;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils.*;
|
||||
|
||||
@Tag(name = "管理后台 - 认证")
|
||||
@RestController
|
||||
@RequestMapping("/system/auth")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class AuthController {
|
||||
|
||||
@Resource
|
||||
private IAdminAuthService authService;
|
||||
@Resource
|
||||
private IAdminUserService userService;
|
||||
@Resource
|
||||
private IRoleService roleService;
|
||||
@Resource
|
||||
private IMenuService menuService;
|
||||
@Resource
|
||||
private IPermissionService permissionService;
|
||||
@Resource
|
||||
private ISocialClientService socialClientService;
|
||||
|
||||
@Resource
|
||||
private SecurityProperties securityProperties;
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@PostMapping("/login")
|
||||
@PermitAll
|
||||
@Operation(tags = "授权管理",summary = "使用账号密码登录")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
|
||||
return success(authService.login(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
@PermitAll
|
||||
@Operation(tags = "授权管理",summary = "登出系统")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<Boolean> logout(HttpServletRequest request) {
|
||||
logoutService(request);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/switch-login")
|
||||
@Operation(tags = "授权管理",summary = "切换部门登录")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<AuthLoginRespVO> switchLogin(@RequestBody SwitchLoginReqVO reqVO, HttpServletRequest request) {
|
||||
//先退出登录 ,然后再重新登录
|
||||
Long loginUserId = getLoginUserId();
|
||||
Long loginDeptId = reqVO.getLoginDeptId();
|
||||
Long loginRoleId = reqVO.getLoginRoleId();
|
||||
if(loginDeptId==null){
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_DEPT_NULL);
|
||||
}
|
||||
if(loginRoleId==null){
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_ROLE_NULL);
|
||||
}
|
||||
//获取该部门下的角色
|
||||
AdminUserDO user = userService.getUser(loginUserId);
|
||||
String deptIdsStr = user.getDeptId();
|
||||
if (StrUtil.isEmpty(deptIdsStr)) {
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_BIND_DEPT_NULL);
|
||||
}
|
||||
Set<Long> deptId = StrUtils.str2setLong(user.getDeptId());
|
||||
|
||||
if(CollectionUtil.isEmpty(deptId)){
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_BIND_DEPT_NULL);
|
||||
}
|
||||
if(loginDeptId!=-1 && !deptId.contains(loginDeptId)){
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_NOTIN_DEPT);
|
||||
}
|
||||
//判断该角色
|
||||
List<UserRoleDO> userRoleList = userService.getUserRoleList(user.getId(), loginDeptId);
|
||||
if(CollectionUtil.isEmpty(userRoleList)){
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_NOTIN_ROLE);
|
||||
}
|
||||
Map<Long, UserRoleDO> userRoleMap = CollectionUtils.convertMap(userRoleList, UserRoleDO::getRoleId);
|
||||
if(loginRoleId!=-1 && !userRoleMap.containsKey(loginRoleId)){
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_NOTIN_ROLE);
|
||||
}
|
||||
//校验通过
|
||||
//1.先退出旧的
|
||||
logoutService(request);
|
||||
//2.重新登录
|
||||
AuthLoginRespVO vo = authService.switchLogin(user.getId(), loginDeptId, loginRoleId);
|
||||
return success(vo);
|
||||
}
|
||||
|
||||
@PostMapping("/switch-tenant")
|
||||
@Operation(tags = "授权管理",summary = "切换租户登录(只允许超级管理员操作)")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<AuthLoginRespVO> switchTenant(@RequestBody SwitchTenantReqVO reqVO, HttpServletRequest request) {
|
||||
Long tenantId = reqVO.getTenantId();
|
||||
boolean supAdminToken = isSupAdmin();
|
||||
if(!supAdminToken){
|
||||
return CommonResult.error(ErrorCodeConstants.AUTH_SWITCH_LOGIN_USER_ISNOT_SUPADMIN);
|
||||
}
|
||||
//1.先退出旧的
|
||||
logoutService(request);
|
||||
//当前是超级管理员 -> 登录到当前租户下的管理
|
||||
TenantContextHolder.setTenantId(tenantId);
|
||||
AuthLoginRespVO vo = authService.supAdminSwitchTenantLogin(tenantId,true);
|
||||
|
||||
return success(vo);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/refresh-token")
|
||||
@PermitAll
|
||||
@Operation(tags = "授权管理",summary = "刷新令牌")
|
||||
@Parameter(name = "refreshToken", description = "刷新令牌", required = true)
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<AuthLoginRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
|
||||
return success(authService.refreshToken(refreshToken));
|
||||
}
|
||||
|
||||
@GetMapping("/get-permission-info")
|
||||
@Operation(tags = "授权管理",summary = "获取登录用户的权限信息")
|
||||
public CommonResult<AuthPermissionInfoRespVO> getPermissionInfo() {
|
||||
// 1.1 获得用户信息
|
||||
AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
if (user == null) {
|
||||
AuthPermissionInfoRespVO vo = new AuthPermissionInfoRespVO();
|
||||
return CommonResult.success(vo);
|
||||
}
|
||||
boolean supAdminFlag = userService.isSupAdmin(user.getId());//是否是超级管理员
|
||||
boolean tenantAdminFlag = userService.isTenantAdmin(user.getId());//是否是租户管理员
|
||||
|
||||
//获取当前登录部门和角色
|
||||
Long loginDeptId = getLoginDeptId();
|
||||
Long loginRoleId = getLoginRoleId();
|
||||
|
||||
//获取所有按钮权限
|
||||
Set<String> allButtonPermissionSets = menuService.getAllButtonPermissionSets();
|
||||
|
||||
// 1.2 获得角色列表
|
||||
Set<Long> roleIds =new HashSet<>();
|
||||
if(supAdminFlag || tenantAdminFlag){//超级管理员 或者租户管理员,直接查自身的所有权限
|
||||
roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId());
|
||||
}else{
|
||||
if(loginRoleId!=null){//当前登录有角色
|
||||
if(loginRoleId==-1){//该部门下的所有角色
|
||||
List<UserRoleDO> userRoleList = userService.getUserRoleList(user.getId(), loginDeptId);
|
||||
roleIds = userRoleList.stream()
|
||||
.map(UserRoleDO::getRoleId)
|
||||
.collect(Collectors.toSet());
|
||||
}else{
|
||||
roleIds.add(loginRoleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return success(AuthConvert.INSTANCE.convert(user, Collections.emptyList(), Collections.emptyList(),allButtonPermissionSets));
|
||||
}
|
||||
List<RoleDO> roles = roleService.getRoleList(roleIds);
|
||||
roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色
|
||||
|
||||
// 1.3 获得菜单列表
|
||||
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
|
||||
List<MenuDO> menuList = new ArrayList<>();
|
||||
if (!CollUtil.isEmpty(menuIds)) {
|
||||
menuList = menuService.getMenuList(menuIds);
|
||||
menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
|
||||
}
|
||||
Set<Long> deptId = StrUtils.str2setLong(user.getDeptId());
|
||||
|
||||
//部门角色信息
|
||||
List<UserRespVO.DeptInfo> deptInfoList = userService.getDeptInfo(user.getId(), deptId);
|
||||
|
||||
// 2. 拼接结果返回
|
||||
AuthPermissionInfoRespVO vo = AuthConvert.INSTANCE.convert(user, roles, menuList, allButtonPermissionSets);
|
||||
Map<String, List<String>> jeeLowCodeButtonPermissionMap = menuService.getJeeLowCodeButtonPermissionMap(vo.getPermissions());
|
||||
vo.setJeeLowCodepermissions(jeeLowCodeButtonPermissionMap);
|
||||
|
||||
|
||||
vo.setDeptInfoList(deptInfoList);
|
||||
AuthPermissionInfoRespVO.UserVO userVo = vo.getUser();
|
||||
userVo.setLoginDeptId(loginDeptId);
|
||||
userVo.setLoginRoleId(loginRoleId);
|
||||
userVo.setSupAdmin(supAdminFlag);//是否是超级管理员
|
||||
userVo.setTenantAdmin(tenantAdminFlag);//是否是租户管理员
|
||||
userVo.setSupAdminToken(SecurityFrameworkUtils.isSupAdmin());
|
||||
return success(vo);
|
||||
}
|
||||
|
||||
// ========== 短信登录相关 ==========
|
||||
|
||||
@PostMapping("/sms-login")
|
||||
@PermitAll
|
||||
@Operation(tags = "授权管理",summary = "使用短信验证码登录")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<AuthLoginRespVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
|
||||
return success(authService.smsLogin(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/send-sms-code")
|
||||
@PermitAll
|
||||
@Operation(tags = "授权管理",summary = "发送手机验证码")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<Boolean> sendLoginSmsCode(@RequestBody @Valid AuthSmsSendReqVO reqVO) {
|
||||
|
||||
authService.sendSmsCode(reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// ========== 社交登录相关 ==========
|
||||
|
||||
@GetMapping("/social-auth-redirect")
|
||||
@PermitAll
|
||||
@Operation(tags = "授权管理",summary = "社交授权的跳转")
|
||||
@Parameters({
|
||||
@Parameter(name = "type", description = "社交类型", required = true),
|
||||
@Parameter(name = "redirectUri", description = "回调路径")
|
||||
})
|
||||
public CommonResult<String> socialLogin(@RequestParam("type") Integer type,
|
||||
@RequestParam("redirectUri") String redirectUri) {
|
||||
return success(socialClientService.getAuthorizeUrl(
|
||||
type, UserTypeEnum.ADMIN.getValue(), redirectUri));
|
||||
}
|
||||
|
||||
@PostMapping("/social-login")
|
||||
@PermitAll
|
||||
@Operation(tags = "授权管理",summary = "社交快捷登录,使用 code 授权码", description = "适合未登录的用户,但是社交账号已绑定用户")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<AuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AuthSocialLoginReqVO reqVO) {
|
||||
return success(authService.socialLogin(reqVO));
|
||||
}
|
||||
|
||||
|
||||
//退出登录
|
||||
private void logoutService(HttpServletRequest request){
|
||||
Long loginUserId = getLoginUserId();
|
||||
|
||||
String token = SecurityFrameworkUtils.obtainAuthorization(request,
|
||||
securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
|
||||
if (StrUtil.isNotBlank(token)) {
|
||||
authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
|
||||
}
|
||||
//清空个人信息
|
||||
String userRedisKey="JEE_LOW_CODE:USER:"+loginUserId+":*";
|
||||
Set<String> keys = stringRedisTemplate.keys(userRedisKey);
|
||||
if(keys!=null && keys.size()>0){
|
||||
keys.forEach(key->{
|
||||
stringRedisTemplate.delete(key);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.tool.framework.common.util.servlet.ServletUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.xingyuv.captcha.model.common.ResponseModel;
|
||||
import com.xingyuv.captcha.model.vo.CaptchaVO;
|
||||
import com.xingyuv.captcha.service.CaptchaService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Tag(name = "管理后台 - 验证码")
|
||||
@RestController("adminCaptchaController")
|
||||
@RequestMapping("/system/captcha")
|
||||
public class CaptchaController {
|
||||
|
||||
@Resource
|
||||
private CaptchaService captchaService;
|
||||
|
||||
@PostMapping({"/get"})
|
||||
@Operation(tags = "验证码管理",summary = "获得验证码")
|
||||
@PermitAll
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) {
|
||||
assert request.getRemoteHost() != null;
|
||||
data.setBrowserInfo(getRemoteId(request));
|
||||
return captchaService.get(data);
|
||||
}
|
||||
|
||||
@PostMapping("/check")
|
||||
@Operation(tags = "验证码管理",summary = "校验验证码")
|
||||
@PermitAll
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) {
|
||||
data.setBrowserInfo(getRemoteId(request));
|
||||
return captchaService.check(data);
|
||||
}
|
||||
|
||||
public static String getRemoteId(HttpServletRequest request) {
|
||||
String ip = ServletUtils.getClientIP(request);
|
||||
String ua = request.getHeader("user-agent");
|
||||
if (StrUtil.isNotBlank(ip)) {
|
||||
return ip + ua;
|
||||
}
|
||||
return request.getRemoteAddr() + ua;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.dept.DeptListReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.dept.DeptRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.dept.DeptSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.dept.DeptSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.DeptDO;
|
||||
import com.jeelowcode.service.system.service.IDeptService;
|
||||
import com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 部门")
|
||||
@RestController
|
||||
@RequestMapping("/system/dept")
|
||||
@Validated
|
||||
public class DeptController {
|
||||
|
||||
@Resource
|
||||
private IDeptService deptService;
|
||||
|
||||
@PostMapping("create")
|
||||
@Operation(tags = "部门管理", summary = "创建部门")
|
||||
@PreAuthorize("@ss.hasPermission('system:dept:create')")
|
||||
public CommonResult<Long> createDept(@Valid @RequestBody DeptSaveReqVO createReqVO) {
|
||||
Long deptId = deptService.createDept(createReqVO);
|
||||
return success(deptId);
|
||||
}
|
||||
|
||||
@PutMapping("update")
|
||||
@Operation(tags = "部门管理", summary = "更新部门")
|
||||
@PreAuthorize("@ss.hasPermission('system:dept:update')")
|
||||
public CommonResult<Boolean> updateDept(@Valid @RequestBody DeptSaveReqVO updateReqVO) {
|
||||
deptService.updateDept(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("delete")
|
||||
@Operation(tags = "部门管理", summary = "删除部门")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:dept:delete')")
|
||||
public CommonResult<Boolean> deleteDept(@RequestParam("id") Long id) {
|
||||
deptService.deleteDept(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(tags = "部门管理", summary = "获取部门列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:dept:query')")
|
||||
public CommonResult<List<DeptRespVO>> getDeptList(DeptListReqVO reqVO) {
|
||||
List<DeptDO> list = deptService.getDeptList(reqVO);
|
||||
return success(BeanUtils.toBean(list, DeptRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "/simple-list"})
|
||||
@Operation(tags = "部门管理", summary = "获取部门精简信息列表", description = "只包含被开启的部门,主要用于前端的下拉选项")
|
||||
public CommonResult<List<DeptSimpleRespVO>> getSimpleDeptList() {
|
||||
List<DeptDO> list = deptService.getDeptList(
|
||||
new DeptListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
return success(BeanUtils.toBean(list, DeptSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "部门管理", summary = "获得部门信息")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:dept:query')")
|
||||
public CommonResult<DeptRespVO> getDept(@RequestParam("id") Long id) {
|
||||
DeptDO dept = deptService.getDept(id);
|
||||
return success(BeanUtils.toBean(dept, DeptRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-user-company")
|
||||
@Operation(tags = "部门管理", summary = "获得用户所在部门的公司部门")
|
||||
public CommonResult<DeptRespVO> getUserCompany() {
|
||||
Long loginDeptId = Objects.requireNonNull(SecurityFrameworkUtils.getLoginDeptId());
|
||||
DeptDO dept = deptService.getCompanyDept(loginDeptId);
|
||||
return success(BeanUtils.toBean(dept, DeptRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.data.DictDataPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.data.DictDataRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.data.DictDataSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.data.DictDataSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.DictDataDO;
|
||||
import com.jeelowcode.service.system.service.IDictDataService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 字典数据")
|
||||
@RestController
|
||||
@RequestMapping("/system/dict-data")
|
||||
@Validated
|
||||
public class DictDataController {
|
||||
|
||||
@Resource
|
||||
private IDictDataService dictDataService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "字典管理",summary = "新增字典数据")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:create')")
|
||||
public CommonResult<Long> createDictData(@Valid @RequestBody DictDataSaveReqVO createReqVO) {
|
||||
Long dictDataId = dictDataService.createDictData(createReqVO);
|
||||
return success(dictDataId);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "字典管理",summary = "修改字典数据")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:update')")
|
||||
public CommonResult<Boolean> updateDictData(@Valid @RequestBody DictDataSaveReqVO updateReqVO) {
|
||||
dictDataService.updateDictData(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "字典管理",summary = "删除字典数据")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:delete')")
|
||||
public CommonResult<Boolean> deleteDictData(Long id) {
|
||||
dictDataService.deleteDictData(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "字典管理",summary = "获得全部字典数据列表", description = "一般用于管理后台缓存字典数据在本地")
|
||||
// 无需添加权限认证,因为前端全局都需要
|
||||
public CommonResult<List<DictDataSimpleRespVO>> getSimpleDictDataList() {
|
||||
List<DictDataDO> list = dictDataService.getDictDataList(
|
||||
CommonStatusEnum.ENABLE.getStatus(), null);
|
||||
return success(BeanUtils.toBean(list, DictDataSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "字典管理",summary = "/获得字典类型的分页列表")
|
||||
//@PreAuthorize("@ss.hasPermission('system:dict:query')")
|
||||
public CommonResult<PageResult<DictDataRespVO>> getDictTypePage(@Valid DictDataPageReqVO pageReqVO) {
|
||||
PageResult<DictDataDO> pageResult = dictDataService.getDictDataPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, DictDataRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get")
|
||||
@Operation(tags = "字典管理",summary = "/查询字典数据详细")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:query')")
|
||||
public CommonResult<DictDataRespVO> getDictData(@RequestParam("id") Long id) {
|
||||
DictDataDO dictData = dictDataService.getDictData(id);
|
||||
return success(BeanUtils.toBean(dictData, DictDataRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@Operation(tags = "字典管理",summary = "导出字典数据")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void export(HttpServletResponse response, @Valid DictDataPageReqVO exportReqVO) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<DictDataDO> list = dictDataService.getDictDataPage(exportReqVO).getList();
|
||||
// 输出
|
||||
ExcelUtils.write(response, "字典数据.xls", "数据", DictDataRespVO.class,
|
||||
BeanUtils.toBean(list, DictDataRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.type.DictTypePageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.type.DictTypeRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.type.DictTypeSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dict.type.DictTypeSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.DictTypeDO;
|
||||
import com.jeelowcode.service.system.service.IDictTypeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 字典类型")
|
||||
@RestController
|
||||
@RequestMapping("/system/dict-type")
|
||||
@Validated
|
||||
public class DictTypeController {
|
||||
|
||||
@Resource
|
||||
private IDictTypeService dictTypeService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "字典管理",summary = "创建字典类型")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:create')")
|
||||
public CommonResult<Long> createDictType(@Valid @RequestBody DictTypeSaveReqVO createReqVO) {
|
||||
Long dictTypeId = dictTypeService.createDictType(createReqVO);
|
||||
return success(dictTypeId);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "字典管理",summary = "修改字典类型")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:update')")
|
||||
public CommonResult<Boolean> updateDictType(@Valid @RequestBody DictTypeSaveReqVO updateReqVO) {
|
||||
dictTypeService.updateDictType(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "字典管理",summary = "删除字典类型")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:delete')")
|
||||
public CommonResult<Boolean> deleteDictType(Long id) {
|
||||
dictTypeService.deleteDictType(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "字典管理",summary = "获得字典类型的分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:query')")
|
||||
public CommonResult<PageResult<DictTypeRespVO>> pageDictTypes(@Valid DictTypePageReqVO pageReqVO) {
|
||||
PageResult<DictTypeDO> pageResult = dictTypeService.getDictTypePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, DictTypeRespVO.class));
|
||||
}
|
||||
|
||||
@Operation(tags = "字典管理",summary = "/查询字典类型详细")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@GetMapping(value = "/get")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:query')")
|
||||
public CommonResult<DictTypeRespVO> getDictType(@RequestParam("id") Long id) {
|
||||
DictTypeDO dictType = dictTypeService.getDictType(id);
|
||||
return success(BeanUtils.toBean(dictType, DictTypeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "字典管理",summary = "获得全部字典类型列表", description = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项")
|
||||
// 无需添加权限认证,因为前端全局都需要
|
||||
public CommonResult<List<DictTypeSimpleRespVO>> getSimpleDictTypeList() {
|
||||
List<DictTypeDO> list = dictTypeService.getDictTypeList();
|
||||
return success(BeanUtils.toBean(list, DictTypeSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@Operation(tags = "字典管理",summary = "导出数据类型")
|
||||
@GetMapping("/export")
|
||||
@PreAuthorize("@ss.hasPermission('system:dict:query')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void export(HttpServletResponse response, @Valid DictTypePageReqVO exportReqVO) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<DictTypeDO> list = dictTypeService.getDictTypePage(exportReqVO).getList();
|
||||
// 导出
|
||||
ExcelUtils.write(response, "字典类型.xls", "数据", DictTypeRespVO.class,
|
||||
BeanUtils.toBean(list, DictTypeRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.duty.DutyPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.duty.DutyRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.duty.DutySaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.duty.DutySimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.DutyDO;
|
||||
import com.jeelowcode.service.system.service.IDutyService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 职务")
|
||||
@RestController
|
||||
@RequestMapping("/system/duty")
|
||||
@Validated
|
||||
public class DutyController {
|
||||
|
||||
@Resource
|
||||
private IDutyService dutyService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "职务管理",summary = "创建职务")
|
||||
@PreAuthorize("@ss.hasPermission('system:duty:create')")
|
||||
public CommonResult<Long> create(@Valid @RequestBody DutySaveReqVO createReqVO) {
|
||||
Long id = dutyService.createDuty(createReqVO);
|
||||
return success(id);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "职务管理",summary = "修改职务")
|
||||
@PreAuthorize("@ss.hasPermission('system:duty:update')")
|
||||
public CommonResult<Boolean> update(@Valid @RequestBody DutySaveReqVO updateReqVO) {
|
||||
dutyService.updateDuty(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "职务管理",summary = "删除职务")
|
||||
@PreAuthorize("@ss.hasPermission('system:duty:delete')")
|
||||
public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
|
||||
dutyService.deleteDuty(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get")
|
||||
@Operation(tags = "职务管理",summary = "获得职务信息")
|
||||
@Parameter(name = "id", description = "职务编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:duty:query')")
|
||||
public CommonResult<DutyRespVO> get(@RequestParam("id") Long id) {
|
||||
DutyDO duty = dutyService.getDuty(id);
|
||||
return success(BeanUtils.toBean(duty, DutyRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "职务管理",summary = "获取职务全列表", description = "只包含被开启的职务,主要用于前端的下拉选项")
|
||||
public CommonResult<List<DutySimpleRespVO>> getSimpleList() {
|
||||
// 获得职务列表,只要开启状态的
|
||||
List<DutyDO> list = dutyService.getDutyList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
// 排序后,返回给前端
|
||||
list.sort(Comparator.comparing(DutyDO::getSort));
|
||||
return success(BeanUtils.toBean(list, DutySimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "职务管理",summary = "获得职务分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:duty:query')")
|
||||
public CommonResult<PageResult<DutyRespVO>> getPage(@Validated DutyPageReqVO pageReqVO) {
|
||||
PageResult<DutyDO> pageResult = dutyService.getDutyPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, DutyRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@Operation(tags = "职务管理",summary = "职务管理")
|
||||
@PreAuthorize("@ss.hasPermission('system:duty:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void export(HttpServletResponse response, @Validated DutyPageReqVO reqVO) throws IOException {
|
||||
reqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<DutyDO> list = dutyService.getDutyPage(reqVO).getList();
|
||||
// 输出
|
||||
ExcelUtils.write(response, "职务数据.xls", "职务列表", DutyRespVO.class,
|
||||
BeanUtils.toBean(list, DutyRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.errorcode.ErrorCodePageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.errorcode.ErrorCodeRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.errorcode.ErrorCodeSaveReqVO;
|
||||
import com.jeelowcode.service.system.entity.ErrorCodeDO;
|
||||
import com.jeelowcode.service.system.service.IErrorCodeService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 错误码")
|
||||
@RestController
|
||||
@RequestMapping("/system/error-code")
|
||||
@Validated
|
||||
public class ErrorCodeController {
|
||||
|
||||
@Resource
|
||||
private IErrorCodeService errorCodeService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "错误码管理",summary = "创建错误码")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:create')")
|
||||
public CommonResult<Long> createErrorCode(@Valid @RequestBody ErrorCodeSaveReqVO createReqVO) {
|
||||
return success(errorCodeService.createErrorCode(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "错误码管理",summary = "更新错误码")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:update')")
|
||||
public CommonResult<Boolean> updateErrorCode(@Valid @RequestBody ErrorCodeSaveReqVO updateReqVO) {
|
||||
errorCodeService.updateErrorCode(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "错误码管理",summary = "删除错误码")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:delete')")
|
||||
public CommonResult<Boolean> deleteErrorCode(@RequestParam("id") Long id) {
|
||||
errorCodeService.deleteErrorCode(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "错误码管理",summary = "获得错误码")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:query')")
|
||||
public CommonResult<ErrorCodeRespVO> getErrorCode(@RequestParam("id") Long id) {
|
||||
ErrorCodeDO errorCode = errorCodeService.getErrorCode(id);
|
||||
return success(BeanUtils.toBean(errorCode, ErrorCodeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "错误码管理",summary = "获得错误码分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:query')")
|
||||
public CommonResult<PageResult<ErrorCodeRespVO>> getErrorCodePage(@Valid ErrorCodePageReqVO pageVO) {
|
||||
PageResult<ErrorCodeDO> pageResult = errorCodeService.getErrorCodePage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, ErrorCodeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(tags = "错误码管理",summary = "导出错误码 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:error-code:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportErrorCodeExcel(@Valid ErrorCodePageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<ErrorCodeDO> list = errorCodeService.getErrorCodePage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "错误码.xls", "数据", ErrorCodeRespVO.class,
|
||||
BeanUtils.toBean(list, ErrorCodeRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.logger.loginlog.LoginLogPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.logger.loginlog.LoginLogRespVO;
|
||||
import com.jeelowcode.service.system.entity.LoginLogDO;
|
||||
import com.jeelowcode.service.system.service.ILoginLogService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 登录日志")
|
||||
@RestController
|
||||
@RequestMapping("/system/login-log")
|
||||
@Validated
|
||||
public class LoginLogController {
|
||||
|
||||
@Resource
|
||||
private ILoginLogService loginLogService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "审查日志",summary = "获得登录日志分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:login-log:query')")
|
||||
public CommonResult<PageResult<LoginLogRespVO>> getLoginLogPage(@Valid LoginLogPageReqVO pageReqVO) {
|
||||
PageResult<LoginLogDO> pageResult = loginLogService.getLoginLogPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, LoginLogRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@Operation(tags = "审查日志",summary = "导出登录日志 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:login-log:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportLoginLog(HttpServletResponse response, @Valid LoginLogPageReqVO exportReqVO) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<LoginLogDO> list = loginLogService.getLoginLogPage(exportReqVO).getList();
|
||||
// 输出
|
||||
ExcelUtils.write(response, "登录日志.xls", "数据列表", LoginLogRespVO.class,
|
||||
BeanUtils.toBean(list, LoginLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.mail.account.MailAccountPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.mail.account.MailAccountRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.mail.account.MailAccountSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.mail.account.MailAccountSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.MailAccountDO;
|
||||
import com.jeelowcode.service.system.service.IMailAccountService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 邮箱账号")
|
||||
@RestController
|
||||
@RequestMapping("/system/mail-account")
|
||||
public class MailAccountController {
|
||||
|
||||
@Resource
|
||||
private IMailAccountService mailAccountService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "邮箱管理",summary = "创建邮箱账号")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:create')")
|
||||
public CommonResult<Long> createMailAccount(@Valid @RequestBody MailAccountSaveReqVO createReqVO) {
|
||||
return success(mailAccountService.createMailAccount(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "邮箱管理",summary = "修改邮箱账号")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:update')")
|
||||
public CommonResult<Boolean> updateMailAccount(@Valid @RequestBody MailAccountSaveReqVO updateReqVO) {
|
||||
mailAccountService.updateMailAccount(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "邮箱管理",summary = "删除邮箱账号")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:delete')")
|
||||
public CommonResult<Boolean> deleteMailAccount(@RequestParam Long id) {
|
||||
mailAccountService.deleteMailAccount(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮箱账号")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:get')")
|
||||
public CommonResult<MailAccountRespVO> getMailAccount(@RequestParam("id") Long id) {
|
||||
MailAccountDO account = mailAccountService.getMailAccount(id);
|
||||
return success(BeanUtils.toBean(account, MailAccountRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮箱账号分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-account:query')")
|
||||
public CommonResult<PageResult<MailAccountRespVO>> getMailAccountPage(@Valid MailAccountPageReqVO pageReqVO) {
|
||||
PageResult<MailAccountDO> pageResult = mailAccountService.getMailAccountPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, MailAccountRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮箱账号精简列表")
|
||||
public CommonResult<List<MailAccountSimpleRespVO>> getSimpleMailAccountList() {
|
||||
List<MailAccountDO> list = mailAccountService.getMailAccountList();
|
||||
return success(BeanUtils.toBean(list, MailAccountSimpleRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.mail.log.MailLogPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.mail.log.MailLogRespVO;
|
||||
import com.jeelowcode.service.system.entity.MailLogDO;
|
||||
import com.jeelowcode.service.system.service.IMailLogService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 邮件日志")
|
||||
@RestController
|
||||
@RequestMapping("/system/mail-log")
|
||||
public class MailLogController {
|
||||
|
||||
@Resource
|
||||
private IMailLogService mailLogService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮箱日志分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-log:query')")
|
||||
public CommonResult<PageResult<MailLogRespVO>> getMailLogPage(@Valid MailLogPageReqVO pageVO) {
|
||||
PageResult<MailLogDO> pageResult = mailLogService.getMailLogPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, MailLogRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮箱日志")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-log:query')")
|
||||
public CommonResult<MailLogRespVO> getMailTemplate(@RequestParam("id") Long id) {
|
||||
MailLogDO log = mailLogService.getMailLog(id);
|
||||
return success(BeanUtils.toBean(log, MailLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.service.system.controller.vo.mail.template.*;
|
||||
import com.jeelowcode.service.system.entity.MailTemplateDO;
|
||||
import com.jeelowcode.service.system.service.IMailSendService;
|
||||
import com.jeelowcode.service.system.service.IMailTemplateService;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 邮件模版")
|
||||
@RestController
|
||||
@RequestMapping("/system/mail-template")
|
||||
public class MailTemplateController {
|
||||
|
||||
@Resource
|
||||
private IMailTemplateService mailTempleService;
|
||||
@Resource
|
||||
private IMailSendService mailSendService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "邮箱管理",summary = "创建邮件模版")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:create')")
|
||||
public CommonResult<Long> createMailTemplate(@Valid @RequestBody MailTemplateSaveReqVO createReqVO){
|
||||
return success(mailTempleService.createMailTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "邮箱管理",summary = "修改邮件模版")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:update')")
|
||||
public CommonResult<Boolean> updateMailTemplate(@Valid @RequestBody MailTemplateSaveReqVO updateReqVO){
|
||||
mailTempleService.updateMailTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "邮箱管理",summary = "删除邮件模版")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:delete')")
|
||||
public CommonResult<Boolean> deleteMailTemplate(@RequestParam("id") Long id) {
|
||||
mailTempleService.deleteMailTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮件模版")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:get')")
|
||||
public CommonResult<MailTemplateRespVO> getMailTemplate(@RequestParam("id") Long id) {
|
||||
MailTemplateDO template = mailTempleService.getMailTemplate(id);
|
||||
return success(BeanUtils.toBean(template, MailTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮件模版分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:query')")
|
||||
public CommonResult<PageResult<MailTemplateRespVO>> getMailTemplatePage(@Valid MailTemplatePageReqVO pageReqVO) {
|
||||
PageResult<MailTemplateDO> pageResult = mailTempleService.getMailTemplatePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, MailTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "邮箱管理",summary = "获得邮件模版精简列表")
|
||||
public CommonResult<List<MailTemplateSimpleRespVO>> getSimpleTemplateList() {
|
||||
List<MailTemplateDO> list = mailTempleService.getMailTemplateList();
|
||||
return success(BeanUtils.toBean(list, MailTemplateSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/send-mail")
|
||||
@Operation(tags = "邮箱管理",summary = "发送短信")
|
||||
@PreAuthorize("@ss.hasPermission('system:mail-template:send-mail')")
|
||||
public CommonResult<Long> sendMail(@Valid @RequestBody MailTemplateSendReqVO sendReqVO) {
|
||||
return success(mailSendService.sendSingleMailToAdmin(sendReqVO.getMail(),
|
||||
sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.menu.MenuListReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.menu.MenuRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.menu.MenuSaveVO;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.menu.MenuSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.MenuDO;
|
||||
import com.jeelowcode.service.system.service.IMenuService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 菜单")
|
||||
@RestController
|
||||
@RequestMapping("/system/menu")
|
||||
@Validated
|
||||
public class MenuController {
|
||||
|
||||
@Resource
|
||||
private IMenuService menuService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "菜单管理",summary = "创建菜单")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu:create')")
|
||||
public CommonResult<Long> createMenu(@Valid @RequestBody MenuSaveVO createReqVO) {
|
||||
Long menuId = menuService.createMenu(createReqVO);
|
||||
return success(menuId);
|
||||
}
|
||||
|
||||
@PostMapping("/batch/create")
|
||||
@Operation(tags = "菜单管理",summary = "批量创建菜单")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu:create')")
|
||||
public CommonResult<List<Long>> createBatchMenu(@Valid @RequestBody List<MenuSaveVO> createReqVO) {
|
||||
List<Long> idList = menuService.createBatchMenu(createReqVO);
|
||||
return success(idList);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "菜单管理",summary = "修改菜单")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu:update')")
|
||||
public CommonResult<Boolean> updateMenu(@Valid @RequestBody MenuSaveVO updateReqVO) {
|
||||
menuService.updateMenu(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "菜单管理",summary = "删除菜单")
|
||||
@Parameter(name = "id", description = "角色编号", required= true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu:delete')")
|
||||
public CommonResult<Boolean> deleteMenu(@RequestBody List<Long> ids,String type) {
|
||||
for(Long id:ids){
|
||||
menuService.deleteMenu(id,type);
|
||||
}
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(tags = "菜单管理",summary = "获取菜单列表", description = "用于【菜单管理】界面")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu:query')")
|
||||
public CommonResult<List<MenuRespVO>> getMenuList(MenuListReqVO reqVO) {
|
||||
List<MenuDO> list = menuService.getMenuList(reqVO);
|
||||
list.sort(Comparator.comparing(MenuDO::getSort));
|
||||
return success(BeanUtils.toBean(list, MenuRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "菜单管理",summary = "获取菜单精简信息列表", description = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" +
|
||||
"在多租户的场景下,会只返回租户所在套餐有的菜单")
|
||||
public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() {
|
||||
List<MenuDO> list = menuService.getMenuListByTenant(
|
||||
new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
list.sort(Comparator.comparing(MenuDO::getSort));
|
||||
return success(BeanUtils.toBean(list, MenuSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "菜单管理",summary = "获取菜单信息")
|
||||
@PreAuthorize("@ss.hasPermission('system:menu:query')")
|
||||
public CommonResult<MenuRespVO> getMenu(Long id) {
|
||||
MenuDO menu = menuService.getMenu(id);
|
||||
return success(BeanUtils.toBean(menu, MenuRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.jeelowcode.tool.framework.common.enums.UserTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.infra.api.IApiWebSocketSenderApi;
|
||||
import com.jeelowcode.service.system.controller.vo.notice.NoticePageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.notice.NoticeRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.notice.NoticeSaveReqVO;
|
||||
import com.jeelowcode.service.system.entity.NoticeDO;
|
||||
import com.jeelowcode.service.system.service.INoticeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 通知公告")
|
||||
@RestController
|
||||
@RequestMapping("/system/notice")
|
||||
@Validated
|
||||
public class NoticeController {
|
||||
|
||||
@Resource
|
||||
private INoticeService noticeService;
|
||||
|
||||
@Resource
|
||||
private IApiWebSocketSenderApi apiWebSocketSenderApi;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "通知公告",summary = "创建通知公告")
|
||||
@PreAuthorize("@ss.hasPermission('system:notice:create')")
|
||||
public CommonResult<Long> createNotice(@Valid @RequestBody NoticeSaveReqVO createReqVO) {
|
||||
Long noticeId = noticeService.createNotice(createReqVO);
|
||||
return success(noticeId);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "通知公告",summary = "修改通知公告")
|
||||
@PreAuthorize("@ss.hasPermission('system:notice:update')")
|
||||
public CommonResult<Boolean> updateNotice(@Valid @RequestBody NoticeSaveReqVO updateReqVO) {
|
||||
noticeService.updateNotice(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "通知公告",summary = "删除通知公告")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:notice:delete')")
|
||||
public CommonResult<Boolean> deleteNotice(@RequestParam("id") Long id) {
|
||||
noticeService.deleteNotice(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "通知公告",summary = "获取通知公告列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:notice:query')")
|
||||
public CommonResult<PageResult<NoticeRespVO>> getNoticePage(@Validated NoticePageReqVO pageReqVO) {
|
||||
PageResult<NoticeDO> pageResult = noticeService.getNoticePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, NoticeRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "通知公告",summary = "获得通知公告")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:notice:query')")
|
||||
public CommonResult<NoticeRespVO> getNotice(@RequestParam("id") Long id) {
|
||||
NoticeDO notice = noticeService.getNotice(id);
|
||||
return success(BeanUtils.toBean(notice, NoticeRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/push")
|
||||
@Operation(tags = "通知公告",summary = "推送通知公告", description = "只发送给 websocket 连接在线的用户")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:notice:update')")
|
||||
public CommonResult<Boolean> push(@RequestParam("id") Long id) {
|
||||
NoticeDO notice = noticeService.getNotice(id);
|
||||
Assert.notNull(notice, "公告不能为空");
|
||||
// 通过 websocket 推送给在线的用户
|
||||
apiWebSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), "notice-push", notice);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.UserTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.notify.message.NotifyMessageMyPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.notify.message.NotifyMessagePageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.notify.message.NotifyMessageRespVO;
|
||||
import com.jeelowcode.service.system.entity.NotifyMessageDO;
|
||||
import com.jeelowcode.service.system.service.INotifyMessageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 我的站内信")
|
||||
@RestController
|
||||
@RequestMapping("/system/notify-message")
|
||||
@Validated
|
||||
public class NotifyMessageController {
|
||||
|
||||
@Resource
|
||||
private INotifyMessageService notifyMessageServicerApi;
|
||||
|
||||
// ========== 管理所有的站内信 ==========
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "站内信管理",summary = "获得站内信")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-message:query')")
|
||||
public CommonResult<NotifyMessageRespVO> getNotifyMessage(@RequestParam("id") Long id) {
|
||||
NotifyMessageDO message = notifyMessageServicerApi.getNotifyMessage(id);
|
||||
return success(BeanUtils.toBean(message, NotifyMessageRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "站内信管理",summary = "获得站内信分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-message:query')")
|
||||
public CommonResult<PageResult<NotifyMessageRespVO>> getNotifyMessagePage(@Valid NotifyMessagePageReqVO pageVO) {
|
||||
PageResult<NotifyMessageDO> pageResult = notifyMessageServicerApi.getNotifyMessagePage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, NotifyMessageRespVO.class));
|
||||
}
|
||||
|
||||
// ========== 查看自己的站内信 ==========
|
||||
|
||||
@GetMapping("/my-page")
|
||||
@Operation(tags = "站内信管理",summary = "获得我的站内信分页")
|
||||
public CommonResult<PageResult<NotifyMessageRespVO>> getMyMyNotifyMessagePage(@Valid NotifyMessageMyPageReqVO pageVO) {
|
||||
PageResult<NotifyMessageDO> pageResult = notifyMessageServicerApi.getMyMyNotifyMessagePage(pageVO,
|
||||
getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
||||
return success(BeanUtils.toBean(pageResult, NotifyMessageRespVO.class));
|
||||
}
|
||||
|
||||
@PutMapping("/update-read")
|
||||
@Operation(tags = "站内信管理",summary = "标记站内信为已读")
|
||||
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
|
||||
public CommonResult<Boolean> updateNotifyMessageRead(@RequestParam("ids") List<Long> ids) {
|
||||
notifyMessageServicerApi.updateNotifyMessageRead(ids, getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
||||
return success(Boolean.TRUE);
|
||||
}
|
||||
|
||||
@PutMapping("/update-all-read")
|
||||
@Operation(tags = "站内信管理",summary = "标记所有站内信为已读")
|
||||
public CommonResult<Boolean> updateAllNotifyMessageRead() {
|
||||
notifyMessageServicerApi.updateAllNotifyMessageRead(getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
||||
return success(Boolean.TRUE);
|
||||
}
|
||||
|
||||
@GetMapping("/get-unread-list")
|
||||
@Operation(tags = "站内信管理",summary = "获取当前用户的最新站内信列表,默认 10 条")
|
||||
@Parameter(name = "size", description = "10")
|
||||
public CommonResult<List<NotifyMessageRespVO>> getUnreadNotifyMessageList(
|
||||
@RequestParam(name = "size", defaultValue = "10") Integer size) {
|
||||
List<NotifyMessageDO> list = notifyMessageServicerApi.getUnreadNotifyMessageList(
|
||||
getLoginUserId(), UserTypeEnum.ADMIN.getValue(), size);
|
||||
return success(BeanUtils.toBean(list, NotifyMessageRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-unread-count")
|
||||
// @Operation(tags = "站内信管理",summary = "获得当前用户的未读站内信数量") //定时请求的,不做记录存储
|
||||
public CommonResult<Long> getUnreadNotifyMessageCount() {
|
||||
return success(notifyMessageServicerApi.getUnreadNotifyMessageCount(
|
||||
getLoginUserId(), UserTypeEnum.ADMIN.getValue()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.UserTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.notify.template.NotifyTemplatePageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.notify.template.NotifyTemplateRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.notify.template.NotifyTemplateSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.notify.template.NotifyTemplateSendReqVO;
|
||||
import com.jeelowcode.service.system.entity.NotifyTemplateDO;
|
||||
import com.jeelowcode.service.system.service.INotifySendService;
|
||||
import com.jeelowcode.service.system.service.INotifyTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 站内信模版")
|
||||
@RestController
|
||||
@RequestMapping("/system/notify-template")
|
||||
@Validated
|
||||
public class NotifyTemplateController {
|
||||
|
||||
@Resource
|
||||
private INotifyTemplateService notifyTemplateService;
|
||||
|
||||
@Resource
|
||||
private INotifySendService notifySendService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "站内信管理",summary = "创建站内信模版")
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-template:create')")
|
||||
public CommonResult<Long> createNotifyTemplate(@Valid @RequestBody NotifyTemplateSaveReqVO createReqVO) {
|
||||
return success(notifyTemplateService.createNotifyTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "站内信管理",summary = "更新站内信模版")
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-template:update')")
|
||||
public CommonResult<Boolean> updateNotifyTemplate(@Valid @RequestBody NotifyTemplateSaveReqVO updateReqVO) {
|
||||
notifyTemplateService.updateNotifyTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "站内信管理",summary = "删除站内信模版")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-template:delete')")
|
||||
public CommonResult<Boolean> deleteNotifyTemplate(@RequestParam("id") Long id) {
|
||||
notifyTemplateService.deleteNotifyTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "站内信管理",summary = "获得站内信模版")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-template:query')")
|
||||
public CommonResult<NotifyTemplateRespVO> getNotifyTemplate(@RequestParam("id") Long id) {
|
||||
NotifyTemplateDO template = notifyTemplateService.getNotifyTemplate(id);
|
||||
return success(BeanUtils.toBean(template, NotifyTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "站内信管理",summary = "获得站内信模版分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-template:query')")
|
||||
public CommonResult<PageResult<NotifyTemplateRespVO>> getNotifyTemplatePage(@Valid NotifyTemplatePageReqVO pageVO) {
|
||||
PageResult<NotifyTemplateDO> pageResult = notifyTemplateService.getNotifyTemplatePage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, NotifyTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/send-notify")
|
||||
@Operation(tags = "站内信管理",summary = "发送站内信")
|
||||
@PreAuthorize("@ss.hasPermission('system:notify-template:send-notify')")
|
||||
public CommonResult sendNotify(@Valid @RequestBody NotifyTemplateSendReqVO sendReqVO) {
|
||||
notifySendService.sendSingleNotifyToAdmin(sendReqVO.getUserIdList(),
|
||||
sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams());
|
||||
return success("成功");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.client.OAuth2ClientPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.client.OAuth2ClientRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.client.OAuth2ClientSaveReqVO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2ClientDO;
|
||||
import com.jeelowcode.service.system.service.IOAuth2ClientService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - OAuth2 客户端")
|
||||
@RestController
|
||||
@RequestMapping("/system/oauth2-client")
|
||||
@Validated
|
||||
public class OAuth2ClientController {
|
||||
|
||||
@Resource
|
||||
private IOAuth2ClientService oAuth2ClientService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "创建 OAuth2 客户端")
|
||||
@PreAuthorize("@ss.hasPermission('system:oauth2-client:create')")
|
||||
public CommonResult<Long> createOAuth2Client(@Valid @RequestBody OAuth2ClientSaveReqVO createReqVO) {
|
||||
return success(oAuth2ClientService.createOAuth2Client(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "更新 OAuth2 客户端")
|
||||
@PreAuthorize("@ss.hasPermission('system:oauth2-client:update')")
|
||||
public CommonResult<Boolean> updateOAuth2Client(@Valid @RequestBody OAuth2ClientSaveReqVO updateReqVO) {
|
||||
oAuth2ClientService.updateOAuth2Client(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "删除 OAuth2 客户端")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:oauth2-client:delete')")
|
||||
public CommonResult<Boolean> deleteOAuth2Client(@RequestParam("id") Long id) {
|
||||
oAuth2ClientService.deleteOAuth2Client(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "获得 OAuth2 客户端")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:oauth2-client:query')")
|
||||
public CommonResult<OAuth2ClientRespVO> getOAuth2Client(@RequestParam("id") Long id) {
|
||||
OAuth2ClientDO client = oAuth2ClientService.getOAuth2Client(id);
|
||||
return success(BeanUtils.toBean(client, OAuth2ClientRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "获得 OAuth2 客户端分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:oauth2-client:query')")
|
||||
public CommonResult<PageResult<OAuth2ClientRespVO>> getOAuth2ClientPage(@Valid OAuth2ClientPageReqVO pageVO) {
|
||||
PageResult<OAuth2ClientDO> pageResult = oAuth2ClientService.getOAuth2ClientPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, OAuth2ClientRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jeelowcode.tool.framework.common.enums.UserTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.util.http.HttpUtils;
|
||||
import com.jeelowcode.tool.framework.common.util.json.JsonUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.open.OAuth2OpenAccessTokenRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.open.OAuth2OpenAuthorizeInfoRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.open.OAuth2OpenCheckTokenRespVO;
|
||||
import com.jeelowcode.service.system.config.convert.oauth2.OAuth2OpenConvert;
|
||||
import com.jeelowcode.service.system.entity.OAuth2AccessTokenDO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2ApproveDO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2ClientDO;
|
||||
import com.jeelowcode.service.system.enums.OAuth2GrantTypeEnum;
|
||||
import com.jeelowcode.service.system.service.IOAuth2ApproveService;
|
||||
import com.jeelowcode.service.system.service.IOAuth2ClientService;
|
||||
import com.jeelowcode.service.system.service.IOAuth2GrantService;
|
||||
import com.jeelowcode.service.system.service.IOAuth2TokenService;
|
||||
import com.jeelowcode.service.system.util.OAuth2Utils;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||
import static com.jeelowcode.tool.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
/**
|
||||
* 提供给外部应用调用为主
|
||||
*
|
||||
* 一般来说,管理后台的 /system-api/* 是不直接提供给外部应用使用,主要是外部应用能够访问的数据与接口是有限的,而管理后台的 RBAC 无法很好的控制。
|
||||
* 参考大量的开放平台,都是独立的一套 OpenAPI,对应到【本系统】就是在 Controller 下新建 open 包,实现 /open-api/* 接口,然后通过 scope 进行控制。
|
||||
* 另外,一个公司如果有多个管理后台,它们 client_id 产生的 access token 相互之间是无法互通的,即无法访问它们系统的 API 接口,直到两个 client_id 产生信任授权。
|
||||
*
|
||||
* 考虑到【本系统】暂时不想做的过于复杂,默认只有获取到 access token 之后,可以访问【本系统】管理后台的 /system-api/* 所有接口,除非手动添加 scope 控制。
|
||||
* scope 的使用示例,可见 {@link OAuth2UserController} 类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Tag(name = "管理后台 - OAuth2.0 授权")
|
||||
@RestController
|
||||
@RequestMapping("/system/oauth2")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class OAuth2OpenController {
|
||||
|
||||
@Resource
|
||||
private IOAuth2GrantService oauth2GrantService;
|
||||
@Resource
|
||||
private IOAuth2ClientService oauth2ClientService;
|
||||
@Resource
|
||||
private IOAuth2ApproveService oauth2ApproveService;
|
||||
@Resource
|
||||
private IOAuth2TokenService oauth2TokenService;
|
||||
|
||||
/**
|
||||
* 对应 Spring Security OAuth 的 TokenEndpoint 类的 postAccessToken 方法
|
||||
*
|
||||
* 授权码 authorization_code 模式时:code + redirectUri + state 参数
|
||||
* 密码 password 模式时:username + password + scope 参数
|
||||
* 刷新 refresh_token 模式时:refreshToken 参数
|
||||
* 客户端 client_credentials 模式:scope 参数
|
||||
* 简化 implicit 模式时:不支持
|
||||
*
|
||||
* 注意,默认需要传递 client_id + client_secret 参数
|
||||
*/
|
||||
@PostMapping("/token")
|
||||
@PermitAll
|
||||
@Operation(tags = "OAuth2.0管理",summary = "获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用")
|
||||
@Parameters({
|
||||
@Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"),
|
||||
@Parameter(name = "code", description = "授权范围", example = "userinfo.read"),
|
||||
@Parameter(name = "redirect_uri", description = "重定向 URI", example = "https://www.iocoder.cn"),
|
||||
@Parameter(name = "state", description = "状态", example = "1"),
|
||||
@Parameter(name = "username", example = "tudou"),
|
||||
@Parameter(name = "password", example = "cai"), // 多个使用空格分隔
|
||||
@Parameter(name = "scope", example = "user_info"),
|
||||
@Parameter(name = "refresh_token", example = "123424233"),
|
||||
})
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request,
|
||||
@RequestParam("grant_type") String grantType,
|
||||
@RequestParam(value = "code", required = false) String code, // 授权码模式
|
||||
@RequestParam(value = "redirect_uri", required = false) String redirectUri, // 授权码模式
|
||||
@RequestParam(value = "state", required = false) String state, // 授权码模式
|
||||
@RequestParam(value = "username", required = false) String username, // 密码模式
|
||||
@RequestParam(value = "password", required = false) String password, // 密码模式
|
||||
@RequestParam(value = "scope", required = false) String scope, // 密码模式
|
||||
@RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式
|
||||
List<String> scopes = OAuth2Utils.buildScopes(scope);
|
||||
// 1.1 校验授权类型
|
||||
OAuth2GrantTypeEnum grantTypeEnum = OAuth2GrantTypeEnum.getByGranType(grantType);
|
||||
if (grantTypeEnum == null) {
|
||||
throw exception0(BAD_REQUEST.getCode(), StrUtil.format("未知授权类型({})", grantType));
|
||||
}
|
||||
if (grantTypeEnum == OAuth2GrantTypeEnum.IMPLICIT) {
|
||||
throw exception0(BAD_REQUEST.getCode(), "Token 接口不支持 implicit 授权模式");
|
||||
}
|
||||
|
||||
// 1.2 校验客户端
|
||||
String[] clientIdAndSecret = obtainBasicAuthorization(request);
|
||||
OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1],
|
||||
grantType, scopes, redirectUri);
|
||||
|
||||
// 2. 根据授权模式,获取访问令牌
|
||||
OAuth2AccessTokenDO accessTokenDO;
|
||||
switch (grantTypeEnum) {
|
||||
case AUTHORIZATION_CODE:
|
||||
accessTokenDO = oauth2GrantService.grantAuthorizationCodeForAccessToken(client.getClientId(), code, redirectUri, state);
|
||||
break;
|
||||
case PASSWORD:
|
||||
accessTokenDO = oauth2GrantService.grantPassword(username, password, client.getClientId(), scopes);
|
||||
break;
|
||||
case CLIENT_CREDENTIALS:
|
||||
accessTokenDO = oauth2GrantService.grantClientCredentials(client.getClientId(), scopes);
|
||||
break;
|
||||
case REFRESH_TOKEN:
|
||||
accessTokenDO = oauth2GrantService.grantRefreshToken(refreshToken, client.getClientId());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("未知授权类型:" + grantType);
|
||||
}
|
||||
Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查
|
||||
return success(OAuth2OpenConvert.INSTANCE.convert(accessTokenDO));
|
||||
}
|
||||
|
||||
@DeleteMapping("/token")
|
||||
@PermitAll
|
||||
@Operation(tags = "OAuth2.0管理",summary = "删除访问令牌")
|
||||
@Parameter(name = "token", required = true, description = "访问令牌", example = "biu")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<Boolean> revokeToken(HttpServletRequest request,
|
||||
@RequestParam("token") String token) {
|
||||
// 校验客户端
|
||||
String[] clientIdAndSecret = obtainBasicAuthorization(request);
|
||||
OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1],
|
||||
null, null, null);
|
||||
|
||||
// 删除访问令牌
|
||||
return success(oauth2GrantService.revokeToken(client.getClientId(), token));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对应 Spring Security OAuth 的 CheckTokenEndpoint 类的 checkToken 方法
|
||||
*/
|
||||
@PostMapping("/check-token")
|
||||
@PermitAll
|
||||
@Operation(tags = "OAuth2.0管理",summary = "校验访问令牌")
|
||||
@Parameter(name = "token", required = true, description = "访问令牌", example = "biu")
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<OAuth2OpenCheckTokenRespVO> checkToken(HttpServletRequest request,
|
||||
@RequestParam("token") String token) {
|
||||
// 校验客户端
|
||||
String[] clientIdAndSecret = obtainBasicAuthorization(request);
|
||||
oauth2ClientService.validOAuthClientFromCache(clientIdAndSecret[0], clientIdAndSecret[1],
|
||||
null, null, null);
|
||||
|
||||
// 校验令牌
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.checkAccessToken(token);
|
||||
Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查
|
||||
return success(OAuth2OpenConvert.INSTANCE.convert2(accessTokenDO));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对应 Spring Security OAuth 的 AuthorizationEndpoint 类的 authorize 方法
|
||||
*/
|
||||
@GetMapping("/authorize")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "获得授权信息", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用")
|
||||
@Parameter(name = "clientId", required = true, description = "客户端编号", example = "tudou")
|
||||
public CommonResult<OAuth2OpenAuthorizeInfoRespVO> authorize(@RequestParam("clientId") String clientId) {
|
||||
// 0. 校验用户已经登录。通过 Spring Security 实现
|
||||
|
||||
// 1. 获得 Client 客户端的信息
|
||||
OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientId);
|
||||
// 2. 获得用户已经授权的信息
|
||||
List<OAuth2ApproveDO> approves = oauth2ApproveService.getApproveList(getLoginUserId(), getUserType(), clientId);
|
||||
// 拼接返回
|
||||
return success(OAuth2OpenConvert.INSTANCE.convert(client, approves));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对应 Spring Security OAuth 的 AuthorizationEndpoint 类的 approveOrDeny 方法
|
||||
*
|
||||
* 场景一:【自动授权 autoApprove = true】
|
||||
* 刚进入 sso.vue 界面,调用该接口,用户历史已经给该应用做过对应的授权,或者 OAuth2Client 支持该 scope 的自动授权
|
||||
* 场景二:【手动授权 autoApprove = false】
|
||||
* 在 sso.vue 界面,用户选择好 scope 授权范围,调用该接口,进行授权。此时,approved 为 true 或者 false
|
||||
*
|
||||
* 因为前后端分离,Axios 无法很好的处理 302 重定向,所以和 Spring Security OAuth 略有不同,返回结果是重定向的 URL,剩余交给前端处理
|
||||
*/
|
||||
@PostMapping("/authorize")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "申请授权", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【提交】调用")
|
||||
@Parameters({
|
||||
@Parameter(name = "response_type", required = true, description = "响应类型", example = "code"),
|
||||
@Parameter(name = "client_id", required = true, description = "客户端编号", example = "tudou"),
|
||||
@Parameter(name = "scope", description = "授权范围", example = "userinfo.read"), // 使用 Map<String, Boolean> 格式,Spring MVC 暂时不支持这么接收参数
|
||||
@Parameter(name = "redirect_uri", required = true, description = "重定向 URI", example = "https://www.iocoder.cn"),
|
||||
@Parameter(name = "auto_approve", required = true, description = "用户是否接受", example = "true"),
|
||||
@Parameter(name = "state", example = "1")
|
||||
})
|
||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||
public CommonResult<String> approveOrDeny(@RequestParam("response_type") String responseType,
|
||||
@RequestParam("client_id") String clientId,
|
||||
@RequestParam(value = "scope", required = false) String scope,
|
||||
@RequestParam("redirect_uri") String redirectUri,
|
||||
@RequestParam(value = "auto_approve") Boolean autoApprove,
|
||||
@RequestParam(value = "state", required = false) String state) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Boolean> scopes = JsonUtils.parseObject(scope, Map.class);
|
||||
scopes = ObjectUtil.defaultIfNull(scopes, Collections.emptyMap());
|
||||
// 0. 校验用户已经登录。通过 Spring Security 实现
|
||||
|
||||
// 1.1 校验 responseType 是否满足 code 或者 token 值
|
||||
OAuth2GrantTypeEnum grantTypeEnum = getGrantTypeEnum(responseType);
|
||||
// 1.2 校验 redirectUri 重定向域名是否合法 + 校验 scope 是否在 Client 授权范围内
|
||||
OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientId, null,
|
||||
grantTypeEnum.getGrantType(), scopes.keySet(), redirectUri);
|
||||
|
||||
// 2.1 假设 approved 为 null,说明是场景一
|
||||
if (Boolean.TRUE.equals(autoApprove)) {
|
||||
// 如果无法自动授权通过,则返回空 url,前端不进行跳转
|
||||
if (!oauth2ApproveService.checkForPreApproval(getLoginUserId(), getUserType(), clientId, scopes.keySet())) {
|
||||
return success(null);
|
||||
}
|
||||
} else { // 2.2 假设 approved 非 null,说明是场景二
|
||||
// 如果计算后不通过,则跳转一个错误链接
|
||||
if (!oauth2ApproveService.updateAfterApproval(getLoginUserId(), getUserType(), clientId, scopes)) {
|
||||
return success(OAuth2Utils.buildUnsuccessfulRedirect(redirectUri, responseType, state,
|
||||
"access_denied", "User denied access"));
|
||||
}
|
||||
}
|
||||
|
||||
// 3.1 如果是 code 授权码模式,则发放 code 授权码,并重定向
|
||||
List<String> approveScopes = convertList(scopes.entrySet(), Map.Entry::getKey, Map.Entry::getValue);
|
||||
if (grantTypeEnum == OAuth2GrantTypeEnum.AUTHORIZATION_CODE) {
|
||||
return success(getAuthorizationCodeRedirect(getLoginUserId(), client, approveScopes, redirectUri, state));
|
||||
}
|
||||
// 3.2 如果是 token 则是 implicit 简化模式,则发送 accessToken 访问令牌,并重定向
|
||||
return success(getImplicitGrantRedirect(getLoginUserId(), client, approveScopes, redirectUri, state));
|
||||
}
|
||||
|
||||
private static OAuth2GrantTypeEnum getGrantTypeEnum(String responseType) {
|
||||
if (StrUtil.equals(responseType, "code")) {
|
||||
return OAuth2GrantTypeEnum.AUTHORIZATION_CODE;
|
||||
}
|
||||
if (StrUtil.equalsAny(responseType, "token")) {
|
||||
return OAuth2GrantTypeEnum.IMPLICIT;
|
||||
}
|
||||
throw exception0(BAD_REQUEST.getCode(), "response_type 参数值只允许 code 和 token");
|
||||
}
|
||||
|
||||
private String getImplicitGrantRedirect(Long userId, OAuth2ClientDO client,
|
||||
List<String> scopes, String redirectUri, String state) {
|
||||
// 1. 创建 access token 访问令牌
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2GrantService.grantImplicit(userId, getUserType(), client.getClientId(), scopes);
|
||||
Assert.notNull(accessTokenDO, "访问令牌不能为空"); // 防御性检查
|
||||
// 2. 拼接重定向的 URL
|
||||
// noinspection unchecked
|
||||
return OAuth2Utils.buildImplicitRedirectUri(redirectUri, accessTokenDO.getAccessToken(), state, accessTokenDO.getExpiresTime(),
|
||||
scopes, JsonUtils.parseObject(client.getAdditionalInformation(), Map.class));
|
||||
}
|
||||
|
||||
private String getAuthorizationCodeRedirect(Long userId, OAuth2ClientDO client,
|
||||
List<String> scopes, String redirectUri, String state) {
|
||||
// 1. 创建 code 授权码
|
||||
String authorizationCode = oauth2GrantService.grantAuthorizationCodeForCode(userId, getUserType(), client.getClientId(), scopes,
|
||||
redirectUri, state);
|
||||
// 2. 拼接重定向的 URL
|
||||
return OAuth2Utils.buildAuthorizationCodeRedirectUri(redirectUri, authorizationCode, state);
|
||||
}
|
||||
|
||||
private Integer getUserType() {
|
||||
return UserTypeEnum.ADMIN.getValue();
|
||||
}
|
||||
|
||||
private String[] obtainBasicAuthorization(HttpServletRequest request) {
|
||||
String[] clientIdAndSecret = HttpUtils.obtainBasicAuthorization(request);
|
||||
if (ArrayUtil.isEmpty(clientIdAndSecret) || clientIdAndSecret.length != 2) {
|
||||
throw exception0(BAD_REQUEST.getCode(), "client_id 或 client_secret 未正确传递");
|
||||
}
|
||||
return clientIdAndSecret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.token.OAuth2AccessTokenPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.token.OAuth2AccessTokenRespVO;
|
||||
import com.jeelowcode.service.system.entity.OAuth2AccessTokenDO;
|
||||
import com.jeelowcode.service.system.enums.LoginLogTypeEnum;
|
||||
import com.jeelowcode.service.system.service.IAdminAuthService;
|
||||
import com.jeelowcode.service.system.service.IOAuth2TokenService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - OAuth2.0 令牌")
|
||||
@RestController
|
||||
@RequestMapping("/system/oauth2-token")
|
||||
public class OAuth2TokenController {
|
||||
|
||||
@Resource
|
||||
private IOAuth2TokenService oauth2TokenService;
|
||||
@Resource
|
||||
private IAdminAuthService authService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "获得访问令牌分页", description = "只返回有效期内的")
|
||||
@PreAuthorize("@ss.hasPermission('system:oauth2-token:page')")
|
||||
public CommonResult<PageResult<OAuth2AccessTokenRespVO>> getAccessTokenPage(@Valid OAuth2AccessTokenPageReqVO reqVO) {
|
||||
PageResult<OAuth2AccessTokenDO> pageResult = oauth2TokenService.getAccessTokenPage(reqVO);
|
||||
return success(BeanUtils.toBean(pageResult, OAuth2AccessTokenRespVO.class));
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "删除访问令牌")
|
||||
@Parameter(name = "accessToken", description = "访问令牌", required = true, example = "tudou")
|
||||
@PreAuthorize("@ss.hasPermission('system:oauth2-token:delete')")
|
||||
public CommonResult<Boolean> deleteAccessToken(@RequestParam("accessToken") String accessToken) {
|
||||
authService.logout(accessToken, LoginLogTypeEnum.LOGOUT_DELETE.getType());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.user.OAuth2UserInfoRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.oauth2.user.OAuth2UserUpdateReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.user.profile.UserProfileUpdateReqVO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import com.jeelowcode.service.system.service.IDeptService;
|
||||
import com.jeelowcode.service.system.service.IPostService;
|
||||
import com.jeelowcode.service.system.service.IAdminUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
/**
|
||||
* 提供给外部应用调用为主
|
||||
*
|
||||
* 1. 在 getUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.read')") 注解,声明需要满足 scope = user.read
|
||||
* 2. 在 updateUserInfo 方法上,添加 @PreAuthorize("@ss.hasScope('user.write')") 注解,声明需要满足 scope = user.write
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Tag(name = "管理后台 - OAuth2.0 用户")
|
||||
@RestController
|
||||
@RequestMapping("/system/oauth2/user")
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class OAuth2UserController {
|
||||
|
||||
@Resource
|
||||
private IAdminUserService userService;
|
||||
@Resource
|
||||
private IDeptService deptService;
|
||||
@Resource
|
||||
private IPostService postService;
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "获得用户基本信息")
|
||||
@PreAuthorize("@ss.hasScope('user.read')") //
|
||||
public CommonResult<OAuth2UserInfoRespVO> getUserInfo() {
|
||||
// 获得用户基本信息
|
||||
AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
OAuth2UserInfoRespVO resp = BeanUtils.toBean(user, OAuth2UserInfoRespVO.class);
|
||||
// 获得部门信息
|
||||
/* if (user.getDeptId() != null) {
|
||||
DeptDO dept = deptService.getDept(user.getDeptId());
|
||||
resp.setDept(BeanUtils.toBean(dept, OAuth2UserInfoRespVO.Dept.class));
|
||||
}*/
|
||||
// 获得岗位信息
|
||||
/*if (CollUtil.isNotEmpty(user.getPostIds())) {
|
||||
List<PostDO> posts = postService.getPostList(user.getPostIds());
|
||||
resp.setPosts(BeanUtils.toBean(posts, OAuth2UserInfoRespVO.Post.class));
|
||||
}*/
|
||||
return success(resp);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "OAuth2.0管理",summary = "更新用户基本信息")
|
||||
@PreAuthorize("@ss.hasScope('user.write')")
|
||||
public CommonResult<Boolean> updateUserInfo(@Valid @RequestBody OAuth2UserUpdateReqVO reqVO) {
|
||||
// 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。
|
||||
// 主要是,AdminUserService 没有自己的 BO 对象,所以复用只能这么做
|
||||
userService.updateUserProfile(getLoginUserId(), BeanUtils.toBean(reqVO, UserProfileUpdateReqVO.class));
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.logger.operatelog.OperateLogPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.logger.operatelog.OperateLogRespVO;
|
||||
import com.jeelowcode.service.system.config.convert.logger.OperateLogConvert;
|
||||
import com.jeelowcode.service.system.entity.OperateLogDO;
|
||||
import com.jeelowcode.service.system.entity.AdminUserDO;
|
||||
import com.jeelowcode.service.system.service.IOperateLogService;
|
||||
import com.jeelowcode.service.system.service.IAdminUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 操作日志")
|
||||
@RestController
|
||||
@RequestMapping("/system/operate-log")
|
||||
@Validated
|
||||
public class OperateLogController {
|
||||
|
||||
@Resource
|
||||
private IOperateLogService operateLogService;
|
||||
@Resource
|
||||
private IAdminUserService userService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "审查日志",summary = "查看操作日志分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:operate-log:query')")
|
||||
public CommonResult<PageResult<OperateLogRespVO>> pageOperateLog(@Valid OperateLogPageReqVO pageReqVO) {
|
||||
PageResult<OperateLogDO> pageResult = operateLogService.getOperateLogPage(pageReqVO);
|
||||
// 获得拼接需要的数据
|
||||
Map<Long, AdminUserDO> userMap = userService.getUserMap(
|
||||
convertList(pageResult.getList(), OperateLogDO::getUserId));
|
||||
return success(new PageResult<>(OperateLogConvert.INSTANCE.convertList(pageResult.getList(), userMap),
|
||||
pageResult.getTotal()));
|
||||
}
|
||||
|
||||
@Operation(tags = "审查日志",summary = "导出操作日志")
|
||||
@GetMapping("/export")
|
||||
@PreAuthorize("@ss.hasPermission('system:operate-log:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportOperateLog(HttpServletResponse response, @Valid OperateLogPageReqVO exportReqVO) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<OperateLogDO> list = operateLogService.getOperateLogPage(exportReqVO).getList();
|
||||
// 输出
|
||||
Map<Long, AdminUserDO> userMap = userService.getUserMap(
|
||||
convertList(list, OperateLogDO::getUserId));
|
||||
ExcelUtils.write(response, "操作日志.xls", "数据列表", OperateLogRespVO.class,
|
||||
OperateLogConvert.INSTANCE.convertList(list, userMap));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.permission.PermissionAssignRoleDataScopeReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.permission.PermissionAssignRoleMenuReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.permission.PermissionAssignUserRoleReqVO;
|
||||
import com.jeelowcode.service.system.service.IPermissionService;
|
||||
import com.jeelowcode.service.system.service.ITenantService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 权限 Controller,提供赋予用户、角色的权限的 API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Tag(name = "管理后台 - 权限")
|
||||
@RestController
|
||||
@RequestMapping("/system/permission")
|
||||
public class PermissionController {
|
||||
|
||||
@Resource
|
||||
private IPermissionService permissionService;
|
||||
@Resource
|
||||
private ITenantService tenantService;
|
||||
|
||||
@Operation(tags = "菜单管理",summary = "获得角色拥有的菜单编号")
|
||||
@Parameter(name = "roleId", description = "角色编号", required = true)
|
||||
@GetMapping("/list-role-menus")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
|
||||
public CommonResult<Set<Long>> getRoleMenuList(Long roleId) {
|
||||
return success(permissionService.getRoleMenuListByRoleId(roleId));
|
||||
}
|
||||
|
||||
@PostMapping("/assign-role-menu")
|
||||
@Operation(tags = "菜单管理",summary = "赋予角色菜单")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
|
||||
public CommonResult<Boolean> assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) {
|
||||
// 开启多租户的情况下,需要过滤掉未开通的菜单
|
||||
tenantService.handleTenantMenu(menuIds -> reqVO.getMenuIds().removeIf(menuId -> !CollUtil.contains(menuIds, menuId)));
|
||||
|
||||
// 执行菜单的分配
|
||||
permissionService.assignRoleMenu(reqVO.getRoleId(), reqVO.getMenuIds());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/assign-role-data-scope")
|
||||
@Operation(tags = "菜单管理",summary = "赋予角色数据权限")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-data-scope')")
|
||||
public CommonResult<Boolean> assignRoleDataScope(@Valid @RequestBody PermissionAssignRoleDataScopeReqVO reqVO) {
|
||||
permissionService.assignRoleDataScope(reqVO.getRoleId(), reqVO.getDataScope(), reqVO.getDataScopeDeptIds());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Operation(tags = "菜单管理",summary = "获得管理员拥有的角色编号列表")
|
||||
@Parameter(name = "userId", description = "用户编号", required = true)
|
||||
@GetMapping("/list-user-roles")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')")
|
||||
public CommonResult<Set<Long>> listAdminRoles(@RequestParam("userId") Long userId) {
|
||||
return success(permissionService.getUserRoleIdListByUserId(userId));
|
||||
}
|
||||
|
||||
@Operation(tags = "菜单管理",summary = "赋予用户角色")
|
||||
@PostMapping("/assign-user-role")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')")
|
||||
public CommonResult<Boolean> assignUserRole(@Validated @RequestBody PermissionAssignUserRoleReqVO reqVO) {
|
||||
permissionService.assignUserRole(reqVO.getUserId(), reqVO.getRoleIds());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.position.PositionPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.position.PositionRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.position.PositionSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.position.PositionSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.PositionDO;
|
||||
import com.jeelowcode.service.system.service.IPositionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 职位")
|
||||
@RestController
|
||||
@RequestMapping("/system/position")
|
||||
@Validated
|
||||
public class PositionController {
|
||||
|
||||
@Resource
|
||||
private IPositionService positionService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "职位管理",summary = "创建职位")
|
||||
@PreAuthorize("@ss.hasPermission('system:position:create')")
|
||||
public CommonResult<Long> create(@Valid @RequestBody PositionSaveReqVO createReqVO) {
|
||||
Long id = positionService.createPosition(createReqVO);
|
||||
return success(id);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "职位管理",summary = "修改职位")
|
||||
@PreAuthorize("@ss.hasPermission('system:position:update')")
|
||||
public CommonResult<Boolean> update(@Valid @RequestBody PositionSaveReqVO updateReqVO) {
|
||||
positionService.updatePosition(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "职位管理",summary = "删除职位")
|
||||
@PreAuthorize("@ss.hasPermission('system:position:delete')")
|
||||
public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
|
||||
positionService.deletePosition(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get")
|
||||
@Operation(tags = "职位管理",summary = "获得职位信息")
|
||||
@Parameter(name = "id", description = "职位编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:position:query')")
|
||||
public CommonResult<PositionRespVO> get(@RequestParam("id") Long id) {
|
||||
PositionDO Position = positionService.getPosition(id);
|
||||
return success(BeanUtils.toBean(Position, PositionRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "职位管理",summary = "获取职位全列表", description = "只包含被开启的职位,主要用于前端的下拉选项")
|
||||
public CommonResult<List<PositionSimpleRespVO>> getSimpleList() {
|
||||
// 获得职位列表,只要开启状态的
|
||||
List<PositionDO> list = positionService.getPositionList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
// 排序后,返回给前端
|
||||
list.sort(Comparator.comparing(PositionDO::getSort));
|
||||
return success(BeanUtils.toBean(list, PositionSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "职位管理",summary = "获得职位分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:position:query')")
|
||||
public CommonResult<PageResult<PositionRespVO>> getPage(@Validated PositionPageReqVO pageReqVO) {
|
||||
PageResult<PositionDO> pageResult = positionService.getPositionPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, PositionRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@Operation(tags = "职位管理",summary = "职位管理")
|
||||
@PreAuthorize("@ss.hasPermission('system:position:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void export(HttpServletResponse response, @Validated PositionPageReqVO reqVO) throws IOException {
|
||||
reqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<PositionDO> list = positionService.getPositionPage(reqVO).getList();
|
||||
// 输出
|
||||
ExcelUtils.write(response, "职位数据.xls", "职位列表", PositionRespVO.class,
|
||||
BeanUtils.toBean(list, PositionRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.post.PostPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.post.PostSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.post.PostRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.post.PostSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.PostDO;
|
||||
import com.jeelowcode.service.system.service.IPostService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 岗位")
|
||||
@RestController
|
||||
@RequestMapping("/system/post")
|
||||
@Validated
|
||||
public class PostController {
|
||||
|
||||
@Resource
|
||||
private IPostService postService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "岗位管理",summary = "创建岗位")
|
||||
@PreAuthorize("@ss.hasPermission('system:post:create')")
|
||||
public CommonResult<Long> createPost(@Valid @RequestBody PostSaveReqVO createReqVO) {
|
||||
Long postId = postService.createPost(createReqVO);
|
||||
return success(postId);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "岗位管理",summary = "修改岗位")
|
||||
@PreAuthorize("@ss.hasPermission('system:post:update')")
|
||||
public CommonResult<Boolean> updatePost(@Valid @RequestBody PostSaveReqVO updateReqVO) {
|
||||
postService.updatePost(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "岗位管理",summary = "删除岗位")
|
||||
@PreAuthorize("@ss.hasPermission('system:post:delete')")
|
||||
public CommonResult<Boolean> deletePost(@RequestParam("id") Long id) {
|
||||
postService.deletePost(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get")
|
||||
@Operation(tags = "岗位管理",summary = "获得岗位信息")
|
||||
@Parameter(name = "id", description = "岗位编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:post:query')")
|
||||
public CommonResult<PostRespVO> getPost(@RequestParam("id") Long id) {
|
||||
PostDO post = postService.getPost(id);
|
||||
return success(BeanUtils.toBean(post, PostRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "岗位管理",summary = "获取岗位全列表", description = "只包含被开启的岗位,主要用于前端的下拉选项")
|
||||
public CommonResult<List<PostSimpleRespVO>> getSimplePostList() {
|
||||
// 获得岗位列表,只要开启状态的
|
||||
List<PostDO> list = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
// 排序后,返回给前端
|
||||
list.sort(Comparator.comparing(PostDO::getSort));
|
||||
return success(BeanUtils.toBean(list, PostSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "岗位管理",summary = "获得岗位分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:post:query')")
|
||||
public CommonResult<PageResult<PostRespVO>> getPostPage(@Validated PostPageReqVO pageReqVO) {
|
||||
PageResult<PostDO> pageResult = postService.getPostPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, PostRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@Operation(tags = "岗位管理",summary = "岗位管理")
|
||||
@PreAuthorize("@ss.hasPermission('system:post:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void export(HttpServletResponse response, @Validated PostPageReqVO reqVO) throws IOException {
|
||||
reqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<PostDO> list = postService.getPostPage(reqVO).getList();
|
||||
// 输出
|
||||
ExcelUtils.write(response, "岗位数据.xls", "岗位列表", PostRespVO.class,
|
||||
BeanUtils.toBean(list, PostRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.rank.RankPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.rank.RankRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.rank.RankSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.dept.rank.RankSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.RankDO;
|
||||
import com.jeelowcode.service.system.service.IRankService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 职级")
|
||||
@RestController
|
||||
@RequestMapping("/system/rank")
|
||||
@Validated
|
||||
public class RankController {
|
||||
|
||||
@Resource
|
||||
private IRankService rankService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "职级管理",summary = "创建职级")
|
||||
@PreAuthorize("@ss.hasPermission('system:rank:create')")
|
||||
public CommonResult<Long> create(@Valid @RequestBody RankSaveReqVO createReqVO) {
|
||||
Long id = rankService.createRank(createReqVO);
|
||||
return success(id);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "职级管理",summary = "修改职级")
|
||||
@PreAuthorize("@ss.hasPermission('system:rank:update')")
|
||||
public CommonResult<Boolean> update(@Valid @RequestBody RankSaveReqVO updateReqVO) {
|
||||
rankService.updateRank(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "职级管理",summary = "删除职级")
|
||||
@PreAuthorize("@ss.hasPermission('system:rank:delete')")
|
||||
public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
|
||||
rankService.deleteRank(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/get")
|
||||
@Operation(tags = "职级管理",summary = "获得职级信息")
|
||||
@Parameter(name = "id", description = "职级编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:rank:query')")
|
||||
public CommonResult<RankRespVO> get(@RequestParam("id") Long id) {
|
||||
RankDO Rank = rankService.getRank(id);
|
||||
return success(BeanUtils.toBean(Rank, RankRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "simple-list"})
|
||||
@Operation(tags = "职级管理",summary = "获取职级全列表", description = "只包含被开启的职级,主要用于前端的下拉选项")
|
||||
public CommonResult<List<RankSimpleRespVO>> getSimpleList() {
|
||||
// 获得职级列表,只要开启状态的
|
||||
List<RankDO> list = rankService.getRankList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
// 排序后,返回给前端
|
||||
list.sort(Comparator.comparing(RankDO::getSort));
|
||||
return success(BeanUtils.toBean(list, RankSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "职级管理",summary = "获得职级分页列表")
|
||||
@PreAuthorize("@ss.hasPermission('system:rank:query')")
|
||||
public CommonResult<PageResult<RankRespVO>> getPage(@Validated RankPageReqVO pageReqVO) {
|
||||
PageResult<RankDO> pageResult = rankService.getRankPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, RankRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
@Operation(tags = "职级管理",summary = "职级管理")
|
||||
@PreAuthorize("@ss.hasPermission('system:rank:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void export(HttpServletResponse response, @Validated RankPageReqVO reqVO) throws IOException {
|
||||
reqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<RankDO> list = rankService.getRankPage(reqVO).getList();
|
||||
// 输出
|
||||
ExcelUtils.write(response, "职级数据.xls", "职级列表", RankRespVO.class,
|
||||
BeanUtils.toBean(list, RankRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.jeelowcode.service.system.controller.vo.permission.role.*;
|
||||
import com.jeelowcode.service.system.entity.DictDataDO;
|
||||
import com.jeelowcode.service.system.entity.RoleDO;
|
||||
import com.jeelowcode.service.system.service.IDictDataService;
|
||||
import com.jeelowcode.service.system.service.IRoleService;
|
||||
import com.jeelowcode.tool.framework.common.enums.CommonStatusEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
@Tag(name = "管理后台 - 角色")
|
||||
@RestController
|
||||
@RequestMapping("/system/role")
|
||||
@Validated
|
||||
public class RoleController {
|
||||
|
||||
@Resource
|
||||
private IRoleService roleService;
|
||||
|
||||
@Resource
|
||||
private IDictDataService dictDataService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "菜单管理",summary = "创建角色")
|
||||
@PreAuthorize("@ss.hasPermission('system:role:create')")
|
||||
public CommonResult<Long> createRole(@Valid @RequestBody RoleSaveReqVO createReqVO) {
|
||||
return success(roleService.createRole(createReqVO, null,true));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "菜单管理",summary = "修改角色")
|
||||
@PreAuthorize("@ss.hasPermission('system:role:update')")
|
||||
public CommonResult<Boolean> updateRole(@Valid @RequestBody RoleSaveReqVO updateReqVO) {
|
||||
roleService.updateRole(updateReqVO,true);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@Operation(tags = "菜单管理",summary = "修改角色状态")
|
||||
@PreAuthorize("@ss.hasPermission('system:role:update')")
|
||||
public CommonResult<Boolean> updateRoleStatus(@Valid @RequestBody RoleUpdateStatusReqVO reqVO) {
|
||||
roleService.updateRoleStatus(reqVO.getId(), reqVO.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "菜单管理",summary = "删除角色")
|
||||
@Parameter(name = "id", description = "角色编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:role:delete')")
|
||||
public CommonResult<Boolean> deleteRole(@RequestParam("id") Long id) {
|
||||
roleService.deleteRole(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "菜单管理",summary = "获得角色信息")
|
||||
@PreAuthorize("@ss.hasPermission('system:role:query')")
|
||||
public CommonResult<RoleRespVO> getRole(@RequestParam("id") Long id) {
|
||||
RoleDO role = roleService.getRole(id);
|
||||
return success(BeanUtils.toBean(role, RoleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "菜单管理",summary = "获得角色分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:role:query')")
|
||||
public CommonResult<PageResult<RoleRespVO>> getRolePage(RolePageReqVO pageReqVO) {
|
||||
PageResult<RoleDO> pageResult = roleService.getRolePage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, RoleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "/simple-list"})
|
||||
@Operation(tags = "菜单管理",summary = "获取角色精简信息列表", description = "只包含被开启的角色,主要用于前端的下拉选项")
|
||||
public CommonResult<List<RoleSimpleRespVO>> getSimpleRoleList() {
|
||||
List<RoleDO> list = roleService.getRoleListByStatus(singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
list.sort(Comparator.comparing(RoleDO::getSort));
|
||||
return success(BeanUtils.toBean(list, RoleSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(tags = "菜单管理",summary = "导出角色 Excel")
|
||||
@OperateLog(type = EXPORT)
|
||||
@PreAuthorize("@ss.hasPermission('system:role:export')")
|
||||
public void export(HttpServletResponse response, @Validated RolePageReqVO exportReqVO) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<RoleDO> list = roleService.getRolePage(exportReqVO).getList();
|
||||
List<CopyRoleRespVO> roleRespVOList = BeanUtils.toBean(list, CopyRoleRespVO.class);
|
||||
List<DictDataDO> dictDataList = dictDataService.getListByDictType("system_data_scope");
|
||||
Map<String, String> dataScopeMap = dictDataList.stream()
|
||||
.collect(Collectors.toMap(DictDataDO::getValue, DictDataDO::getLabel, (existingValue, newValue) -> newValue));
|
||||
roleRespVOList.stream()
|
||||
.filter(item -> ObjectUtil.isNotEmpty(item.getDataScope()))
|
||||
.forEach(item -> {
|
||||
if (!dataScopeMap.containsKey(item.getDataScope())) {
|
||||
return;
|
||||
}
|
||||
item.setDataScope(dataScopeMap.get(item.getDataScope()));
|
||||
});
|
||||
// 输出
|
||||
ExcelUtils.write(response, "角色数据.xls", "数据", CopyRoleRespVO.class, roleRespVOList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.sensitiveword.SensitiveWordPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sensitiveword.SensitiveWordRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sensitiveword.SensitiveWordSaveVO;
|
||||
import com.jeelowcode.service.system.entity.SensitiveWordDO;
|
||||
import com.jeelowcode.service.system.service.ISensitiveWordService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 敏感词")
|
||||
@RestController
|
||||
@RequestMapping("/system/sensitive-word")
|
||||
@Validated
|
||||
public class SensitiveWordController {
|
||||
|
||||
@Resource
|
||||
private ISensitiveWordService sensitiveWordService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "敏感词管理",summary = "创建敏感词")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:create')")
|
||||
public CommonResult<Long> createSensitiveWord(@Valid @RequestBody SensitiveWordSaveVO createReqVO) {
|
||||
return success(sensitiveWordService.createSensitiveWord(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "敏感词管理",summary = "更新敏感词")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:update')")
|
||||
public CommonResult<Boolean> updateSensitiveWord(@Valid @RequestBody SensitiveWordSaveVO updateReqVO) {
|
||||
sensitiveWordService.updateSensitiveWord(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "敏感词管理",summary = "删除敏感词")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:delete')")
|
||||
public CommonResult<Boolean> deleteSensitiveWord(@RequestParam("id") Long id) {
|
||||
sensitiveWordService.deleteSensitiveWord(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "敏感词管理",summary = "获得敏感词")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
|
||||
public CommonResult<SensitiveWordRespVO> getSensitiveWord(@RequestParam("id") Long id) {
|
||||
SensitiveWordDO sensitiveWord = sensitiveWordService.getSensitiveWord(id);
|
||||
return success(BeanUtils.toBean(sensitiveWord, SensitiveWordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "敏感词管理",summary = "获得敏感词分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
|
||||
public CommonResult<PageResult<SensitiveWordRespVO>> getSensitiveWordPage(@Valid SensitiveWordPageReqVO pageVO) {
|
||||
PageResult<SensitiveWordDO> pageResult = sensitiveWordService.getSensitiveWordPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, SensitiveWordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(tags = "敏感词管理",summary = "导出敏感词 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportSensitiveWordExcel(@Valid SensitiveWordPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<SensitiveWordDO> list = sensitiveWordService.getSensitiveWordPage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "敏感词.xls", "数据", SensitiveWordRespVO.class,
|
||||
BeanUtils.toBean(list, SensitiveWordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get-tags")
|
||||
@Operation(tags = "敏感词管理",summary = "获取所有敏感词的标签数组")
|
||||
@PreAuthorize("@ss.hasPermission('system:sensitive-word:query')")
|
||||
public CommonResult<Set<String>> getSensitiveWordTagSet() {
|
||||
return success(sensitiveWordService.getSensitiveWordTagSet());
|
||||
}
|
||||
|
||||
@GetMapping("/validate-text")
|
||||
@Operation(tags = "敏感词管理",summary = "获得文本所包含的不合法的敏感词数组")
|
||||
public CommonResult<List<String>> validateText(@RequestParam("text") String text,
|
||||
@RequestParam(value = "tags", required = false) List<String> tags) {
|
||||
return success(sensitiveWordService.validateText(text, tags));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.util.servlet.ServletUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.config.framework.sms.core.enums.SmsChannelEnum;
|
||||
import com.jeelowcode.service.system.service.ISmsSendService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 短信回调")
|
||||
@RestController
|
||||
@RequestMapping("/system/sms/callback")
|
||||
public class SmsCallbackController {
|
||||
|
||||
@Resource
|
||||
private ISmsSendService smsSendService;
|
||||
|
||||
@PostMapping("/aliyun")
|
||||
@PermitAll
|
||||
@Operation(tags = "短信管理",summary = "阿里云短信的回调", description = "参见 https://help.aliyun.com/document_detail/120998.html 文档")
|
||||
@OperateLog(enable = false)
|
||||
public CommonResult<Boolean> receiveAliyunSmsStatus(HttpServletRequest request) throws Throwable {
|
||||
String text = ServletUtils.getBody(request);
|
||||
smsSendService.receiveSmsStatus(SmsChannelEnum.ALIYUN.getCode(), text);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/tencent")
|
||||
@PermitAll
|
||||
@Operation(tags = "短信管理",summary = "腾讯云短信的回调", description = "参见 https://cloud.tencent.com/document/product/382/52077 文档")
|
||||
@OperateLog(enable = false)
|
||||
public CommonResult<Boolean> receiveTencentSmsStatus(HttpServletRequest request) throws Throwable {
|
||||
String text = ServletUtils.getBody(request);
|
||||
smsSendService.receiveSmsStatus(SmsChannelEnum.TENCENT.getCode(), text);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.channel.SmsChannelPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.channel.SmsChannelRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.channel.SmsChannelSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.channel.SmsChannelSimpleRespVO;
|
||||
import com.jeelowcode.service.system.entity.SmsChannelDO;
|
||||
import com.jeelowcode.service.system.service.ISmsChannelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 短信渠道")
|
||||
@RestController
|
||||
@RequestMapping("system/sms-channel")
|
||||
public class SmsChannelController {
|
||||
|
||||
@Resource
|
||||
private ISmsChannelService smsChannelService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "短信管理",summary = "创建短信渠道")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-channel:create')")
|
||||
public CommonResult<Long> createSmsChannel(@Valid @RequestBody SmsChannelSaveReqVO createReqVO) {
|
||||
return success(smsChannelService.createSmsChannel(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "短信管理",summary = "更新短信渠道")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-channel:update')")
|
||||
public CommonResult<Boolean> updateSmsChannel(@Valid @RequestBody SmsChannelSaveReqVO updateReqVO) {
|
||||
smsChannelService.updateSmsChannel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "短信管理",summary = "删除短信渠道")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-channel:delete')")
|
||||
public CommonResult<Boolean> deleteSmsChannel(@RequestParam("id") Long id) {
|
||||
smsChannelService.deleteSmsChannel(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "短信管理",summary = "获得短信渠道")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-channel:query')")
|
||||
public CommonResult<SmsChannelRespVO> getSmsChannel(@RequestParam("id") Long id) {
|
||||
SmsChannelDO channel = smsChannelService.getSmsChannel(id);
|
||||
return success(BeanUtils.toBean(channel, SmsChannelRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "短信管理",summary = "获得短信渠道分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-channel:query')")
|
||||
public CommonResult<PageResult<SmsChannelRespVO>> getSmsChannelPage(@Valid SmsChannelPageReqVO pageVO) {
|
||||
PageResult<SmsChannelDO> pageResult = smsChannelService.getSmsChannelPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, SmsChannelRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "/simple-list"})
|
||||
@Operation(tags = "短信管理",summary = "获得短信渠道精简列表", description = "包含被禁用的短信渠道")
|
||||
public CommonResult<List<SmsChannelSimpleRespVO>> getSimpleSmsChannelList() {
|
||||
List<SmsChannelDO> list = smsChannelService.getSmsChannelList();
|
||||
list.sort(Comparator.comparing(SmsChannelDO::getId));
|
||||
return success(BeanUtils.toBean(list, SmsChannelSimpleRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.log.SmsLogPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.log.SmsLogRespVO;
|
||||
import com.jeelowcode.service.system.entity.SmsLogDO;
|
||||
import com.jeelowcode.service.system.service.ISmsLogService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 短信日志")
|
||||
@RestController
|
||||
@RequestMapping("/system/sms-log")
|
||||
@Validated
|
||||
public class SmsLogController {
|
||||
|
||||
@Resource
|
||||
private ISmsLogService smsLogService;
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "短信管理",summary = "获得短信日志分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-log:query')")
|
||||
public CommonResult<PageResult<SmsLogRespVO>> getSmsLogPage(@Valid SmsLogPageReqVO pageReqVO) {
|
||||
PageResult<SmsLogDO> pageResult = smsLogService.getSmsLogPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, SmsLogRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(tags = "短信管理",summary = "导出短信日志 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-log:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportSmsLogExcel(@Valid SmsLogPageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<SmsLogDO> list = smsLogService.getSmsLogPage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "短信日志.xls", "数据", SmsLogRespVO.class,
|
||||
BeanUtils.toBean(list, SmsLogRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageParam;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.template.SmsTemplatePageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.template.SmsTemplateRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.template.SmsTemplateSaveReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.sms.template.SmsTemplateSendReqVO;
|
||||
import com.jeelowcode.service.system.entity.SmsTemplateDO;
|
||||
import com.jeelowcode.service.system.service.ISmsTemplateService;
|
||||
import com.jeelowcode.service.system.service.ISmsSendService;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.excel.core.util.ExcelUtils;
|
||||
import com.jeelowcode.tool.framework.operatelog.core.annotations.OperateLog;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
@Tag(name = "管理后台 - 短信模板")
|
||||
@RestController
|
||||
@RequestMapping("/system/sms-template")
|
||||
public class SmsTemplateController {
|
||||
|
||||
@Resource
|
||||
private ISmsTemplateService smsTemplateService;
|
||||
@Resource
|
||||
private ISmsSendService smsSendService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "短信管理",summary = "创建短信模板")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:create')")
|
||||
public CommonResult<Long> createSmsTemplate(@Valid @RequestBody SmsTemplateSaveReqVO createReqVO) {
|
||||
return success(smsTemplateService.createSmsTemplate(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "短信管理",summary = "更新短信模板")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:update')")
|
||||
public CommonResult<Boolean> updateSmsTemplate(@Valid @RequestBody SmsTemplateSaveReqVO updateReqVO) {
|
||||
smsTemplateService.updateSmsTemplate(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "短信管理",summary = "删除短信模板")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:delete')")
|
||||
public CommonResult<Boolean> deleteSmsTemplate(@RequestParam("id") Long id) {
|
||||
smsTemplateService.deleteSmsTemplate(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "短信管理",summary = "获得短信模板")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:query')")
|
||||
public CommonResult<SmsTemplateRespVO> getSmsTemplate(@RequestParam("id") Long id) {
|
||||
SmsTemplateDO template = smsTemplateService.getSmsTemplate(id);
|
||||
return success(BeanUtils.toBean(template, SmsTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "短信管理",summary = "获得短信模板分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:query')")
|
||||
public CommonResult<PageResult<SmsTemplateRespVO>> getSmsTemplatePage(@Valid SmsTemplatePageReqVO pageVO) {
|
||||
PageResult<SmsTemplateDO> pageResult = smsTemplateService.getSmsTemplatePage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, SmsTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(tags = "短信管理",summary = "导出短信模板 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportSmsTemplateExcel(@Valid SmsTemplatePageReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<SmsTemplateDO> list = smsTemplateService.getSmsTemplatePage(exportReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "短信模板.xls", "数据", SmsTemplateRespVO.class,
|
||||
BeanUtils.toBean(list, SmsTemplateRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/send-sms")
|
||||
@Operation(tags = "短信管理",summary = "发送短信")
|
||||
@PreAuthorize("@ss.hasPermission('system:sms-template:send-sms')")
|
||||
public CommonResult<Long> sendSms(@Valid @RequestBody SmsTemplateSendReqVO sendReqVO) {
|
||||
return success(smsSendService.sendSingleSmsToAdmin(sendReqVO.getMobile(), sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.client.SocialClientPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.client.SocialClientRespVO;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.client.SocialClientSaveReqVO;
|
||||
import com.jeelowcode.service.system.entity.SocialClientDO;
|
||||
import com.jeelowcode.service.system.service.ISocialClientService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 社交客户端")
|
||||
@RestController
|
||||
@RequestMapping("/system/social-client")
|
||||
@Validated
|
||||
public class SocialClientController {
|
||||
|
||||
@Resource
|
||||
private ISocialClientService socialClientService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(tags = "社交管理",summary = "创建社交客户端")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:create')")
|
||||
public CommonResult<Long> createSocialClient(@Valid @RequestBody SocialClientSaveReqVO createReqVO) {
|
||||
return success(socialClientService.createSocialClient(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(tags = "社交管理",summary = "更新社交客户端")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:update')")
|
||||
public CommonResult<Boolean> updateSocialClient(@Valid @RequestBody SocialClientSaveReqVO updateReqVO) {
|
||||
socialClientService.updateSocialClient(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(tags = "社交管理",summary = "删除社交客户端")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:delete')")
|
||||
public CommonResult<Boolean> deleteSocialClient(@RequestParam("id") Long id) {
|
||||
socialClientService.deleteSocialClient(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "社交管理",summary = "获得社交客户端")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:query')")
|
||||
public CommonResult<SocialClientRespVO> getSocialClient(@RequestParam("id") Long id) {
|
||||
SocialClientDO client = socialClientService.getSocialClient(id);
|
||||
return success(BeanUtils.toBean(client, SocialClientRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "社交管理",summary = "获得社交客户端分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-client:query')")
|
||||
public CommonResult<PageResult<SocialClientRespVO>> getSocialClientPage(@Valid SocialClientPageReqVO pageVO) {
|
||||
PageResult<SocialClientDO> pageResult = socialClientService.getSocialClientPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, SocialClientRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.jeelowcode.service.system.controller;
|
||||
|
||||
import com.jeelowcode.tool.framework.common.enums.UserTypeEnum;
|
||||
import com.jeelowcode.tool.framework.common.pojo.CommonResult;
|
||||
import com.jeelowcode.tool.framework.common.pojo.PageResult;
|
||||
import com.jeelowcode.tool.framework.common.util.object.BeanUtils;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.user.SocialUserBindReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.user.SocialUserUnbindReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.user.SocialUserPageReqVO;
|
||||
import com.jeelowcode.service.system.controller.vo.socail.user.SocialUserRespVO;
|
||||
import com.jeelowcode.service.system.config.convert.social.SocialUserConvert;
|
||||
import com.jeelowcode.service.system.entity.SocialUserDO;
|
||||
import com.jeelowcode.service.system.service.ISocialUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static com.jeelowcode.tool.framework.common.pojo.CommonResult.success;
|
||||
import static com.jeelowcode.tool.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - 社交用户")
|
||||
@RestController
|
||||
@RequestMapping("/system/social-user")
|
||||
@Validated
|
||||
public class SocialUserController {
|
||||
|
||||
@Resource
|
||||
private ISocialUserService socialUserService;
|
||||
|
||||
@PostMapping("/bind")
|
||||
@Operation(tags = "社交管理",summary = "社交绑定,使用 code 授权码")
|
||||
public CommonResult<Boolean> socialBind(@RequestBody @Valid SocialUserBindReqVO reqVO) {
|
||||
socialUserService.bindSocialUser(SocialUserConvert.INSTANCE.convert(
|
||||
getLoginUserId(), UserTypeEnum.ADMIN.getValue(), reqVO));
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/unbind")
|
||||
@Operation(tags = "社交管理",summary = "取消社交绑定")
|
||||
public CommonResult<Boolean> socialUnbind(@RequestBody SocialUserUnbindReqVO reqVO) {
|
||||
socialUserService.unbindSocialUser(getLoginUserId(), UserTypeEnum.ADMIN.getValue(), reqVO.getType(), reqVO.getOpenid());
|
||||
return CommonResult.success(true);
|
||||
}
|
||||
|
||||
// ==================== 社交用户 CRUD ====================
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(tags = "社交管理",summary = "获得社交用户")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-user:query')")
|
||||
public CommonResult<SocialUserRespVO> getSocialUser(@RequestParam("id") Long id) {
|
||||
SocialUserDO socialUser = socialUserService.getSocialUser(id);
|
||||
return success(BeanUtils.toBean(socialUser, SocialUserRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(tags = "社交管理",summary = "获得社交用户分页")
|
||||
@PreAuthorize("@ss.hasPermission('system:social-user:query')")
|
||||
public CommonResult<PageResult<SocialUserRespVO>> getSocialUserPage(@Valid SocialUserPageReqVO pageVO) {
|
||||
PageResult<SocialUserDO> pageResult = socialUserService.getSocialUserPage(pageVO);
|
||||
return success(BeanUtils.toBean(pageResult, SocialUserRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user