dev #2

Merged
bunny merged 3 commits from dev into master 2024-05-21 21:20:58 +08:00
39 changed files with 524 additions and 603 deletions
Showing only changes of commit 0c4612ff2f - Show all commits

View File

@ -17,16 +17,17 @@
</properties>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>cn.bunny</groupId>
<artifactId>model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<!-- knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>

View File

@ -26,7 +26,7 @@ public class Knife4jConfig {
return new OpenAPI().info(info).externalDocs(new ExternalDocumentation());
}
// 管理员相关分类接口
// 前台相关分类接口
@Bean
public GroupedOpenApi groupedOpenApi() {
return GroupedOpenApi.builder().group("前台接口管理").pathsToMatch("/api/**").build();

View File

@ -18,10 +18,18 @@
</properties>
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- hutool -->
<!-- hu tool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!-- fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>

View File

@ -0,0 +1,23 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.bunny</groupId>
<artifactId>module</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>module-task</artifactId>
<packaging>jar</packaging>
<name>module-task</name>
<url>https://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
</dependencies>
</project>

View File

@ -1,4 +1,4 @@
package cn.bunny.service.task;
package cn.bunny.module.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;

View File

@ -17,6 +17,7 @@
<module>module-mail</module>
<module>module-rabbitMQ</module>
<module>module-websocket</module>
<module>module-task</module>
</modules>
<properties>

View File

@ -35,12 +35,6 @@
<artifactId>module-minio</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- service-utils -->
<dependency>
<groupId>cn.bunny</groupId>
<artifactId>service-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>

View File

@ -7,11 +7,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@ComponentScan(basePackages = {"cn.bunny"})
@MapperScan("cn.bunny.service.mapper")
@EnableScheduling// 定时任务
@EnableCaching// 开启缓存注解
@EnableTransactionManagement// 开启事务注解
@SpringBootApplication
@Slf4j
public class ServiceApplication {

View File

@ -1,59 +0,0 @@
package cn.bunny.service.controller;
import cn.bunny.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Tag(name = "后台登录管理")
@RestController
@RequestMapping("/")
public class BaseController {
@Autowired
private SessionRegistry sessionRegistry;
@GetMapping()
public String index() {
return "欢迎访问";
}
@Operation(summary = "Security上下文对象", description = "Security上下文对象")
@GetMapping("/test/getSecurityHolder")
public Result<Object> getSecurityHolder() {
SecurityContext context = SecurityContextHolder.getContext();
return Result.success(context);
}
@Operation(summary = "当前所有登录的用户", description = "当前所有登录的用户")
@GetMapping("/test/getAllUserLogin")
public Result<Object> getAllUserLogin() {
return Result.success(sessionRegistry.getAllPrincipals());
}
@Operation(summary = "剔除下线", description = "剔除下线")
@GetMapping("/test/killOut")
public Result<Object> killOut(String userId) {
List<Object> allPrincipals = sessionRegistry.getAllPrincipals();
for (Object allPrincipal : allPrincipals) {
// 获取当前所有已经登录session会话未失效的session
List<SessionInformation> allSessions = sessionRegistry.getAllSessions(allPrincipal, false);
User user = (User) allPrincipals;
// 如果用户名匹配将这个用户下线
if (user.getUsername().equals(userId)) {
allSessions.forEach(SessionInformation::expireNow);
}
}
return Result.success();
}
}

View File

@ -1,45 +1,18 @@
package cn.bunny.service.controller;
import cn.bunny.result.Result;
import cn.bunny.service.service.SysUserService;
import cn.bunny.vo.system.login.LoginVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* <p>
* 后台登录登出
* </p>
*/
@Tag(name = "后台登录管理")
@Tag(name = "访问首页内容")
@RestController
@RequestMapping("/admin/system/index")
@RequestMapping("/")
public class IndexController {
@Autowired
private SysUserService sysUserService;
@Operation(summary = "登录", description = "登录")
@PostMapping("login")
public Result<Login> login(@RequestBody LoginVo loginVo) {
Login login = sysUserService.login(loginVo);
return Result.success(login);
@Operation(summary = "访问首页", description = "访问首页")
@GetMapping("")
public String index() {
return "欢迎访问 Bunny Java Template";
}
@Operation(summary = "获取用户信息", description = "获取用户信息")
@GetMapping("info")
public Result<SysUserinfo> info(HttpServletRequest request) {
SysUserinfo userinfo = sysUserService.getUserinfo(request);
return Result.success(userinfo);
}
@Operation(summary = "退出", description = "退出")
@GetMapping("logout")
public Result<Map<String, Object>> logout() {
return Result.success();
}
}
}

View File

@ -0,0 +1,36 @@
package cn.bunny.service.controller;
import cn.bunny.dto.user.LoginDto;
import cn.bunny.result.Result;
import cn.bunny.service.service.UserService;
import cn.bunny.vo.system.login.LoginVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
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;
@Tag(name = "登录相关接口")
@RestController
@RequestMapping("/admin")
public class LoginController {
@Autowired
private UserService userService;
@Operation(summary = "登录接口", description = "后台用户登录接口")
@PostMapping("login")
public Result<LoginVo> login(@RequestBody LoginDto loginDto) {
LoginVo vo = userService.login(loginDto);
return Result.success(vo);
}
@Operation(summary = "发送邮箱验证码", description = "发送邮箱验证码")
@PostMapping("noAuth/sendEmail")
public Result<String> sendEmail(String email) {
userService.sendEmail(email);
return Result.success();
}
}

View File

@ -1,55 +0,0 @@
package cn.bunny.service.controller;
import cn.bunny.common.result.Result;
import cn.bunny.entity.email.EmailSend;
import cn.bunny.service.service.EmailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@Tag(name = "发送邮件")
@RequestMapping("/test/mail")
@Slf4j
public class MailController {
@Autowired
private EmailService emailService;
@Operation(summary = "发送简单邮件", description = "发送简单邮件")
@PostMapping("/send-text")
public Result<String> sendText(@RequestBody EmailSend emailSend) {
log.info("发送简单邮件");
emailService.sendSimpleEmail(emailSend);
return Result.success();
}
@Operation(summary = "发送带附件邮件", description = "发送带附件邮件")
@PostMapping("send-attachment")
public Result<String> sendAttachment(@RequestBody EmailSend emailSend) {
log.info("发送带附件邮件");
boolean isSuccess = emailService.sendAttachmentEmail(emailSend);
return isSuccess ? Result.success() : Result.error();
}
@Operation(summary = "发送富文本邮件", description = "发送富文本邮件")
@PostMapping("send-rich")
public Result<String> sendRich(@RequestBody EmailSend emailSend) {
log.info("发送富文本邮件");
boolean isSuccess = emailService.sendRich(emailSend);
return isSuccess ? Result.success() : Result.error();
}
@Operation(summary = "发送带抄送的邮件", description = "发送带抄送的邮件")
@PostMapping("send-cc")
public Result<String> sendCC(@RequestBody EmailSend emailSend) {
log.info("发送带抄送的邮件");
boolean isSuccess = emailService.sendCC(emailSend);
return isSuccess ? Result.success() : Result.error();
}
}

View File

@ -1,18 +0,0 @@
package cn.bunny.service.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 菜单表 前端控制器
* </p>
*
* @author Bunny
* @since 2024-05-06
*/
@RestController
@RequestMapping("/sysMenu")
public class SysMenuController {
}

View File

@ -0,0 +1,34 @@
package cn.bunny.service.mapper;
import cn.bunny.entity.system.admin.AdminPower;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Bunny
* @since 2024-05-18
*/
@Mapper
public interface AdminPowerMapper extends BaseMapper<AdminPower> {
/**
* 查询用户权限信息
*
* @param roleIdList 角色id 列表
* @return 用户对应的权限
*/
AdminPower[] selectByPowerWithRoleIdList(List<Long> roleIdList);
/**
* 查询用户权限
*
* @param userId 用户id
* @return 用户权限列表
*/
List<AdminPower> queryByUserIdWithPower(Long userId);
}

View File

@ -0,0 +1,26 @@
package cn.bunny.service.mapper;
import cn.bunny.entity.system.admin.AdminRole;
import cn.bunny.entity.system.admin.auth.AuthUserRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Bunny
* @since 2024-05-18
*/
@Mapper
public interface AdminRoleMapper extends BaseMapper<AdminRole> {
/**
* 查询用户所有的角色信息
*
* @param userId 用户id
* @return 用户对应的角色
*/
AuthUserRole[] selectByRoleWithUserId(Long userId);
}

View File

@ -0,0 +1,24 @@
package cn.bunny.service.mapper;
import cn.bunny.entity.system.email.EmailUsers;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Bunny
* @since 2024-05-14
*/
@Mapper
public interface EmailUsersMapper extends BaseMapper<EmailUsers> {
/**
* 彻底删除邮箱用户
*
* @param id 用户ID
*/
void thoroughDeleteById(Long id);
}

View File

@ -1,16 +0,0 @@
package cn.bunny.service.mapper;
import cn.bunny.entity.system.SysMenu;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 菜单表 Mapper 接口
* </p>
*
* @author Bunny
* @since 2024-05-06
*/
public interface SysMenuMapper extends BaseMapper<SysMenu> {
}

View File

@ -1,7 +0,0 @@
package cn.bunny.service.mapper;
import cn.bunny.entity.system.SysRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SysRoleMapper extends BaseMapper<SysRole> {
}

View File

@ -1,19 +0,0 @@
package cn.bunny.service.mapper;
import cn.bunny.entity.system.SysUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 用户表 Mapper 接口
* </p>
*
* @author bunny
* @since 2024-04-22
*/
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
}

View File

@ -0,0 +1,25 @@
package cn.bunny.service.mapper;
import cn.bunny.entity.system.user.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 用户信息 Mapper 接口
* </p>
*
* @author Bunny
* @since 2024-05-18
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
/**
* 前台用户登录接口
*
* @param username 邮箱/昵称
* @param password Image
* @return 登录参数
*/
User login(String username, String password);
}

