From 8fae01c4a2a5483fa9bdfd2cb05309527f6c5f08 Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Thu, 26 Sep 2024 16:58:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=96=B0=E5=A2=9E):=20UserFactory?= =?UTF-8?q?=E6=9C=AA=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bunny/common/generator/AdminGenerator.kt | 2 +- .../service/config/RedisConfiguration.kt | 2 + .../service/config/WebMvcConfiguration.kt | 40 -------- .../exception/GlobalExceptionHandler.kt | 9 +- .../cn/bunny/common/service/utils/IpUtil.kt | 66 ------------- .../service/utils/email/MailSenderUtil.kt | 14 ++- .../bunny/common/service/utils/ip/IpEntity.kt | 21 ++++ .../bunny/common/service/utils/ip/IpUtil.kt | 98 +++++++++++++++++++ .../dao/dto/{user => system}/LoginDto.kt | 7 +- .../kotlin/cn/bunny/dao/entity/BaseEntity.kt | 4 +- .../dao/entity/{user => system}/AdminUser.kt | 2 +- .../entity/{email => system}/EmailTemplate.kt | 15 +-- .../entity/{email => system}/EmailUsers.kt | 20 ++-- .../cn/bunny/dao/entity/system/MenuIcon.java | 52 ++++++++++ .../cn/bunny/dao/entity/system/Router.java | 71 ++++++++++++++ .../cn/bunny/dao/pojo/email/EmailSend.kt | 4 +- .../dao/pojo/enums/EmailTemplateTypes.kt | 8 ++ .../{OperationType.kt => OperationTypes.kt} | 2 +- .../bunny/dao/pojo/result/ResultCodeEnum.kt | 7 +- .../kotlin/cn/bunny/dao/vo/user/LoginVo.kt | 30 ++---- .../controller/EmailTemplateController.java | 18 ++++ .../controller/EmailUsersController.java | 18 ++++ .../services/controller/I18nController.java | 2 +- .../controller/I18nTypeController.java | 2 +- .../services/controller/IndexController.kt | 1 + .../controller/MenuIconController.java | 20 ++++ .../services/controller/RouterController.java | 20 ++++ .../services/controller/UserController.kt | 20 +++- .../cn/bunny/services/factory/EmailFactory.kt | 58 +++++++++++ .../cn/bunny/services/factory/UserFactory.kt | 57 +++++++++++ .../services/mapper/EmailTemplateMapper.java | 18 ++++ .../services/mapper/EmailUsersMapper.java | 18 ++++ .../bunny/services/mapper/MenuIconMapper.java | 18 ++++ .../bunny/services/mapper/RouterMapper.java | 18 ++++ .../cn/bunny/services/mapper/UserMapper.java | 2 +- .../security/config/WebSecurityConfig.kt | 10 +- .../services/security/custom/CustomUser.kt | 2 +- .../filter/TokenAuthenticationFilter.kt | 5 +- .../filter/TokenLoginFilterService.kt | 57 +++++------ .../CustomAuthorizationManagerService.kt | 6 -- .../service/CustomUserDetailsService.kt | 2 +- .../CustomAuthorizationManagerServiceImpl.kt | 54 +++++----- .../impl/CustomUserDetailsServiceImpl.kt | 50 +++++++--- .../service/EmailTemplateService.java | 16 +++ .../services/service/EmailUsersService.java | 16 +++ .../services/service/MenuIconService.java | 16 +++ .../bunny/services/service/RouterService.java | 16 +++ .../bunny/services/service/UserService.java | 9 +- .../impl/EmailTemplateServiceImpl.java | 20 ++++ .../service/impl/EmailUsersServiceImpl.kt | 19 ++++ .../service/impl/MenuIconServiceImpl.java | 20 ++++ .../service/impl/RouterServiceImpl.java | 20 ++++ .../services/service/impl/UserServiceImpl.kt | 59 +++++++++-- .../src/main/resources/application-dev.yml | 4 +- .../src/main/resources/application-prod.yml | 10 +- services/src/main/resources/application.yml | 2 +- .../resources/mapper/EmailTemplateMapper.xml | 25 +++++ .../resources/mapper/EmailUsersMapper.xml | 27 +++++ .../main/resources/mapper/MenuIconMapper.xml | 21 ++++ .../main/resources/mapper/RouterMapper.xml | 27 +++++ .../src/main/resources/mapper/UserMapper.xml | 2 +- 61 files changed, 1003 insertions(+), 276 deletions(-) delete mode 100644 common/common-service/src/main/kotlin/cn/bunny/common/service/config/WebMvcConfiguration.kt delete mode 100644 common/common-service/src/main/kotlin/cn/bunny/common/service/utils/IpUtil.kt create mode 100644 common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpEntity.kt create mode 100644 common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpUtil.kt rename dao/src/main/kotlin/cn/bunny/dao/dto/{user => system}/LoginDto.kt (80%) rename dao/src/main/kotlin/cn/bunny/dao/entity/{user => system}/AdminUser.kt (97%) rename dao/src/main/kotlin/cn/bunny/dao/entity/{email => system}/EmailTemplate.kt (63%) rename dao/src/main/kotlin/cn/bunny/dao/entity/{email => system}/EmailUsers.kt (74%) create mode 100644 dao/src/main/kotlin/cn/bunny/dao/entity/system/MenuIcon.java create mode 100644 dao/src/main/kotlin/cn/bunny/dao/entity/system/Router.java create mode 100644 dao/src/main/kotlin/cn/bunny/dao/pojo/enums/EmailTemplateTypes.kt rename dao/src/main/kotlin/cn/bunny/dao/pojo/enums/{OperationType.kt => OperationTypes.kt} (75%) create mode 100644 services/src/main/kotlin/cn/bunny/services/controller/EmailTemplateController.java create mode 100644 services/src/main/kotlin/cn/bunny/services/controller/EmailUsersController.java create mode 100644 services/src/main/kotlin/cn/bunny/services/controller/MenuIconController.java create mode 100644 services/src/main/kotlin/cn/bunny/services/controller/RouterController.java create mode 100644 services/src/main/kotlin/cn/bunny/services/factory/EmailFactory.kt create mode 100644 services/src/main/kotlin/cn/bunny/services/factory/UserFactory.kt create mode 100644 services/src/main/kotlin/cn/bunny/services/mapper/EmailTemplateMapper.java create mode 100644 services/src/main/kotlin/cn/bunny/services/mapper/EmailUsersMapper.java create mode 100644 services/src/main/kotlin/cn/bunny/services/mapper/MenuIconMapper.java create mode 100644 services/src/main/kotlin/cn/bunny/services/mapper/RouterMapper.java delete mode 100644 services/src/main/kotlin/cn/bunny/services/security/service/CustomAuthorizationManagerService.kt create mode 100644 services/src/main/kotlin/cn/bunny/services/service/EmailTemplateService.java create mode 100644 services/src/main/kotlin/cn/bunny/services/service/EmailUsersService.java create mode 100644 services/src/main/kotlin/cn/bunny/services/service/MenuIconService.java create mode 100644 services/src/main/kotlin/cn/bunny/services/service/RouterService.java create mode 100644 services/src/main/kotlin/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java create mode 100644 services/src/main/kotlin/cn/bunny/services/service/impl/EmailUsersServiceImpl.kt create mode 100644 services/src/main/kotlin/cn/bunny/services/service/impl/MenuIconServiceImpl.java create mode 100644 services/src/main/kotlin/cn/bunny/services/service/impl/RouterServiceImpl.java create mode 100644 services/src/main/resources/mapper/EmailTemplateMapper.xml create mode 100644 services/src/main/resources/mapper/EmailUsersMapper.xml create mode 100644 services/src/main/resources/mapper/MenuIconMapper.xml create mode 100644 services/src/main/resources/mapper/RouterMapper.xml diff --git a/common/common-generator/src/main/kotlin/cn/bunny/common/generator/AdminGenerator.kt b/common/common-generator/src/main/kotlin/cn/bunny/common/generator/AdminGenerator.kt index 1db25d8..6a62561 100644 --- a/common/common-generator/src/main/kotlin/cn/bunny/common/generator/AdminGenerator.kt +++ b/common/common-generator/src/main/kotlin/cn/bunny/common/generator/AdminGenerator.kt @@ -27,7 +27,7 @@ class AdminGenerator { @JvmStatic fun main(args: Array) { - generation("sys_user") + generation("sys_email_template") } /** diff --git a/common/common-service/src/main/kotlin/cn/bunny/common/service/config/RedisConfiguration.kt b/common/common-service/src/main/kotlin/cn/bunny/common/service/config/RedisConfiguration.kt index 93e3996..2141d18 100644 --- a/common/common-service/src/main/kotlin/cn/bunny/common/service/config/RedisConfiguration.kt +++ b/common/common-service/src/main/kotlin/cn/bunny/common/service/config/RedisConfiguration.kt @@ -50,6 +50,8 @@ class RedisConfiguration { redisTemplate.hashKeySerializer = StringRedisSerializer() redisTemplate.hashValueSerializer = GenericJackson2JsonRedisSerializer() + // 开启Redis事务 + redisTemplate.setEnableTransactionSupport(true) return redisTemplate } diff --git a/common/common-service/src/main/kotlin/cn/bunny/common/service/config/WebMvcConfiguration.kt b/common/common-service/src/main/kotlin/cn/bunny/common/service/config/WebMvcConfiguration.kt deleted file mode 100644 index 33b3808..0000000 --- a/common/common-service/src/main/kotlin/cn/bunny/common/service/config/WebMvcConfiguration.kt +++ /dev/null @@ -1,40 +0,0 @@ -package cn.bunny.common.service.config - -import cn.bunny.common.service.interceptor.UserTokenInterceptor -import lombok.extern.slf4j.Slf4j -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.annotation.Configuration -import org.springframework.web.servlet.config.annotation.CorsRegistry -import org.springframework.web.servlet.config.annotation.InterceptorRegistry -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer - -@Configuration -@Slf4j -open class WebMvcConfiguration : WebMvcConfigurer { - @Autowired - private val userTokenInterceptor: UserTokenInterceptor? = null - - /** - * 跨域配置 - * - * @param registry 跨域注册表 - */ - override fun addCorsMappings(registry: CorsRegistry) { - registry.addMapping("/**") // 是否发送Cookies - .allowCredentials(true) // 放行哪些原始域 - .allowedOriginPatterns("*").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*") - .exposedHeaders("*") - } - - override fun addInterceptors(registry: InterceptorRegistry) { - // TODO Spring Security 和这个拦截器任选一个 - val excludeList = arrayOf( - "/", "/test/**", "/*.html", "/*/*/noAuth/**", "/*/noAuth/**", "/favicon.ico", - "/swagger-resources/**", "/swagger-ui.html/**", "/admin/login", "/v3/**", "/api/**" - ) - registry.addInterceptor(userTokenInterceptor!!).excludePathPatterns(*excludeList) - - // TODO 如果想使用普通JWT可以使用这个,不使用 SpringSecurity6 - // registry.addInterceptor(userTokenInterceptor).addPathPatterns("/api/**").excludePathPatterns(excludeList); - } -} diff --git a/common/common-service/src/main/kotlin/cn/bunny/common/service/exception/GlobalExceptionHandler.kt b/common/common-service/src/main/kotlin/cn/bunny/common/service/exception/GlobalExceptionHandler.kt index 2bd5277..258c903 100644 --- a/common/common-service/src/main/kotlin/cn/bunny/common/service/exception/GlobalExceptionHandler.kt +++ b/common/common-service/src/main/kotlin/cn/bunny/common/service/exception/GlobalExceptionHandler.kt @@ -36,7 +36,7 @@ class GlobalExceptionHandler { fun exceptionHandler(exception: RuntimeException): Result { logger.error("GlobalExceptionHandler===>运行时异常信息:{}", exception.message) exception.printStackTrace() - return Result.error(null, 500, "出错了啦") + return Result.error(null, 500, "出错了") } // 捕获系统异常 @@ -47,12 +47,19 @@ class GlobalExceptionHandler { // 错误消息 val message = exception.message ?: "" + // 匹配到内容 val patternString = "Request method '(\\w+)' is not supported" val matcher = Pattern.compile(patternString).matcher(message) + // 请求API不存在 + val noStaticResource = "No static resource (.*)\\." + val noStaticResourceMatcher = Pattern.compile(noStaticResource).matcher(message) + if (noStaticResourceMatcher.find()) return Result.error(null, 500, "请求API不存在 " + noStaticResourceMatcher.group(1)) + return when { matcher.find() -> Result.error(null, 500, "请求方法错误,不是 " + matcher.group(1)) + noStaticResourceMatcher.find() -> return Result.error(null, 500, "请求API不存在 " + noStaticResourceMatcher.group(1)) else -> Result.error(null, 500, "系统异常") } } diff --git a/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/IpUtil.kt b/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/IpUtil.kt deleted file mode 100644 index 21c797c..0000000 --- a/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/IpUtil.kt +++ /dev/null @@ -1,66 +0,0 @@ -package cn.bunny.common.service.utils - -import cn.bunny.common.service.exception.BunnyException -import jakarta.annotation.PostConstruct -import lombok.extern.slf4j.Slf4j -import org.apache.logging.log4j.LogManager -import org.lionsoul.ip2region.xdb.Searcher -import org.springframework.core.io.ClassPathResource -import org.springframework.util.FileCopyUtils -import java.util.regex.Pattern - -@Slf4j -class IpUtil { - - companion object { - private val logger = LogManager.getLogger(IpUtil::class.java) - private var searcher: Searcher? = null - - /** - * 判断是否为合法 IP - */ - private fun checkIp(ipAddress: String): Boolean { - val ip = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}" - val pattern = Pattern.compile(ip) - val matcher = pattern.matcher(ipAddress) - - return matcher.matches() - } - - /** - * 在服务启动时,将 ip2region 加载到内存中 - */ - @PostConstruct - private fun initIp2Region() { - try { - val inputStream = ClassPathResource("/ipdb/ip2region.xdb").inputStream - val bytes = FileCopyUtils.copyToByteArray(inputStream) - searcher = Searcher.newWithBuffer(bytes) - } catch (exception: Exception) { - logger.error(exception.message) - } - } - - /** - * 获取 ip 所属地址 - * - * @param checkIp ip - */ - fun getIpRegion(checkIp: String): String { - val ip = if (checkIp == "0:0:0:0:0:0:0:1") "127.0.0.1" else checkIp - if (!checkIp(ip)) throw BunnyException("非法的IP地址") - - val searchIpInfo = searcher?.search(ip) - return searchIpInfo?.let { it -> - val splitIpInfo = it.split("\\|".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - if (splitIpInfo.isNotEmpty()) { - when { - splitIpInfo[0] == "中国" -> splitIpInfo[2] // 国内属地返回省份 - splitIpInfo[0] == "0" && splitIpInfo[4] == "内网IP" -> splitIpInfo[4] // 内网 IP - else -> splitIpInfo[0] // 国外属地返回国家 - } - } else "" - } ?: "" - } - } -} diff --git a/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/email/MailSenderUtil.kt b/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/email/MailSenderUtil.kt index 06e1077..07fb41c 100644 --- a/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/email/MailSenderUtil.kt +++ b/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/email/MailSenderUtil.kt @@ -44,17 +44,23 @@ class MailSenderUtil(emailSendInit: EmailSendInit) { // 设置发送人 helper.setFrom(username!!) + // 设置邮件接受者 helper.setTo(emailSend.sendTo!!) + // 设置邮件主题 helper.setSubject(emailSend.subject!!) + // 设置发送消息 为富文本 - helper.setText(emailSend.message!!, emailSend.isRichText!!) + helper.setText(emailSend.message!!, emailSend.isRichText) + // 设置抄送人 - helper.setCc(emailSend.ccParam!!.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) + val split: List = emailSend.ccParam?.split(",") ?: emptyList() + helper.setCc(split.toTypedArray()) + // 邮件添加附件 - val files = emailSend.file - for (file in files!!) { + val files = emailSend.files + if (files !== null) for (file in files) { helper.addAttachment(Objects.requireNonNull(file.originalFilename), file) } diff --git a/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpEntity.kt b/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpEntity.kt new file mode 100644 index 0000000..82ccc56 --- /dev/null +++ b/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpEntity.kt @@ -0,0 +1,21 @@ +package cn.bunny.common.service.utils.ip + +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty +import lombok.AllArgsConstructor +import lombok.Builder +import lombok.Data +import lombok.NoArgsConstructor + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@ApiModel(value = "IpEntity对象", description = "用户IP相关信息") +class IpEntity { + @ApiModelProperty("原始地址") + var remoteAddr: String? = null + + @ApiModelProperty("IP归属地") + var ipRegion: String? = null +} diff --git a/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpUtil.kt b/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpUtil.kt new file mode 100644 index 0000000..45d6994 --- /dev/null +++ b/common/common-service/src/main/kotlin/cn/bunny/common/service/utils/ip/IpUtil.kt @@ -0,0 +1,98 @@ +package cn.bunny.common.service.utils.ip + +import jakarta.annotation.PostConstruct +import lombok.extern.slf4j.Slf4j +import org.apache.logging.log4j.LogManager +import org.lionsoul.ip2region.xdb.Searcher +import org.springframework.core.io.ClassPathResource +import org.springframework.util.FileCopyUtils +import org.springframework.web.context.request.RequestContextHolder +import org.springframework.web.context.request.ServletRequestAttributes +import java.util.regex.Pattern + +@Slf4j +class IpUtil { + + companion object { + private val logger = LogManager.getLogger(IpUtil::class.java) + private var searcher: Searcher? = null + + /** + * 判断是否为合法 IP + */ + fun checkIp(ipAddress: String): Boolean { + val ip = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}" + val pattern = Pattern.compile(ip) + val matcher = pattern.matcher(ipAddress) + + return matcher.matches() + } + + /** + * 在服务启动时,将 ip2region 加载到内存中 + */ + @PostConstruct + fun initIp2Region() { + try { + val inputStream = ClassPathResource("/ipdb/ip2region.xdb").inputStream + val bytes = FileCopyUtils.copyToByteArray(inputStream) + searcher = Searcher.newWithBuffer(bytes) + } catch (exception: Exception) { + logger.error(exception.message) + } + } + + /** + * 获取 ip 所属地址 + * + * @param ip ip + */ + private fun getIpRegion(ip: String): String { + var checkIp = ip + if (checkIp == "0:0:0:0:0:0:0:1") checkIp = "127.0.0.1" + val isIp = checkIp(checkIp) + if (isIp) { + initIp2Region() + try { + // searchIpInfo 的数据格式: 国家|区域|省份|城市|ISP + val searchIpInfo: String = searcher!!.search(checkIp) + val splitIpInfo = searchIpInfo.split("\\|".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + if (splitIpInfo.isNotEmpty()) { + return if ("中国" == splitIpInfo[0]) { + // 国内属地返回省份 + splitIpInfo[2] + } else if ("0" == splitIpInfo[0]) { + if ("内网IP" == splitIpInfo[4]) splitIpInfo[4] else "" + } else splitIpInfo[0] + } + } catch (exception: java.lang.Exception) { + logger.error("获取 ip 所属地址消息:{}", exception.message) + logger.error("获取 ip 所属地址:{}", exception.stackTrace as Any) + } + return "" + } else { + throw IllegalArgumentException("非法的IP地址") + } + } + + /** + * * 获取当前用户登录IP地址 + * + * @return IP地址 + */ + fun getCurrentUserIpAddress(): IpEntity { + // 获取用户IP地址 + val requestAttributes = RequestContextHolder.getRequestAttributes() as ServletRequestAttributes + var remoteAddr = requestAttributes.request.remoteAddr + val ipRegion = getIpRegion(remoteAddr) + + // 设置返回对象 + val ipEntity = IpEntity() + if (remoteAddr == "0:0:0:0:0:0:0:1") remoteAddr = "127.0.0.1" + ipEntity.remoteAddr = remoteAddr + ipEntity.ipRegion = ipRegion + + return ipEntity + } + } +} diff --git a/dao/src/main/kotlin/cn/bunny/dao/dto/user/LoginDto.kt b/dao/src/main/kotlin/cn/bunny/dao/dto/system/LoginDto.kt similarity index 80% rename from dao/src/main/kotlin/cn/bunny/dao/dto/user/LoginDto.kt rename to dao/src/main/kotlin/cn/bunny/dao/dto/system/LoginDto.kt index 313582c..decbec3 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/dto/user/LoginDto.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/dto/system/LoginDto.kt @@ -1,4 +1,4 @@ -package cn.bunny.dao.dto.user +package cn.bunny.dao.dto.system import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.NotBlank @@ -6,11 +6,13 @@ import lombok.AllArgsConstructor import lombok.Builder import lombok.Data import lombok.NoArgsConstructor +import lombok.experimental.Accessors @Data @AllArgsConstructor @NoArgsConstructor @Builder +@Accessors(chain = true) @Schema(name = "LoginDto", title = "登录表单内容", description = "登录表单内容") class LoginDto { @Schema(name = "username", title = "用户名") @@ -21,4 +23,7 @@ class LoginDto { @Schema(name = "emailCode", title = "邮箱验证码") var emailCode: @NotBlank(message = "邮箱验证码不能为空") String? = null + + @Schema(name = "readMeDay", title = "记住我的天数") + var readMeDay: Long = 7 } diff --git a/dao/src/main/kotlin/cn/bunny/dao/entity/BaseEntity.kt b/dao/src/main/kotlin/cn/bunny/dao/entity/BaseEntity.kt index d65f110..4fc7332 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/entity/BaseEntity.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/entity/BaseEntity.kt @@ -4,13 +4,14 @@ import com.alibaba.fastjson2.annotation.JSONField import com.baomidou.mybatisplus.annotation.* import com.fasterxml.jackson.annotation.JsonFormat import com.fasterxml.jackson.databind.ser.std.ToStringSerializer -import io.swagger.annotations.ApiModelProperty import io.swagger.v3.oas.annotations.media.Schema import lombok.Data +import lombok.experimental.Accessors import java.io.Serializable import java.time.LocalDateTime @Data +@Accessors(chain = true) @Schema(name = "BaseEntity", title = "基础实体类型", description = "基础实体类型") open class BaseEntity : Serializable { @Schema(name = "id", title = "唯一标识") @@ -19,7 +20,6 @@ open class BaseEntity : Serializable { @JSONField(serializeUsing = ToStringSerializer::class) var id: Long? = null - @ApiModelProperty("创建时间") @Schema(name = "createTime", title = "创建时间") @TableField(fill = FieldFill.INSERT) var createTime: LocalDateTime? = null diff --git a/dao/src/main/kotlin/cn/bunny/dao/entity/user/AdminUser.kt b/dao/src/main/kotlin/cn/bunny/dao/entity/system/AdminUser.kt similarity index 97% rename from dao/src/main/kotlin/cn/bunny/dao/entity/user/AdminUser.kt rename to dao/src/main/kotlin/cn/bunny/dao/entity/system/AdminUser.kt index cdf5ec6..88f6575 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/entity/user/AdminUser.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/entity/system/AdminUser.kt @@ -1,4 +1,4 @@ -package cn.bunny.dao.entity.user +package cn.bunny.dao.entity.system import cn.bunny.dao.entity.BaseEntity import com.baomidou.mybatisplus.annotation.TableName diff --git a/dao/src/main/kotlin/cn/bunny/dao/entity/email/EmailTemplate.kt b/dao/src/main/kotlin/cn/bunny/dao/entity/system/EmailTemplate.kt similarity index 63% rename from dao/src/main/kotlin/cn/bunny/dao/entity/email/EmailTemplate.kt rename to dao/src/main/kotlin/cn/bunny/dao/entity/system/EmailTemplate.kt index ed75e66..9732f67 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/entity/email/EmailTemplate.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/entity/system/EmailTemplate.kt @@ -1,4 +1,4 @@ -package cn.bunny.dao.entity.email +package cn.bunny.dao.entity.system import cn.bunny.dao.entity.BaseEntity import com.baomidou.mybatisplus.annotation.TableName @@ -10,19 +10,19 @@ import lombok.experimental.Accessors /** * * - * + * 邮件模板表 * * * @author Bunny - * @since 2024-05-19 + * @since 2024-09-26 */ @Getter @Setter @Accessors(chain = true) -@TableName("email_template") -@Schema(name = "EmailTemplate", title = "邮件模板", description = "邮件模板") +@TableName("sys_email_template") +@Schema(name = "EmailTemplate对象", title = "邮件模板表", description = "邮件模板表") class EmailTemplate : BaseEntity() { - @Schema(name = "templateName", title = "模板名称") + @Schema(name = "email", title = "模板名称") var templateName: String? = null @Schema(name = "subject", title = "主题") @@ -33,4 +33,7 @@ class EmailTemplate : BaseEntity() { @Schema(name = "type", title = "邮件类型") var type: String? = null + + @Schema(name = "isDefault", title = "是否默认") + var isDefault: Boolean? = null } diff --git a/dao/src/main/kotlin/cn/bunny/dao/entity/email/EmailUsers.kt b/dao/src/main/kotlin/cn/bunny/dao/entity/system/EmailUsers.kt similarity index 74% rename from dao/src/main/kotlin/cn/bunny/dao/entity/email/EmailUsers.kt rename to dao/src/main/kotlin/cn/bunny/dao/entity/system/EmailUsers.kt index 73450c1..2fe368e 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/entity/email/EmailUsers.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/entity/system/EmailUsers.kt @@ -1,10 +1,9 @@ -package cn.bunny.dao.entity.email +package cn.bunny.dao.entity.system import cn.bunny.dao.entity.BaseEntity import com.baomidou.mybatisplus.annotation.TableName import io.swagger.v3.oas.annotations.media.Schema -import lombok.Getter -import lombok.Setter +import lombok.Data import lombok.experimental.Accessors /** @@ -14,17 +13,20 @@ import lombok.experimental.Accessors * * * @author Bunny - * @since 2024-05-17 + * @since 2024-09-26 */ -@Getter -@Setter +@Data @Accessors(chain = true) -@TableName("email_users") +@TableName("sys_email_users") @Schema(name = "EmailUsers对象", title = "邮箱发送表", description = "邮箱发送表") -class EmailUsers : BaseEntity() { +open class EmailUsers : BaseEntity() { + @Schema(name = "email", title = "邮箱") var email: String? = null + @Schema(name = "emailTemplate", title = "使用邮件模板") + var emailTemplate: Long? = null + @Schema(name = "password", title = "密码") var password: String? = null @@ -38,5 +40,5 @@ class EmailUsers : BaseEntity() { var smtpAgreement: String? = null @Schema(name = "isDefault", title = "是否为默认邮件") - var isDefault: Int? = null + var isDefault: Byte? = null } diff --git a/dao/src/main/kotlin/cn/bunny/dao/entity/system/MenuIcon.java b/dao/src/main/kotlin/cn/bunny/dao/entity/system/MenuIcon.java new file mode 100644 index 0000000..c1c49df --- /dev/null +++ b/dao/src/main/kotlin/cn/bunny/dao/entity/system/MenuIcon.java @@ -0,0 +1,52 @@ +package cn.bunny.dao.entity.system; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 系统菜单图标 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Getter +@Setter +@Accessors(chain = true) +@TableName("sys_menu_icon") +@ApiModel(value = "MenuIcon对象", description = "系统菜单图标") +public class MenuIcon implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("icon 名称") + private String iconName; + + @ApiModelProperty("创建用户") + private Long createUser; + + @ApiModelProperty("操作用户") + private Long updateUser; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + + @ApiModelProperty("是否删除") + private Byte isDeleted; +} diff --git a/dao/src/main/kotlin/cn/bunny/dao/entity/system/Router.java b/dao/src/main/kotlin/cn/bunny/dao/entity/system/Router.java new file mode 100644 index 0000000..abf2cae --- /dev/null +++ b/dao/src/main/kotlin/cn/bunny/dao/entity/system/Router.java @@ -0,0 +1,71 @@ +package cn.bunny.dao.entity.system; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * 系统菜单表 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Getter +@Setter +@Accessors(chain = true) +@TableName("sys_router") +@ApiModel(value = "Router对象", description = "系统菜单表") +public class Router implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty("在项目中路径") + private String routerPath; + + @ApiModelProperty("路由名称") + private String routeName; + + @ApiModelProperty("父级id") + private Long parentId; + + @ApiModelProperty("路由title") + private String title; + + @ApiModelProperty("图标") + private String icon; + + @ApiModelProperty("等级") + private Integer routerRank; + + @ApiModelProperty("是否显示") + private Boolean visible; + + @ApiModelProperty("创建用户") + private Long createUser; + + @ApiModelProperty("操作用户") + private Long updateUser; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + + @ApiModelProperty("是否删除") + private Byte isDeleted; +} diff --git a/dao/src/main/kotlin/cn/bunny/dao/pojo/email/EmailSend.kt b/dao/src/main/kotlin/cn/bunny/dao/pojo/email/EmailSend.kt index 54472a6..862be5b 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/pojo/email/EmailSend.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/pojo/email/EmailSend.kt @@ -24,7 +24,7 @@ class EmailSend { var subject: String? = null @Schema(name = "isRichText", title = "是否为富文本") - var isRichText: Boolean? = null + var isRichText: Boolean = true @Schema(name = "message", title = "发送内容") var message: String? = null @@ -33,5 +33,5 @@ class EmailSend { var ccParam: String? = null @Schema(name = "file", title = "发送的文件") - var file: Array? = null + var files: Array? = null } diff --git a/dao/src/main/kotlin/cn/bunny/dao/pojo/enums/EmailTemplateTypes.kt b/dao/src/main/kotlin/cn/bunny/dao/pojo/enums/EmailTemplateTypes.kt new file mode 100644 index 0000000..53e46d3 --- /dev/null +++ b/dao/src/main/kotlin/cn/bunny/dao/pojo/enums/EmailTemplateTypes.kt @@ -0,0 +1,8 @@ +package cn.bunny.dao.pojo.enums + +enum class EmailTemplateTypes(val type: String, val summary: String) { + VERIFICATION_CODE("verification_code", "邮箱验证码发送"), + NOTIFICATION("notification", "通知型邮件"), + WARNING("warning", "警告型邮件"), + ; +} \ No newline at end of file diff --git a/dao/src/main/kotlin/cn/bunny/dao/pojo/enums/OperationType.kt b/dao/src/main/kotlin/cn/bunny/dao/pojo/enums/OperationTypes.kt similarity index 75% rename from dao/src/main/kotlin/cn/bunny/dao/pojo/enums/OperationType.kt rename to dao/src/main/kotlin/cn/bunny/dao/pojo/enums/OperationTypes.kt index c14aff3..16f5854 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/pojo/enums/OperationType.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/pojo/enums/OperationTypes.kt @@ -3,6 +3,6 @@ package cn.bunny.dao.pojo.enums /** * 数据库操作类型 */ -enum class OperationType { +enum class OperationTypes { UPDATE, INSERT } diff --git a/dao/src/main/kotlin/cn/bunny/dao/pojo/result/ResultCodeEnum.kt b/dao/src/main/kotlin/cn/bunny/dao/pojo/result/ResultCodeEnum.kt index f257b08..cb9e712 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/pojo/result/ResultCodeEnum.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/pojo/result/ResultCodeEnum.kt @@ -15,15 +15,18 @@ enum class ResultCodeEnum(val code: Int, val message: String) { // 验证错误 201 USERNAME_OR_PASSWORD_NOT_EMPTY(201, "用户名或密码不能为空"), EMAIL_CODE_NOT_EMPTY(201, "邮箱验证码不能为空"), - SEND_EMAIL_CODE_NOT_EMPTY(201, "请先发送邮箱验证码"), + EMAIL_CODE_EMPTY(201, "邮箱验证码过期或不存在"), EMAIL_CODE_NOT_MATCHING(201, "邮箱验证码不匹配"), LOGIN_ERROR(201, "账号或密码错误"), LOGIN_ERROR_USERNAME_PASSWORD_NOT_EMPTY(201, "登录信息不能为空"), + SEND_MAIL_CODE_ERROR(201, "邮件发送失败"), // 数据相关 206 ILLEGAL_REQUEST(206, "非法请求"), REPEAT_SUBMIT(206, "重复提交"), DATA_ERROR(206, "数据异常"), + EMAIL_TEMPLATE_IS_EMPTY(206, "邮件模板为空"), + EMAIL_USER_TEMPLATE_IS_EMPTY(206, "邮件模板为空"), // 身份过期 208 LOGIN_AUTH(208, "请先登陆"), @@ -31,7 +34,7 @@ enum class ResultCodeEnum(val code: Int, val message: String) { SESSION_EXPIRATION(208, "会话过期"), // 封禁 209 - FAIL_NO_ACCESS_DENIED_USER_LOCKED(209, "该账户被封禁"), + FAIL_NO_ACCESS_DENIED_USER_LOCKED(209, "账户已封禁"), THE_SAME_USER_HAS_LOGGED_IN(209, "相同用户已登录"), // 提示错误 diff --git a/dao/src/main/kotlin/cn/bunny/dao/vo/user/LoginVo.kt b/dao/src/main/kotlin/cn/bunny/dao/vo/user/LoginVo.kt index 9b412d2..a9c9cf9 100644 --- a/dao/src/main/kotlin/cn/bunny/dao/vo/user/LoginVo.kt +++ b/dao/src/main/kotlin/cn/bunny/dao/vo/user/LoginVo.kt @@ -14,12 +14,12 @@ import lombok.* @Builder @Schema(name = "LoginVo对象", title = "登录成功返回内容", description = "登录成功返回内容") class LoginVo : BaseVo() { - @Schema(name = "nickName", title = "昵称") - var nickName: String? = null - @Schema(name = "username", title = "用户名") var username: String? = null + @Schema(name = "nickName", title = "昵称") + var nickName: String? = null + @Schema(name = "email", title = "邮箱") var email: String? = null @@ -32,32 +32,20 @@ class LoginVo : BaseVo() { @Schema(name = "avatar", title = "头像") var avatar: String? = null - @Schema(name = "sex", title = "0:女 1:男") + @Schema(name = "sex", title = "性别", description = "0:女 1:男") var sex: Byte? = null - @Schema(name = "personDescription", title = "个人描述") - var personDescription: String? = null - - @Schema(name = "articleMode", title = "文章显示模式") - var articleMode: String? = null - - @Schema(name = "layout", title = "页面布局方式") - var layout: String? = null + @Schema(name = "summary", title = "个人描述") + var summary: String? = null @Schema(name = "lastLoginIp", title = "最后登录IP") var lastLoginIp: String? = null - @Schema(name = "lastLoginIpAddress", title = "最后登录ip地址") + @Schema(name = "lastLoginIpAddress", title = "最后登录ip归属地") var lastLoginIpAddress: String? = null - @Schema(name = "totalIntegral", title = "积分") - var totalIntegral: Int? = null - - @Schema(name = "currentIntegral", title = "当前积分") - var currentIntegral: Int? = null - - @Schema(name = "status", title = "0:禁用 1:正常") - var status: Boolean? = null + @Schema(name = "status", title = "状态", description = "1:禁用 0:正常") + var status: Byte? = null @Schema(name = "token", title = "令牌") var token: String? = null diff --git a/services/src/main/kotlin/cn/bunny/services/controller/EmailTemplateController.java b/services/src/main/kotlin/cn/bunny/services/controller/EmailTemplateController.java new file mode 100644 index 0000000..1012681 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/controller/EmailTemplateController.java @@ -0,0 +1,18 @@ +package cn.bunny.services.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 前端控制器 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@RestController +@RequestMapping("/emailTemplate") +public class EmailTemplateController { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/controller/EmailUsersController.java b/services/src/main/kotlin/cn/bunny/services/controller/EmailUsersController.java new file mode 100644 index 0000000..7e92d34 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/controller/EmailUsersController.java @@ -0,0 +1,18 @@ +package cn.bunny.services.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 邮箱发送表 前端控制器 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@RestController +@RequestMapping("/emailUsers") +public class EmailUsersController { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/controller/I18nController.java b/services/src/main/kotlin/cn/bunny/services/controller/I18nController.java index 2c624c2..1793e48 100644 --- a/services/src/main/kotlin/cn/bunny/services/controller/I18nController.java +++ b/services/src/main/kotlin/cn/bunny/services/controller/I18nController.java @@ -12,9 +12,9 @@ import org.springframework.web.bind.annotation.RestController; * @author Bunny * @since 2024-09-26 */ +@Tag(name = "多语言", description = "多语言相关接口") @RestController @RequestMapping("/i18n") -@Tag(name = "多语言", description = "多语言相关接口") public class I18nController { } diff --git a/services/src/main/kotlin/cn/bunny/services/controller/I18nTypeController.java b/services/src/main/kotlin/cn/bunny/services/controller/I18nTypeController.java index b380356..e4252bb 100644 --- a/services/src/main/kotlin/cn/bunny/services/controller/I18nTypeController.java +++ b/services/src/main/kotlin/cn/bunny/services/controller/I18nTypeController.java @@ -12,9 +12,9 @@ import org.springframework.web.bind.annotation.RestController; * @author Bunny * @since 2024-09-26 */ +@Tag(name = "多语言类型", description = "多语言类型相关接口") @RestController @RequestMapping("/i18nType") -@Tag(name = "多语言类型", description = "多语言类型相关接口") public class I18nTypeController { } diff --git a/services/src/main/kotlin/cn/bunny/services/controller/IndexController.kt b/services/src/main/kotlin/cn/bunny/services/controller/IndexController.kt index 7411636..e712695 100644 --- a/services/src/main/kotlin/cn/bunny/services/controller/IndexController.kt +++ b/services/src/main/kotlin/cn/bunny/services/controller/IndexController.kt @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/") class IndexController { + @Operation(summary = "访问首页", description = "访问首页") @GetMapping("") fun index(): String { diff --git a/services/src/main/kotlin/cn/bunny/services/controller/MenuIconController.java b/services/src/main/kotlin/cn/bunny/services/controller/MenuIconController.java new file mode 100644 index 0000000..b7a4f17 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/controller/MenuIconController.java @@ -0,0 +1,20 @@ +package cn.bunny.services.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 系统菜单图标 前端控制器 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Tag(name = "菜单Icon", description = "菜单Icon相关接口") +@RestController +@RequestMapping("/menuIcon") +public class MenuIconController { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/controller/RouterController.java b/services/src/main/kotlin/cn/bunny/services/controller/RouterController.java new file mode 100644 index 0000000..11849c5 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/controller/RouterController.java @@ -0,0 +1,20 @@ +package cn.bunny.services.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 系统菜单表 前端控制器 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Tag(name = "系统路由", description = "系统路由相关接口") +@RestController +@RequestMapping("/router") +public class RouterController { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/controller/UserController.kt b/services/src/main/kotlin/cn/bunny/services/controller/UserController.kt index 8d9ee8d..db70267 100644 --- a/services/src/main/kotlin/cn/bunny/services/controller/UserController.kt +++ b/services/src/main/kotlin/cn/bunny/services/controller/UserController.kt @@ -1,6 +1,11 @@ package cn.bunny.services.controller +import cn.bunny.dao.pojo.result.Result +import cn.bunny.services.service.UserService +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.RequestMapping import org.springframework.web.bind.annotation.RestController @@ -14,6 +19,17 @@ import org.springframework.web.bind.annotation.RestController * @since 2024-09-26 */ @RestController -@RequestMapping("/user") +@RequestMapping("/admin/user") @Tag(name = "系统用户", description = "系统用户相关接口") -class UserController +class UserController { + + @Autowired + private lateinit var userService: UserService + + @Operation(summary = "登录发送邮件验证码", description = "登录发送邮件验证码") + @PostMapping("noAuth/sendLoginEmail") + fun sendLoginEmail(email: String): Result { + userService.sendLoginEmail(email) + return Result.success() + } +} diff --git a/services/src/main/kotlin/cn/bunny/services/factory/EmailFactory.kt b/services/src/main/kotlin/cn/bunny/services/factory/EmailFactory.kt new file mode 100644 index 0000000..d865973 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/factory/EmailFactory.kt @@ -0,0 +1,58 @@ +package cn.bunny.services.factory + +import cn.bunny.common.service.exception.BunnyException +import cn.bunny.common.service.utils.email.MailSenderUtil +import cn.bunny.dao.entity.system.EmailTemplate +import cn.bunny.dao.pojo.email.EmailSend +import cn.bunny.dao.pojo.email.EmailSendInit +import cn.bunny.dao.pojo.enums.EmailTemplateTypes +import cn.bunny.dao.pojo.result.ResultCodeEnum +import cn.bunny.services.mapper.EmailTemplateMapper +import cn.hutool.captcha.CaptchaUtil +import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper +import jakarta.mail.MessagingException +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component + +@Component +class EmailFactory { + @Autowired + private lateinit var emailTemplateMapper: EmailTemplateMapper + + /** + * * 生成邮箱验证码 + * + * @param email 接受者邮箱 + * @param emailSendInit 初始化发送参数 + */ + fun sendmailCode(email: String, emailSendInit: EmailSendInit): String { + // 查询验证码邮件模板 + val lambdaQueryWrapper = KtQueryWrapper(EmailTemplate()) + lambdaQueryWrapper.eq(EmailTemplate::isDefault, 1) + lambdaQueryWrapper.eq(EmailTemplate::type, EmailTemplateTypes.VERIFICATION_CODE.type) + val emailTemplate = emailTemplateMapper.selectOne(lambdaQueryWrapper) + + // 判断邮件模板是否为空 + if (emailTemplate === null) throw BunnyException(ResultCodeEnum.EMAIL_TEMPLATE_IS_EMPTY) + + // 生成验证码 + val captcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 2) + val code = captcha.code + val htmlContent = emailTemplate.body?.replace("\${verifyCode}", code) + + // 发送验证码 + val mailSenderUtil = MailSenderUtil(emailSendInit) + try { + val emailSend = EmailSend() + emailSend.subject = emailTemplate.subject + emailSend.message = htmlContent + emailSend.sendTo = email + emailSend.isRichText = true + mailSenderUtil.sendEmail(emailSend) + } catch (e: MessagingException) { + throw BunnyException(ResultCodeEnum.SEND_MAIL_CODE_ERROR) + } + + return code + } +} \ No newline at end of file diff --git a/services/src/main/kotlin/cn/bunny/services/factory/UserFactory.kt b/services/src/main/kotlin/cn/bunny/services/factory/UserFactory.kt new file mode 100644 index 0000000..4096c70 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/factory/UserFactory.kt @@ -0,0 +1,57 @@ +package cn.bunny.services.factory + +import cn.bunny.common.service.utils.JwtHelper +import cn.bunny.common.service.utils.ip.IpUtil +import cn.bunny.dao.entity.system.AdminUser +import cn.bunny.dao.pojo.constant.RedisUserConstant.Companion.getAdminLoginInfoPrefix +import cn.bunny.dao.pojo.constant.RedisUserConstant.Companion.getAdminUserEmailCodePrefix +import cn.bunny.dao.vo.user.LoginVo +import cn.bunny.services.mapper.UserMapper +import org.springframework.beans.BeanUtils +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.data.redis.core.RedisTemplate +import org.springframework.stereotype.Component +import org.springframework.transaction.annotation.Transactional +import java.util.concurrent.TimeUnit + +@Component +@Transactional +class UserFactory { + @Qualifier("redisTemplate") + @Autowired + private lateinit var redisTemplate: RedisTemplate + + @Autowired + private lateinit var userMapper: UserMapper + + fun buildUserVo(user: AdminUser, readMeDay: Long): LoginVo { + // 创建token + val userId = user.id + val token = JwtHelper.createToken(userId, user.email, readMeDay.toInt()) + + // 设置用户IP地址,并更新用户信息 + val updateUser = AdminUser() + updateUser.id = userId + updateUser.lastLoginIp = IpUtil.getCurrentUserIpAddress().remoteAddr + updateUser.lastLoginIpAddress = IpUtil.getCurrentUserIpAddress().ipRegion + + // 构建返回对象 + val loginVo = LoginVo() + BeanUtils.copyProperties(user, loginVo) + loginVo.token = token + loginVo.lastLoginIp = IpUtil.getCurrentUserIpAddress().remoteAddr + loginVo.lastLoginIpAddress = IpUtil.getCurrentUserIpAddress().ipRegion + // TODO 设置权限和角色内容 + loginVo.roleList = listOf("admin", "common") + loginVo.powerList = listOf("*.*") + + // 将信息保存在Redis中 + redisTemplate.opsForValue().set(getAdminLoginInfoPrefix(user.email!!), loginVo, readMeDay, TimeUnit.DAYS) + + // 将Redis中验证码删除 + redisTemplate.delete(getAdminUserEmailCodePrefix(user.email!!)) + + return loginVo + } +} \ No newline at end of file diff --git a/services/src/main/kotlin/cn/bunny/services/mapper/EmailTemplateMapper.java b/services/src/main/kotlin/cn/bunny/services/mapper/EmailTemplateMapper.java new file mode 100644 index 0000000..be6a70a --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/mapper/EmailTemplateMapper.java @@ -0,0 +1,18 @@ +package cn.bunny.services.mapper; + +import cn.bunny.dao.entity.system.EmailTemplate; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Mapper +public interface EmailTemplateMapper extends BaseMapper { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/mapper/EmailUsersMapper.java b/services/src/main/kotlin/cn/bunny/services/mapper/EmailUsersMapper.java new file mode 100644 index 0000000..849c062 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/mapper/EmailUsersMapper.java @@ -0,0 +1,18 @@ +package cn.bunny.services.mapper; + +import cn.bunny.dao.entity.system.EmailUsers; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 邮箱发送表 Mapper 接口 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Mapper +public interface EmailUsersMapper extends BaseMapper { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/mapper/MenuIconMapper.java b/services/src/main/kotlin/cn/bunny/services/mapper/MenuIconMapper.java new file mode 100644 index 0000000..5893726 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/mapper/MenuIconMapper.java @@ -0,0 +1,18 @@ +package cn.bunny.services.mapper; + +import cn.bunny.dao.entity.system.MenuIcon; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 系统菜单图标 Mapper 接口 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Mapper +public interface MenuIconMapper extends BaseMapper { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/mapper/RouterMapper.java b/services/src/main/kotlin/cn/bunny/services/mapper/RouterMapper.java new file mode 100644 index 0000000..1ec2630 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/mapper/RouterMapper.java @@ -0,0 +1,18 @@ +package cn.bunny.services.mapper; + +import cn.bunny.dao.entity.system.Router; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 系统菜单表 Mapper 接口 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Mapper +public interface RouterMapper extends BaseMapper { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/mapper/UserMapper.java b/services/src/main/kotlin/cn/bunny/services/mapper/UserMapper.java index 5957bda..03c6a9b 100644 --- a/services/src/main/kotlin/cn/bunny/services/mapper/UserMapper.java +++ b/services/src/main/kotlin/cn/bunny/services/mapper/UserMapper.java @@ -1,6 +1,6 @@ package cn.bunny.services.mapper; -import cn.bunny.dao.entity.user.AdminUser; +import cn.bunny.dao.entity.system.AdminUser; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; diff --git a/services/src/main/kotlin/cn/bunny/services/security/config/WebSecurityConfig.kt b/services/src/main/kotlin/cn/bunny/services/security/config/WebSecurityConfig.kt index 84c75c1..ae58fdd 100644 --- a/services/src/main/kotlin/cn/bunny/services/security/config/WebSecurityConfig.kt +++ b/services/src/main/kotlin/cn/bunny/services/security/config/WebSecurityConfig.kt @@ -5,8 +5,8 @@ import cn.bunny.services.security.filter.TokenAuthenticationFilter import cn.bunny.services.security.filter.TokenLoginFilterService import cn.bunny.services.security.handelr.SecurityAccessDeniedHandler import cn.bunny.services.security.handelr.SecurityAuthenticationEntryPoint -import cn.bunny.services.security.service.CustomAuthorizationManagerService import cn.bunny.services.security.service.CustomUserDetailsService +import cn.bunny.services.security.service.impl.CustomAuthorizationManagerServiceImpl import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -27,7 +27,7 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher @Configuration @EnableWebSecurity @EnableMethodSecurity -open class WebSecurityConfig { +class WebSecurityConfig { @Autowired private val redisTemplate: RedisTemplate? = null @@ -41,14 +41,14 @@ open class WebSecurityConfig { // 自定义验证码 @Autowired - private val customAuthorizationManager: CustomAuthorizationManagerService? = null + private val customAuthorizationManager: CustomAuthorizationManagerServiceImpl? = null @Autowired private val authenticationConfiguration: AuthenticationConfiguration? = null @Bean @Throws(Exception::class) - open fun filterChain(httpSecurity: HttpSecurity): SecurityFilterChain { + fun filterChain(httpSecurity: HttpSecurity): SecurityFilterChain { httpSecurity // 前端段分离不需要---禁用明文验证 .httpBasic { obj: HttpBasicConfigurer -> obj.disable() } // 前端段分离不需要---禁用默认登录页 .formLogin { obj: FormLoginConfigurer -> obj.disable() } // 前端段分离不需要---禁用退出页 @@ -90,7 +90,7 @@ open class WebSecurityConfig { // 排出鉴定路径 @Bean - open fun webSecurityCustomizer(): WebSecurityCustomizer { + fun webSecurityCustomizer(): WebSecurityCustomizer { val annotations = arrayOf( "/", "/ws/**", "/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**", diff --git a/services/src/main/kotlin/cn/bunny/services/security/custom/CustomUser.kt b/services/src/main/kotlin/cn/bunny/services/security/custom/CustomUser.kt index ccbbc07..4273d84 100644 --- a/services/src/main/kotlin/cn/bunny/services/security/custom/CustomUser.kt +++ b/services/src/main/kotlin/cn/bunny/services/security/custom/CustomUser.kt @@ -1,6 +1,6 @@ package cn.bunny.services.security.custom -import cn.bunny.dao.entity.user.AdminUser +import cn.bunny.dao.entity.system.AdminUser import lombok.Getter import lombok.Setter import org.springframework.security.core.GrantedAuthority diff --git a/services/src/main/kotlin/cn/bunny/services/security/filter/TokenAuthenticationFilter.kt b/services/src/main/kotlin/cn/bunny/services/security/filter/TokenAuthenticationFilter.kt index 4baf974..a1494ed 100644 --- a/services/src/main/kotlin/cn/bunny/services/security/filter/TokenAuthenticationFilter.kt +++ b/services/src/main/kotlin/cn/bunny/services/security/filter/TokenAuthenticationFilter.kt @@ -27,10 +27,7 @@ class TokenAuthenticationFilter(private val redisTemplate: RedisTemplate out(response, Result.error(ResultCodeEnum.USERNAME_OR_PASSWORD_NOT_EMPTY)) else -> out(response, Result.error(null, ResultCodeEnum.LOGIN_ERROR)) } diff --git a/services/src/main/kotlin/cn/bunny/services/security/service/CustomAuthorizationManagerService.kt b/services/src/main/kotlin/cn/bunny/services/security/service/CustomAuthorizationManagerService.kt deleted file mode 100644 index f3ce3b2..0000000 --- a/services/src/main/kotlin/cn/bunny/services/security/service/CustomAuthorizationManagerService.kt +++ /dev/null @@ -1,6 +0,0 @@ -package cn.bunny.services.security.service - -import org.springframework.security.authorization.AuthorizationManager -import org.springframework.security.web.access.intercept.RequestAuthorizationContext - -interface CustomAuthorizationManagerService : AuthorizationManager diff --git a/services/src/main/kotlin/cn/bunny/services/security/service/CustomUserDetailsService.kt b/services/src/main/kotlin/cn/bunny/services/security/service/CustomUserDetailsService.kt index 5867c43..98b1190 100644 --- a/services/src/main/kotlin/cn/bunny/services/security/service/CustomUserDetailsService.kt +++ b/services/src/main/kotlin/cn/bunny/services/security/service/CustomUserDetailsService.kt @@ -1,6 +1,6 @@ package cn.bunny.services.security.service -import cn.bunny.dao.dto.user.LoginDto +import cn.bunny.dao.dto.system.LoginDto import cn.bunny.dao.vo.user.LoginVo import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UserDetailsService diff --git a/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.kt b/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.kt index 7eb09f5..31e1391 100644 --- a/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.kt +++ b/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomAuthorizationManagerServiceImpl.kt @@ -1,18 +1,14 @@ -package cn.bunny.services.security.service.impl; - -import cn.bunny.common.service.utils.JwtHelper; -import cn.bunny.services.security.service.CustomAuthorizationManagerService; -import jakarta.servlet.http.HttpServletRequest; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.authorization.AuthorizationDecision; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.web.access.intercept.RequestAuthorizationContext; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.function.Supplier; +package cn.bunny.services.security.service.impl +import cn.bunny.common.service.utils.JwtHelper.getUserId +import lombok.extern.slf4j.Slf4j +import org.springframework.security.authorization.AuthorizationDecision +import org.springframework.security.authorization.AuthorizationManager +import org.springframework.security.core.Authentication +import org.springframework.security.core.GrantedAuthority +import org.springframework.security.web.access.intercept.RequestAuthorizationContext +import org.springframework.stereotype.Component +import java.util.function.Supplier /** * 自定义权限判断 @@ -20,28 +16,26 @@ import java.util.function.Supplier; */ @Component @Slf4j -public class CustomAuthorizationManagerServiceImpl implements CustomAuthorizationManagerService { - - @Override - public void verify(Supplier authentication, RequestAuthorizationContext requestAuthorizationContext) { - CustomAuthorizationManagerService.super.verify(authentication, requestAuthorizationContext); +class CustomAuthorizationManagerServiceImpl : AuthorizationManager { + override fun verify(authentication: Supplier, requestAuthorizationContext: RequestAuthorizationContext) { + super.verify(authentication, requestAuthorizationContext) } - @Override - public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) { + override fun check(authentication: Supplier, context: RequestAuthorizationContext): AuthorizationDecision { // 用户的token和用户id、请求Url - HttpServletRequest request = context.getRequest(); - String token = request.getHeader("token"); + val request = context.request + val token = request.getHeader("token") // 用户id - Long userId = JwtHelper.getUserId(token); + val userId = getUserId(token) // 请求地址 - String requestURI = request.getRequestURI(); + val requestURI = request.requestURI // 请求方式 - String method = request.getMethod(); + val method = request.method // 角色代码列表 - List roleCodeList = authentication.get().getAuthorities().stream().map(GrantedAuthority::getAuthority).toList(); + val roleCodeList = authentication.get().authorities.stream().map { obj: GrantedAuthority -> obj.authority } + .toList() - return new AuthorizationDecision(hasRoleList(requestURI, method, userId)); + return AuthorizationDecision(hasRoleList(requestURI, method, userId)) } /** @@ -51,7 +45,7 @@ public class CustomAuthorizationManagerServiceImpl implements CustomAuthorizatio * @param method 请求方式 * @param userId 用户id */ - private Boolean hasRoleList(String requestURI, String method, Long userId) { - return true; + private fun hasRoleList(requestURI: String, method: String, userId: Long?): Boolean { + return true } } diff --git a/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.kt b/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.kt index 52fc37a..ceb75ab 100644 --- a/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.kt +++ b/services/src/main/kotlin/cn/bunny/services/security/service/impl/CustomUserDetailsServiceImpl.kt @@ -1,36 +1,43 @@ package cn.bunny.services.security.service.impl -import cn.bunny.dao.dto.user.LoginDto -import cn.bunny.dao.entity.user.AdminUser +import cn.bunny.common.service.exception.BunnyException +import cn.bunny.dao.dto.system.LoginDto +import cn.bunny.dao.entity.system.AdminUser +import cn.bunny.dao.pojo.result.ResultCodeEnum import cn.bunny.dao.vo.user.LoginVo +import cn.bunny.services.factory.UserFactory import cn.bunny.services.mapper.UserMapper import cn.bunny.services.security.custom.CustomUser import cn.bunny.services.security.service.CustomUserDetailsService -import com.baomidou.mybatisplus.core.toolkit.Wrappers -import com.baomidou.mybatisplus.core.toolkit.support.SFunction +import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.security.core.authority.AuthorityUtils import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UsernameNotFoundException import org.springframework.stereotype.Component +import org.springframework.util.DigestUtils @Component class CustomUserDetailsServiceImpl : CustomUserDetailsService { @Autowired - private val userMapper: UserMapper? = null + private lateinit var userFactory: UserFactory + + @Autowired + private lateinit var userMapper: UserMapper + @Throws(UsernameNotFoundException::class) override fun loadUserByUsername(username: String): UserDetails { - // 根据邮箱查询用户名 - val user = userMapper!!.selectOne( - Wrappers.lambdaQuery().eq(SFunction { obj: AdminUser -> obj.email }, username) - ) - // 都为空抛出异常,用户不存在 - if (user == null) { - throw UsernameNotFoundException("") - } + // 查询用户相关内容 + val queryWrapper = KtQueryWrapper(AdminUser()).eq(AdminUser::email, username) + .or() + .eq(AdminUser::username, username) - // 查询所有的角色 + // 根据邮箱查询用户名 + val user = userMapper.selectOne(queryWrapper) + user ?: throw UsernameNotFoundException("") + + // TODO 查询所有的角色 return CustomUser(user, AuthorityUtils.createAuthorityList(listOf("admin", "common"))) } @@ -41,7 +48,18 @@ class CustomUserDetailsServiceImpl : CustomUserDetailsService { * @return 登录后结果返回 */ override fun login(loginDto: LoginDto): LoginVo { - // 自定义登录逻辑 - return LoginVo() + val username = loginDto.username + val password = loginDto.password + + // 查询用户相关内容 + val queryWrapper = KtQueryWrapper(AdminUser()).eq(AdminUser::email, username).or() + .eq(AdminUser::username, username) + val user = userMapper.selectOne(queryWrapper) + + // 对登录密码进行md5加密判断,是否与数据库中一致 + val md5Password: String = DigestUtils.md5DigestAsHex(password!!.byteInputStream()) + if (!user.password.equals(md5Password)) throw BunnyException(ResultCodeEnum.LOGIN_ERROR) + + return userFactory.buildUserVo(user, loginDto.readMeDay) } } diff --git a/services/src/main/kotlin/cn/bunny/services/service/EmailTemplateService.java b/services/src/main/kotlin/cn/bunny/services/service/EmailTemplateService.java new file mode 100644 index 0000000..c22adfc --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/EmailTemplateService.java @@ -0,0 +1,16 @@ +package cn.bunny.services.service; + +import cn.bunny.dao.entity.system.EmailTemplate; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +public interface EmailTemplateService extends IService { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/service/EmailUsersService.java b/services/src/main/kotlin/cn/bunny/services/service/EmailUsersService.java new file mode 100644 index 0000000..c3577d3 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/EmailUsersService.java @@ -0,0 +1,16 @@ +package cn.bunny.services.service; + +import cn.bunny.dao.entity.system.EmailUsers; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 邮箱发送表 服务类 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +public interface EmailUsersService extends IService { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/service/MenuIconService.java b/services/src/main/kotlin/cn/bunny/services/service/MenuIconService.java new file mode 100644 index 0000000..f9c8d6d --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/MenuIconService.java @@ -0,0 +1,16 @@ +package cn.bunny.services.service; + +import cn.bunny.dao.entity.system.MenuIcon; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 系统菜单图标 服务类 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +public interface MenuIconService extends IService { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/service/RouterService.java b/services/src/main/kotlin/cn/bunny/services/service/RouterService.java new file mode 100644 index 0000000..130b11a --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/RouterService.java @@ -0,0 +1,16 @@ +package cn.bunny.services.service; + +import cn.bunny.dao.entity.system.Router; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 系统菜单表 服务类 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +public interface RouterService extends IService { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/service/UserService.java b/services/src/main/kotlin/cn/bunny/services/service/UserService.java index 9b19acc..e7faad0 100644 --- a/services/src/main/kotlin/cn/bunny/services/service/UserService.java +++ b/services/src/main/kotlin/cn/bunny/services/service/UserService.java @@ -1,7 +1,8 @@ package cn.bunny.services.service; -import cn.bunny.dao.entity.user.AdminUser; +import cn.bunny.dao.entity.system.AdminUser; import com.baomidou.mybatisplus.extension.service.IService; +import org.jetbrains.annotations.NotNull; /** *

@@ -13,4 +14,10 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface UserService extends IService { + /** + * 登录发送邮件验证码 + * + * @param email 邮箱 + */ + void sendLoginEmail(@NotNull String email); } diff --git a/services/src/main/kotlin/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java b/services/src/main/kotlin/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java new file mode 100644 index 0000000..c8d7948 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/impl/EmailTemplateServiceImpl.java @@ -0,0 +1,20 @@ +package cn.bunny.services.service.impl; + +import cn.bunny.dao.entity.system.EmailTemplate; +import cn.bunny.services.mapper.EmailTemplateMapper; +import cn.bunny.services.service.EmailTemplateService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Service +public class EmailTemplateServiceImpl extends ServiceImpl implements EmailTemplateService { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/service/impl/EmailUsersServiceImpl.kt b/services/src/main/kotlin/cn/bunny/services/service/impl/EmailUsersServiceImpl.kt new file mode 100644 index 0000000..abfa4fc --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/impl/EmailUsersServiceImpl.kt @@ -0,0 +1,19 @@ +package cn.bunny.services.service.impl + +import cn.bunny.dao.entity.system.EmailUsers +import cn.bunny.services.mapper.EmailUsersMapper +import cn.bunny.services.service.EmailUsersService +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl +import org.springframework.stereotype.Service + +/** + * + * + * 邮箱发送表 服务实现类 + * + * + * @author Bunny + * @since 2024-09-26 + */ +@Service +class EmailUsersServiceImpl : ServiceImpl(), EmailUsersService diff --git a/services/src/main/kotlin/cn/bunny/services/service/impl/MenuIconServiceImpl.java b/services/src/main/kotlin/cn/bunny/services/service/impl/MenuIconServiceImpl.java new file mode 100644 index 0000000..e1851b9 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/impl/MenuIconServiceImpl.java @@ -0,0 +1,20 @@ +package cn.bunny.services.service.impl; + +import cn.bunny.dao.entity.system.MenuIcon; +import cn.bunny.services.mapper.MenuIconMapper; +import cn.bunny.services.service.MenuIconService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 系统菜单图标 服务实现类 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Service +public class MenuIconServiceImpl extends ServiceImpl implements MenuIconService { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/service/impl/RouterServiceImpl.java b/services/src/main/kotlin/cn/bunny/services/service/impl/RouterServiceImpl.java new file mode 100644 index 0000000..4aa5367 --- /dev/null +++ b/services/src/main/kotlin/cn/bunny/services/service/impl/RouterServiceImpl.java @@ -0,0 +1,20 @@ +package cn.bunny.services.service.impl; + +import cn.bunny.dao.entity.system.Router; +import cn.bunny.services.mapper.RouterMapper; +import cn.bunny.services.service.RouterService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 系统菜单表 服务实现类 + *

+ * + * @author Bunny + * @since 2024-09-26 + */ +@Service +public class RouterServiceImpl extends ServiceImpl implements RouterService { + +} diff --git a/services/src/main/kotlin/cn/bunny/services/service/impl/UserServiceImpl.kt b/services/src/main/kotlin/cn/bunny/services/service/impl/UserServiceImpl.kt index 2744591..e13c97d 100644 --- a/services/src/main/kotlin/cn/bunny/services/service/impl/UserServiceImpl.kt +++ b/services/src/main/kotlin/cn/bunny/services/service/impl/UserServiceImpl.kt @@ -1,20 +1,61 @@ -package cn.bunny.services.service.impl; +package cn.bunny.services.service.impl -import cn.bunny.dao.entity.user.AdminUser; -import cn.bunny.services.mapper.UserMapper; -import cn.bunny.services.service.UserService; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import org.springframework.stereotype.Service; +import cn.bunny.common.service.exception.BunnyException +import cn.bunny.dao.entity.system.AdminUser +import cn.bunny.dao.entity.system.EmailUsers +import cn.bunny.dao.pojo.constant.RedisUserConstant +import cn.bunny.dao.pojo.email.EmailSendInit +import cn.bunny.dao.pojo.result.ResultCodeEnum +import cn.bunny.services.factory.EmailFactory +import cn.bunny.services.mapper.EmailUsersMapper +import cn.bunny.services.mapper.UserMapper +import cn.bunny.services.service.UserService +import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper +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.transaction.annotation.Transactional /** - *

* 用户信息 服务实现类 - *

* * @author Bunny * @since 2024-09-26 */ @Service -public class UserServiceImpl extends ServiceImpl implements UserService { +@Transactional +internal class UserServiceImpl : ServiceImpl(), UserService { + @Autowired + private lateinit var redisTemplate: RedisTemplate + @Autowired + private lateinit var emailUsersMapper: EmailUsersMapper + + @Autowired + private lateinit var emailFactory: EmailFactory + + /** + * 登录发送邮件验证码 + * + * @param email 邮箱 + */ + override fun sendLoginEmail(email: String) { + // 查找数据库默认发送邮件用户 + val emailUsers: EmailUsers = emailUsersMapper.selectOne(KtQueryWrapper(EmailUsers()).eq(EmailUsers::isDefault, 1)) + ?: throw BunnyException(ResultCodeEnum.EMAIL_USER_TEMPLATE_IS_EMPTY) + + // 构建发送对象 + val emailSendInit = EmailSendInit() + BeanUtils.copyProperties(emailUsers, emailSendInit) + emailSendInit.username = emailUsers.email + + // 发送邮件 + val emailCode = emailFactory.sendmailCode(email, emailSendInit) + + // 将验证码存入Redis中 + redisTemplate.opsForValue().set(RedisUserConstant.getAdminUserEmailCodePrefix(email), emailCode) + } } + diff --git a/services/src/main/resources/application-dev.yml b/services/src/main/resources/application-dev.yml index 74a6699..2c78a04 100644 --- a/services/src/main/resources/application-dev.yml +++ b/services/src/main/resources/application-dev.yml @@ -7,8 +7,8 @@ bunny: password: "02120212" datasource2: host: 106.15.251.123 - port: 3304 - sqlData: auth_admin_i18n + port: 3305 + sqlData: auth_i18n username: root password: "02120212" diff --git a/services/src/main/resources/application-prod.yml b/services/src/main/resources/application-prod.yml index 11b23c3..2c78a04 100644 --- a/services/src/main/resources/application-prod.yml +++ b/services/src/main/resources/application-prod.yml @@ -1,14 +1,14 @@ bunny: - datasource: + datasource1: host: 192.168.3.98 port: 3304 - sqlData: bunny_docs + sqlData: auth_admin username: root password: "02120212" datasource2: - host: 192.168.3.98 - port: 3304 - sqlData: bunny_docs_i18n + host: 106.15.251.123 + port: 3305 + sqlData: auth_i18n username: root password: "02120212" diff --git a/services/src/main/resources/application.yml b/services/src/main/resources/application.yml index 32f0599..2fa4ae9 100644 --- a/services/src/main/resources/application.yml +++ b/services/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8800 + port: 7070 spring: profiles: active: dev diff --git a/services/src/main/resources/mapper/EmailTemplateMapper.xml b/services/src/main/resources/mapper/EmailTemplateMapper.xml new file mode 100644 index 0000000..b8f8d50 --- /dev/null +++ b/services/src/main/resources/mapper/EmailTemplateMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + id, template_name, subject, body, type, is_default, create_time, update_time, create_user, update_user, is_deleted + + + diff --git a/services/src/main/resources/mapper/EmailUsersMapper.xml b/services/src/main/resources/mapper/EmailUsersMapper.xml new file mode 100644 index 0000000..4a960f3 --- /dev/null +++ b/services/src/main/resources/mapper/EmailUsersMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, email, email_template, password, host, port, smtp_agreement, is_default, create_time, update_time, create_user, update_user, is_deleted + + + diff --git a/services/src/main/resources/mapper/MenuIconMapper.xml b/services/src/main/resources/mapper/MenuIconMapper.xml new file mode 100644 index 0000000..106bbc6 --- /dev/null +++ b/services/src/main/resources/mapper/MenuIconMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + id, icon_name, create_user, update_user, create_time, update_time, is_deleted + + + diff --git a/services/src/main/resources/mapper/RouterMapper.xml b/services/src/main/resources/mapper/RouterMapper.xml new file mode 100644 index 0000000..713dcab --- /dev/null +++ b/services/src/main/resources/mapper/RouterMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + id, router_path, route_name, parent_id, title, icon, router_rank, visible, create_user, update_user, create_time, update_time, is_deleted + + + diff --git a/services/src/main/resources/mapper/UserMapper.xml b/services/src/main/resources/mapper/UserMapper.xml index a0ef60a..039549e 100644 --- a/services/src/main/resources/mapper/UserMapper.xml +++ b/services/src/main/resources/mapper/UserMapper.xml @@ -3,7 +3,7 @@ - +