View File

@ -1,12 +1,13 @@
package cn.bunny.service.security;
import cn.bunny.common.constant.CommonMessageConstant;
import cn.bunny.common.service.exception.BunnyException;
import cn.bunny.entity.system.SysRole;
import cn.bunny.entity.system.SysUser;
import cn.bunny.dto.user.LoginDto;
import cn.bunny.entity.system.admin.AdminRole;
import cn.bunny.entity.system.user.User;
import cn.bunny.security.custom.CustomUser;
import cn.bunny.service.mapper.SysRoleMapper;
import cn.bunny.service.mapper.SysUserMapper;
import cn.bunny.service.mapper.AdminRoleMapper;
import cn.bunny.service.mapper.UserMapper;
import cn.bunny.service.service.UserService;
import cn.bunny.vo.system.login.LoginVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@ -19,23 +20,35 @@ import java.util.List;
@Configuration
public class CustomUserDetailsService implements cn.bunny.security.service.CustomUserDetailsService {
@Autowired
private SysUserMapper sysUserMapper;
private UserMapper userMapper;
@Autowired
private SysRoleMapper sysRoleMapper;
private UserService userService;
@Autowired
private AdminRoleMapper adminRoleMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser sysUser = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
List<SysRole> sysRoleList = sysRoleMapper.selectList(null);
if (sysUser == null) {
throw new UsernameNotFoundException(CommonMessageConstant.USER_DOES_NOT_EXIST);
// 根据邮箱查询用户名
User user = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getEmail, username));
List<AdminRole> sysRoleList = adminRoleMapper.selectList(null);
// 都为空抛出异常用户不存在
if (user == null) {
throw new UsernameNotFoundException("");
}
if (sysUser.getStatus() == 0) {
throw new BunnyException(CommonMessageConstant.ACCOUNT_LOCKED);
}
List<String> roleAuthoritieList = sysRoleList.stream().map(SysRole::getRoleCode).toList();
return new CustomUser(sysUser, AuthorityUtils.createAuthorityList(roleAuthoritieList));
// 查询所有的角色
List<String> roleAuthoritieList = sysRoleList.stream().map(AdminRole::getRoleCode).toList();
return new CustomUser(user, AuthorityUtils.createAuthorityList(roleAuthoritieList));
}
}
/**
* 前台用户登录接口
*
* @param loginDto 登录参数
* @return 登录后结果返回
*/
@Override
public LoginVo login(LoginDto loginDto) {
return userService.login(loginDto);
}
}

View File

@ -1,37 +0,0 @@
package cn.bunny.service.service;
import cn.bunny.entity.email.EmailSend;
public interface EmailService {
/**
* 发送邮件-简单
*
* @param emailSend 邮件消息
*/
void sendSimpleEmail(EmailSend emailSend);
/**
* 发送带附件邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
boolean sendAttachmentEmail(EmailSend emailSend);
/**
* 发送富文本邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
boolean sendRich(EmailSend emailSend);
/**
* 发送带抄送的邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
boolean sendCC(EmailSend emailSend);
}

View File

@ -1,16 +0,0 @@
package cn.bunny.service.service;
import cn.bunny.entity.system.SysMenu;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 菜单表 服务类
* </p>
*
* @author Bunny
* @since 2024-05-06
*/
public interface SysMenuService extends IService<SysMenu> {
}

View File

@ -1,8 +0,0 @@
package cn.bunny.service.service;
import cn.bunny.entity.system.SysRole;
import com.baomidou.mybatisplus.extension.service.IService;
public interface SysRoleService extends IService<SysRole> {
}

View File

@ -1,43 +0,0 @@
package cn.bunny.service.service;
import cn.bunny.entity.system.Login;
import cn.bunny.entity.system.SysUser;
import cn.bunny.entity.system.SysUserinfo;
import cn.bunny.vo.system.LoginVo;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletRequest;
/**
* <p>
* 用户表 服务类
* </p>
*
* @author bunny
* @since 2024-04-22
*/
public interface SysUserService extends IService<SysUser> {
/**
* 登录
*
* @param vo 登录条件
* @return 返回token
*/
Login login(LoginVo vo);
/**
* 获取用户信息
*
* @param request 请求头
* @return 用户信息
*/
SysUserinfo getUserinfo(HttpServletRequest request);
/**
* 根据用户名查询用户信息
*
* @param username 用户名
* @return 用户信息
*/
SysUser getByUsername(String username);
}

View File

@ -0,0 +1,31 @@
package cn.bunny.service.service;
import cn.bunny.dto.user.LoginDto;
import cn.bunny.entity.system.user.User;
import cn.bunny.vo.system.login.LoginVo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户信息 服务类
* </p>
*
* @author Bunny
* @since 2024-05-18
*/
public interface UserService extends IService<User> {
/**
* 前台用户登录接口
*
* @param loginDto 登录参数
* @return 登录后结果返回
*/
LoginVo login(LoginDto loginDto);
/**
* 发送邮箱验证码
*
* @param email 邮箱
*/
void sendEmail(String email);
}

View File

@ -1,98 +0,0 @@
package cn.bunny.service.service.impl;
import cn.bunny.entity.email.EmailSend;
import cn.bunny.entity.email.EmailSendInit;
import cn.bunny.module.mail.utils.MailSenderUtil;
import cn.bunny.service.service.EmailService;
import jakarta.mail.MessagingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {
/**
* 发送邮件-简单
*
* @param emailSend 邮件消息
*/
@Override
public void sendSimpleEmail(EmailSend emailSend) {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderUtil mailSenderUtil = new MailSenderUtil(emailSendInit);
mailSenderUtil.sendSimpleEmail(emailSend);
}
/**
* 发送带附件邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
@Override
public boolean sendAttachmentEmail(EmailSend emailSend) {
try {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderUtil mailSenderUtil = new MailSenderUtil(emailSendInit);
mailSenderUtil.sendEmail(emailSend);
return true;
} catch (MessagingException e) {
return false;
}
}
/**
* 发送富文本邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
@Override
public boolean sendRich(EmailSend emailSend) {
try {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderUtil mailSenderUtil = new MailSenderUtil(emailSendInit);
mailSenderUtil.sendRichText(emailSend, true);
return true;
} catch (MessagingException e) {
return false;
}
}
/**
* 发送带抄送的邮件
*
* @param emailSend 邮件消息
*/
@Override
public boolean sendCC(EmailSend emailSend) {
try {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderUtil mailSenderUtil = new MailSenderUtil(emailSendInit);
mailSenderUtil.sendCC(emailSend, true);
return true;
} catch (MessagingException e) {
return false;
}
}
}

View File

@ -1,20 +0,0 @@
package cn.bunny.service.service.impl;
import cn.bunny.entity.system.SysMenu;
import cn.bunny.service.mapper.SysMenuMapper;
import cn.bunny.service.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 菜单表 服务实现类
* </p>
*
* @author Bunny
* @since 2024-05-06
*/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
}

View File

@ -1,11 +0,0 @@
package cn.bunny.service.service.impl;
import cn.bunny.entity.system.SysRole;
import cn.bunny.service.mapper.SysRoleMapper;
import cn.bunny.service.service.SysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
}

View File

@ -1,91 +0,0 @@
package cn.bunny.service.service.impl;
import cn.bunny.common.constant.CommonMessageConstant;
import cn.bunny.common.service.exception.BunnyException;
import cn.bunny.common.service.utils.JwtHelper;
import cn.bunny.entity.system.Login;
import cn.bunny.entity.system.SysUser;
import cn.bunny.entity.system.SysUserinfo;
import cn.bunny.service.mapper.SysUserMapper;
import cn.bunny.service.service.SysUserService;
import cn.bunny.vo.system.LoginVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
/**
* <p>
* 用户表 服务实现类
* </p>
*
* @author bunny
* @since 2024-04-22
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 登录
*
* @param vo 登录条件
* @return 返回token
*/
@Override
public Login login(LoginVo vo) {
String username = vo.getUsername();
String password = vo.getPassword();
// 查询用户信息
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysUser::getUsername, username);
SysUser sysUser = getOne(wrapper);
// 用户是否存在
if (sysUser == null) {
throw new BunnyException(CommonMessageConstant.ACCOUNT_NOT_FOUND);
}
// 判断是否被禁用
if (sysUser.getStatus() == 0) {
throw new BunnyException(CommonMessageConstant.ACCOUNT_LOCKED);
}
// 判断密码
String md5DigestAsHexPassword = DigestUtils.md5DigestAsHex(password.getBytes());
if (!md5DigestAsHexPassword.equals(sysUser.getPassword())) {
throw new BunnyException(CommonMessageConstant.PASSWORD_ERROR);
}
// 添加token
String token = JwtHelper.createToken(sysUser.getId(), sysUser.getUsername());
return Login.builder().token(token).build();
}
/**
* 获取用户信息
*
* @param request 请求头
* @return 用户信息
*/
@Override
public SysUserinfo getUserinfo(HttpServletRequest request) {
redisTemplate.opsForValue().set("test", "测试");
return null;
}
/**
* 根据用户名查询用户信息
*
* @param username 用户名
* @return 用户信息
*/
@Override
public SysUser getByUsername(String username) {
return getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
}
}

View File

@ -0,0 +1,122 @@
package cn.bunny.service.service.impl;
import cn.bunny.common.service.utils.EmptyUtil;
import cn.bunny.common.service.utils.JwtHelper;
import cn.bunny.dto.user.LoginDto;
import cn.bunny.entity.system.admin.AdminPower;
import cn.bunny.entity.system.admin.auth.AuthUserRole;
import cn.bunny.entity.system.email.EmailSend;
import cn.bunny.entity.system.email.EmailSendInit;
import cn.bunny.entity.system.email.EmailUsers;
import cn.bunny.entity.system.user.User;
import cn.bunny.module.mail.utils.MailSenderUtil;
import cn.bunny.result.constant.ExceptionConstant;
import cn.bunny.result.constant.MailMessageConstant;
import cn.bunny.result.constant.RedisUserConstant;
import cn.bunny.service.mapper.AdminPowerMapper;
import cn.bunny.service.mapper.AdminRoleMapper;
import cn.bunny.service.mapper.EmailUsersMapper;
import cn.bunny.service.mapper.UserMapper;
import cn.bunny.service.service.UserService;
import cn.bunny.vo.system.login.LoginVo;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* <p>
* 用户信息 服务实现类
* </p>
*
* @author Bunny
* @since 2024-05-18
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private AdminRoleMapper roleMapper;
@Autowired
private AdminPowerMapper powerMapper;
@Autowired
private EmailUsersMapper emailUsersMapper;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 前台用户登录接口
*
* @param loginDto 登录参数
* @return 登录后结果返回
*/
@Override
public LoginVo login(LoginDto loginDto) {
// 判断用户和密码是否为空
String username = loginDto.getUsername();
EmptyUtil.isEmpty(username, ExceptionConstant.USERNAME_IS_EMPTY_Exception);
// 密码不能为空
EmptyUtil.isEmpty(loginDto.getPassword(), ExceptionConstant.PASSWORD_NOT_EMPTY_Exception);
String password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
// 查询数据库用户对应的角色权限
User user = baseMapper.login(username, password);
Long userId = user.getId();
// 查询用户所有的角色信息
AuthUserRole[] roleList = roleMapper.selectByRoleWithUserId(userId);
List<String> roleCodeList = Arrays.stream(roleList).map(AuthUserRole::getRoleCode).toList();
List<Long> roleIdList = Arrays.stream(roleList).map(AuthUserRole::getRoleId).toList();
// 查询用户权限信息
AdminPower[] adminPowerList = powerMapper.selectByPowerWithRoleIdList(roleIdList);
List<String> powerCodeList = Arrays.stream(adminPowerList).map(AdminPower::getPowerCode).toList();
// 设置返回类型
LoginVo loginVo = new LoginVo();
BeanUtils.copyProperties(user, loginVo);
String token = JwtHelper.createToken(loginVo.getId(), loginVo.getEmail(), 7);
loginVo.setToken(token);
loginVo.setRoleList(roleCodeList);
loginVo.setPowerList(powerCodeList);
return loginVo;
}
/**
* 发送邮箱验证码
*
* @param email 邮箱
*/
@Override
public void sendEmail(String email) {
// 从数据库中获取发送邮箱参数
EmailUsers emailUsers = emailUsersMapper.selectOne(Wrappers.<EmailUsers>lambdaQuery().eq(EmailUsers::getIsDefault, 1));
EmailSendInit emailSendInit = new EmailSendInit();
// 判断发送邮箱邮件是否为空
EmptyUtil.isEmpty(emailUsers, MailMessageConstant.EMAIL_CONFIG_NOT_FOUND);
BeanUtils.copyProperties(emailUsers, emailSendInit);
emailSendInit.setUsername(emailUsers.getEmail());
// 生成验证码
MailSenderUtil mailSenderUtil = new MailSenderUtil(emailSendInit);
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 2);
// 生成验证码和可以
String code = captcha.getCode();
// 发送验证码
EmailSend emailSend = new EmailSend();
emailSend.setSubject("邮箱验证码");
emailSend.setMessage(code);
emailSend.setSendTo(email);
emailSend.setIsRichText(false);
mailSenderUtil.sendSimpleEmail(emailSend);
// 将验证码保存到Redis中并设置15分钟过期
redisTemplate.opsForValue().set(RedisUserConstant.ADMIN_EMAIL_CODE_PREFIX + email, code, 15, TimeUnit.MINUTES);
}
}

View File

@ -33,6 +33,9 @@ spring:
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
global-config:
db-config:
logic-delete-field: isDelete
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bunny.service.mapper.AdminPowerMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.bunny.entity.system.admin.AdminPower">
<id column="id" property="id"/>
<result column="power_name" property="powerName"/>
<result column="power_code" property="powerCode"/>
<result column="description" property="description"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="update_user" property="updateUser"/>
<result column="is_delete" property="isDelete"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, power_name, power_code, description, create_time, update_time, update_user, is_delete
</sql>
<!-- 查询用户权限信息 -->
<select id="selectByPowerWithRoleIdList">
SELECT *
FROM admin_power
WHERE id IN (SELECT arp.power_id
FROM admin_role_power arp
WHERE arp.role_id IN <foreach collection="roleIdList" item="roleId" open="(" close=")" separator=",">
#{roleId}
</foreach> )
</select>
<!-- 查询用户权限 -->
<select id="queryByUserIdWithPower" resultType="cn.bunny.entity.system.admin.AdminPower">
SELECT ap.*
FROM admin_user_role aur
INNER JOIN admin_role_power arp ON aur.role_id = arp.role_id
INNER JOIN admin_power ap ON ap.id = arp.power_id
WHERE aur.user_id = #{userId}
</select>
</mapper>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bunny.service.mapper.AdminRoleMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.bunny.entity.system.admin.AdminRole">
<id column="id" property="id"/>
<result column="role_name" property="roleName"/>
<result column="description" property="description"/>
<result column="role_code" property="roleCode"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="update_user" property="updateUser"/>
<result column="is_deleted" property="isDeleted"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, role_name, description, role_code, create_time, update_time, update_user, is_deleted
</sql>
<!-- 查询用户所有的角色信息 -->
<select id="selectByRoleWithUserId">
SELECT ar.id roleId, ar.role_code, ar.description roleDescription, aur.user_id
FROM admin_user_role aur
LEFT JOIN admin_role ar ON ar.id = aur.role_id
WHERE aur.user_id = #{userId}
</select>
</mapper>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bunny.service.mapper.EmailUsersMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.bunny.entity.system.email.EmailUsers">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="password" property="password"/>
<result column="host" property="host"/>
<result column="port" property="port"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="update_user" property="updateUser"/>
<result column="is_delete" property="isDeleted"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, email, password, host, port, create_time, update_time, update_user, is_delete
</sql>
<!-- 彻底删除邮箱用户 -->
<delete id="thoroughDeleteById">
delete
from email_users
where id = #{id}
</delete>
</mapper>

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bunny.service.mapper.SysMenuMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.bunny.entity.system.SysMenu">
<id column="id" property="id"/>
<result column="parent_id" property="parentId"/>
<result column="name" property="name"/>
<result column="type" property="type"/>
<result column="path" property="path"/>
<result column="component" property="component"/>
<result column="perms" property="perms"/>
<result column="icon" property="icon"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="is_deleted" property="isDeleted"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, parent_id, name, type, path, component, perms, icon, sort_value, status, create_time, update_time, is_deleted
</sql>
</mapper>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.bunny.service.mapper.SysRoleMapper">
</mapper>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bunny.service.mapper.SysUserMapper">
</mapper>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bunny.service.mapper.UserMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.bunny.entity.system.user.User">
<id column="id" property="id"/>
<result column="nick_name" property="nickName"/>
<result column="email" property="email"/>
<result column="password" property="password"/>
<result column="avatar" property="avatar"/>
<result column="sex" property="sex"/>
<result column="person_description" property="personDescription"/>
<result column="join_time" property="joinTime"/>
<result column="last_login_time" property="lastLoginTime"/>
<result column="last_login_ip" property="lastLoginIp"/>
<result column="last_login_ip_address" property="lastLoginIpAddress"/>
<result column="total_integral" property="totalIntegral"/>
<result column="current_integral" property="currentIntegral"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="update_user" property="updateUser"/>
<result column="is_deleted" property="isDeleted"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, nick_name, email, password, avatar, sex, person_description, join_time, last_login_time, last_login_ip, last_login_ip_address, total_integral, current_integral, status, create_time, update_time, update_user, is_deleted
</sql>
<!-- 后台登录用户 -->
<select id="login" resultType="cn.bunny.entity.system.user.User">
select *
from user
where (email = #{username} and password = #{password})
or (nick_name = #{username} and password = #{password})
</select>
</mapper>