Complete core functions #9
@@ -5,14 +5,12 @@ import org.aspectj.lang.annotation.AfterReturning
|
|||||||
import org.aspectj.lang.annotation.Aspect
|
import org.aspectj.lang.annotation.Aspect
|
||||||
import org.aspectj.lang.annotation.Pointcut
|
import org.aspectj.lang.annotation.Pointcut
|
||||||
import org.aspectj.lang.reflect.MethodSignature
|
import org.aspectj.lang.reflect.MethodSignature
|
||||||
import org.slf4j.Logger
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import top.fatweb.api.annotation.EventLogRecord
|
import top.fatweb.api.annotation.EventLogRecord
|
||||||
import top.fatweb.api.entity.system.EventLog
|
|
||||||
import top.fatweb.api.service.system.IEventLogService
|
import top.fatweb.api.service.system.IEventLogService
|
||||||
import top.fatweb.api.util.WebUtil
|
import top.fatweb.api.util.WebUtil
|
||||||
import top.fatweb.api.vo.permission.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
|
import top.fatweb.api.vo.permission.RegisterVo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event log record aspect
|
* Event log record aspect
|
||||||
@@ -25,24 +23,21 @@ import top.fatweb.api.vo.permission.LoginVo
|
|||||||
class EventLogAspect(
|
class EventLogAspect(
|
||||||
private val eventLogService: IEventLogService
|
private val eventLogService: IEventLogService
|
||||||
) {
|
) {
|
||||||
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
|
||||||
|
|
||||||
@Pointcut("@annotation(top.fatweb.api.annotation.EventLogRecord)")
|
@Pointcut("@annotation(top.fatweb.api.annotation.EventLogRecord)")
|
||||||
fun eventLogPointcut() {
|
fun eventLogPointcut() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterReturning(value = "eventLogPointcut()", returning = "retValue")
|
@AfterReturning(value = "eventLogPointcut()", returning = "retValue")
|
||||||
fun doAfter(joinPoint: JoinPoint, retValue: Any) {
|
fun doAfter(joinPoint: JoinPoint, retValue: Any?) {
|
||||||
val annotation = (joinPoint.signature as MethodSignature).method.getAnnotation(EventLogRecord::class.java)
|
val annotation = (joinPoint.signature as MethodSignature).method.getAnnotation(EventLogRecord::class.java)
|
||||||
|
|
||||||
try {
|
val userId = WebUtil.getLoginUserId() ?: when (retValue) {
|
||||||
eventLogService.save(EventLog().apply {
|
is LoginVo -> retValue.userId!!
|
||||||
this.event = annotation.event
|
is RegisterVo -> retValue.userId!!
|
||||||
operateUserId = WebUtil.getLoginUserId()
|
else -> -1
|
||||||
?: if (retValue is LoginVo) retValue.userId else -1
|
|
||||||
})
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logger.error("Cannot record event!!!", e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventLogService.saveEvent(annotation, userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,7 @@ import top.fatweb.api.param.permission.VerifyParam
|
|||||||
import top.fatweb.api.service.permission.IAuthenticationService
|
import top.fatweb.api.service.permission.IAuthenticationService
|
||||||
import top.fatweb.api.util.WebUtil
|
import top.fatweb.api.util.WebUtil
|
||||||
import top.fatweb.api.vo.permission.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
|
import top.fatweb.api.vo.permission.RegisterVo
|
||||||
import top.fatweb.api.vo.permission.TokenVo
|
import top.fatweb.api.vo.permission.TokenVo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,11 +37,11 @@ class AuthenticationController(
|
|||||||
*/
|
*/
|
||||||
@Operation(summary = "注册")
|
@Operation(summary = "注册")
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
fun register(@Valid @RequestBody registerParam: RegisterParam): ResponseResult<Nothing> {
|
fun register(@Valid @RequestBody registerParam: RegisterParam): ResponseResult<RegisterVo> = ResponseResult.success(
|
||||||
authenticationService.register(registerParam)
|
ResponseCode.PERMISSION_REGISTER_SUCCESS,
|
||||||
|
data = authenticationService.register(registerParam)
|
||||||
|
)
|
||||||
|
|
||||||
return ResponseResult.success(ResponseCode.PERMISSION_REGISTER_SUCCESS)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send verify email
|
* Send verify email
|
||||||
|
|||||||
@@ -7,11 +7,23 @@ import top.fatweb.api.properties.SecurityProperties
|
|||||||
import top.fatweb.api.service.system.IStatisticsLogService
|
import top.fatweb.api.service.system.IStatisticsLogService
|
||||||
import top.fatweb.api.util.RedisUtil
|
import top.fatweb.api.util.RedisUtil
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistics scheduled tasks
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
@Component
|
@Component
|
||||||
class StatisticsCron(
|
class StatisticsCron(
|
||||||
private val redisUtil: RedisUtil,
|
private val redisUtil: RedisUtil,
|
||||||
private val statisticsLogService: IStatisticsLogService
|
private val statisticsLogService: IStatisticsLogService
|
||||||
) {
|
) {
|
||||||
|
/**
|
||||||
|
* Auto record number of online users
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
@Scheduled(cron = "0 * * * * *")
|
@Scheduled(cron = "0 * * * * *")
|
||||||
fun onlineUserCount() {
|
fun onlineUserCount() {
|
||||||
statisticsLogService.save(StatisticsLog().apply {
|
statisticsLogService.save(StatisticsLog().apply {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import java.time.LocalDateTime
|
|||||||
@TableName("t_event_log")
|
@TableName("t_event_log")
|
||||||
class EventLog : Serializable {
|
class EventLog : Serializable {
|
||||||
enum class Event(@field:EnumValue @field:JsonValue val code: String) {
|
enum class Event(@field:EnumValue @field:JsonValue val code: String) {
|
||||||
LOGIN("LOGIN"), LOGOUT("LOGOUT"), REGISTER("REGISTER"), API("API")
|
LOGIN("LOGIN"), LOGOUT("LOGOUT"), REGISTER("REGISTER"), VERIFY("VERIFY"), API("API")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
package top.fatweb.api.exception
|
package top.fatweb.api.exception
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Account need initialize exception
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
class AccountNeedInitException : RuntimeException("Account need initialize")
|
class AccountNeedInitException : RuntimeException("Account need initialize")
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
package top.fatweb.api.exception
|
package top.fatweb.api.exception
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Email settings not configured exception
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
class NoEmailConfigException(
|
class NoEmailConfigException(
|
||||||
vararg configs: String
|
vararg configs: String
|
||||||
) : RuntimeException("Email settings not configured: ${configs.joinToString(", ")}")
|
) : RuntimeException("Email settings not configured: ${configs.joinToString(", ")}")
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
package top.fatweb.api.exception
|
package top.fatweb.api.exception
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No verification required exception
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
class NoVerificationRequiredException : RuntimeException("No verification required")
|
class NoVerificationRequiredException : RuntimeException("No verification required")
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
package top.fatweb.api.exception
|
package top.fatweb.api.exception
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verification code error or expired exception
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
class VerificationCodeErrorOrExpiredException : RuntimeException("Verification code is error or has expired")
|
class VerificationCodeErrorOrExpiredException : RuntimeException("Verification code is error or has expired")
|
||||||
@@ -4,5 +4,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
|||||||
import org.apache.ibatis.annotations.Mapper
|
import org.apache.ibatis.annotations.Mapper
|
||||||
import top.fatweb.api.entity.system.EventLog
|
import top.fatweb.api.entity.system.EventLog
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event log mapper
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
interface EventLogMapper : BaseMapper<EventLog>
|
interface EventLogMapper : BaseMapper<EventLog>
|
||||||
@@ -4,5 +4,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper
|
|||||||
import org.apache.ibatis.annotations.Mapper
|
import org.apache.ibatis.annotations.Mapper
|
||||||
import top.fatweb.api.entity.system.StatisticsLog
|
import top.fatweb.api.entity.system.StatisticsLog
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistics log mapper
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
interface StatisticsLogMapper : BaseMapper<StatisticsLog>
|
interface StatisticsLogMapper : BaseMapper<StatisticsLog>
|
||||||
@@ -86,6 +86,7 @@ data class UserAddParam(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Schema(description = "昵称")
|
@Schema(description = "昵称")
|
||||||
|
@field:NotBlank(message = "Nickname can not be blank")
|
||||||
val nickname: String?,
|
val nickname: String?,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ package top.fatweb.api.param.system
|
|||||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||||
import com.fasterxml.jackson.annotation.JsonValue
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get active information parameters
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
data class ActiveInfoGetParam(
|
data class ActiveInfoGetParam(
|
||||||
val scope: Scope = Scope.WEAK
|
val scope: Scope = Scope.WEAK
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ package top.fatweb.api.param.system
|
|||||||
import com.baomidou.mybatisplus.annotation.EnumValue
|
import com.baomidou.mybatisplus.annotation.EnumValue
|
||||||
import com.fasterxml.jackson.annotation.JsonValue
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get online information parameters
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
data class OnlineInfoGetParam(
|
data class OnlineInfoGetParam(
|
||||||
val scope: Scope = Scope.WEAK
|
val scope: Scope = Scope.WEAK
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import top.fatweb.api.param.permission.LoginParam
|
|||||||
import top.fatweb.api.param.permission.RegisterParam
|
import top.fatweb.api.param.permission.RegisterParam
|
||||||
import top.fatweb.api.param.permission.VerifyParam
|
import top.fatweb.api.param.permission.VerifyParam
|
||||||
import top.fatweb.api.vo.permission.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
|
import top.fatweb.api.vo.permission.RegisterVo
|
||||||
import top.fatweb.api.vo.permission.TokenVo
|
import top.fatweb.api.vo.permission.TokenVo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,7 +22,7 @@ interface IAuthenticationService {
|
|||||||
* @author FatttSnake, fatttsnake@gmail.com
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
fun register(registerParam: RegisterParam)
|
fun register(registerParam: RegisterParam): RegisterVo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send verify email
|
* Send verify email
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import top.fatweb.api.util.MailUtil
|
|||||||
import top.fatweb.api.util.RedisUtil
|
import top.fatweb.api.util.RedisUtil
|
||||||
import top.fatweb.api.util.WebUtil
|
import top.fatweb.api.util.WebUtil
|
||||||
import top.fatweb.api.vo.permission.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
|
import top.fatweb.api.vo.permission.RegisterVo
|
||||||
import top.fatweb.api.vo.permission.TokenVo
|
import top.fatweb.api.vo.permission.TokenVo
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -63,13 +64,14 @@ class AuthenticationServiceImpl(
|
|||||||
) : IAuthenticationService {
|
) : IAuthenticationService {
|
||||||
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
|
||||||
|
@EventLogRecord(EventLog.Event.REGISTER)
|
||||||
@Transactional
|
@Transactional
|
||||||
override fun register(registerParam: RegisterParam) {
|
override fun register(registerParam: RegisterParam): RegisterVo {
|
||||||
val user = User().apply {
|
val user = User().apply {
|
||||||
username = registerParam.username
|
username = registerParam.username
|
||||||
password = passwordEncoder.encode(registerParam.password)
|
password = passwordEncoder.encode(registerParam.password)
|
||||||
verify =
|
verify =
|
||||||
"${LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()}-${UUID.randomUUID()}"
|
"${LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
||||||
locking = 0
|
locking = 0
|
||||||
enable = 1
|
enable = 1
|
||||||
}
|
}
|
||||||
@@ -82,6 +84,8 @@ class AuthenticationServiceImpl(
|
|||||||
})
|
})
|
||||||
|
|
||||||
sendVerifyMail(user.username!!, "http://localhost:5173/verify?code=${user.verify!!}", registerParam.email!!)
|
sendVerifyMail(user.username!!, "http://localhost:5173/verify?code=${user.verify!!}", registerParam.email!!)
|
||||||
|
|
||||||
|
return RegisterVo(userId = user.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -91,7 +95,7 @@ class AuthenticationServiceImpl(
|
|||||||
user.verify ?: throw NoVerificationRequiredException()
|
user.verify ?: throw NoVerificationRequiredException()
|
||||||
|
|
||||||
user.verify =
|
user.verify =
|
||||||
"${LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()}-${UUID.randomUUID()}"
|
"${LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
||||||
user.updateTime = LocalDateTime.now(ZoneOffset.UTC)
|
user.updateTime = LocalDateTime.now(ZoneOffset.UTC)
|
||||||
userService.updateById(user)
|
userService.updateById(user)
|
||||||
|
|
||||||
@@ -113,11 +117,12 @@ class AuthenticationServiceImpl(
|
|||||||
template.merge(velocityContext, stringWriter)
|
template.merge(velocityContext, stringWriter)
|
||||||
|
|
||||||
MailUtil.sendSimpleMail(
|
MailUtil.sendSimpleMail(
|
||||||
"激活您的账号", stringWriter.toString(), true,
|
"验证您的账号", stringWriter.toString(), true,
|
||||||
email
|
email
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventLogRecord(EventLog.Event.VERIFY)
|
||||||
@Transactional
|
@Transactional
|
||||||
override fun verify(verifyParam: VerifyParam) {
|
override fun verify(verifyParam: VerifyParam) {
|
||||||
val user = userService.getById(WebUtil.getLoginUserId()) ?: throw AccessDeniedException("Access Denied")
|
val user = userService.getById(WebUtil.getLoginUserId()) ?: throw AccessDeniedException("Access Denied")
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import top.fatweb.api.vo.permission.UserWithPasswordRoleInfoVo
|
|||||||
import top.fatweb.api.vo.permission.UserWithRoleInfoVo
|
import top.fatweb.api.vo.permission.UserWithRoleInfoVo
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User service implement
|
* User service implement
|
||||||
@@ -111,9 +112,12 @@ class UserServiceImpl(
|
|||||||
|
|
||||||
user.apply {
|
user.apply {
|
||||||
password = passwordEncoder.encode(rawPassword)
|
password = passwordEncoder.encode(rawPassword)
|
||||||
|
verify = if (userAddParam.verified) null else "${
|
||||||
|
LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()
|
||||||
|
}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseMapper.insert(user) == 1) {
|
if (this.save(user)) {
|
||||||
user.userInfo?.let { userInfoService.save(it.apply { userId = user.id }) }
|
user.userInfo?.let { userInfoService.save(it.apply { userId = user.id }) }
|
||||||
|
|
||||||
if (!user.roles.isNullOrEmpty()) {
|
if (!user.roles.isNullOrEmpty()) {
|
||||||
@@ -175,9 +179,16 @@ class UserServiceImpl(
|
|||||||
removeGroupIds.removeAll(addGroupIds)
|
removeGroupIds.removeAll(addGroupIds)
|
||||||
oldGroupList.toSet().let { addGroupIds.removeAll(it) }
|
oldGroupList.toSet().let { addGroupIds.removeAll(it) }
|
||||||
|
|
||||||
baseMapper.updateById(user)
|
this.updateById(user)
|
||||||
baseMapper.update(
|
this.update(
|
||||||
KtUpdateWrapper(User()).eq(User::id, user.id).set(User::expiration, user.expiration)
|
KtUpdateWrapper(User()).eq(User::id, user.id)
|
||||||
|
.set(
|
||||||
|
User::verify,
|
||||||
|
if (userUpdateParam.verified) null else "${
|
||||||
|
LocalDateTime.now(ZoneOffset.UTC).toInstant(ZoneOffset.UTC).toEpochMilli()
|
||||||
|
}-${UUID.randomUUID()}-${UUID.randomUUID()}-${UUID.randomUUID()}"
|
||||||
|
)
|
||||||
|
.set(User::expiration, user.expiration)
|
||||||
.set(User::credentialsExpiration, user.credentialsExpiration)
|
.set(User::credentialsExpiration, user.credentialsExpiration)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -230,7 +241,7 @@ class UserServiceImpl(
|
|||||||
throw AccessDeniedException("Access denied")
|
throw AccessDeniedException("Access denied")
|
||||||
}
|
}
|
||||||
|
|
||||||
val user = baseMapper.selectById(userUpdatePasswordParam.id)
|
val user = this.getById(userUpdatePasswordParam.id)
|
||||||
user?.let {
|
user?.let {
|
||||||
val wrapper = KtUpdateWrapper(User())
|
val wrapper = KtUpdateWrapper(User())
|
||||||
wrapper.eq(User::id, user.id)
|
wrapper.eq(User::id, user.id)
|
||||||
@@ -265,7 +276,7 @@ class UserServiceImpl(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
baseMapper.deleteBatchIds(ids)
|
this.removeBatchByIds(ids)
|
||||||
userInfoService.remove(KtQueryWrapper(UserInfo()).`in`(UserInfo::userId, ids))
|
userInfoService.remove(KtQueryWrapper(UserInfo()).`in`(UserInfo::userId, ids))
|
||||||
userRoleService.remove(KtQueryWrapper(UserRole()).`in`(UserRole::userId, ids))
|
userRoleService.remove(KtQueryWrapper(UserRole()).`in`(UserRole::userId, ids))
|
||||||
userGroupService.remove(KtQueryWrapper(UserGroup()).`in`(UserGroup::userId, ids))
|
userGroupService.remove(KtQueryWrapper(UserGroup()).`in`(UserGroup::userId, ids))
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
package top.fatweb.api.service.system
|
package top.fatweb.api.service.system
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService
|
import com.baomidou.mybatisplus.extension.service.IService
|
||||||
|
import top.fatweb.api.annotation.EventLogRecord
|
||||||
import top.fatweb.api.entity.system.EventLog
|
import top.fatweb.api.entity.system.EventLog
|
||||||
|
|
||||||
interface IEventLogService : IService<EventLog>
|
/**
|
||||||
|
* Event log service interface
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
interface IEventLogService : IService<EventLog> {
|
||||||
|
fun saveEvent(annotation: EventLogRecord, userId: Long)
|
||||||
|
}
|
||||||
@@ -3,4 +3,10 @@ package top.fatweb.api.service.system
|
|||||||
import com.baomidou.mybatisplus.extension.service.IService
|
import com.baomidou.mybatisplus.extension.service.IService
|
||||||
import top.fatweb.api.entity.system.StatisticsLog
|
import top.fatweb.api.entity.system.StatisticsLog
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistics log service interface
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
interface IStatisticsLogService : IService<StatisticsLog>
|
interface IStatisticsLogService : IService<StatisticsLog>
|
||||||
@@ -2,11 +2,30 @@ package top.fatweb.api.service.system.impl
|
|||||||
|
|
||||||
import com.baomidou.dynamic.datasource.annotation.DS
|
import com.baomidou.dynamic.datasource.annotation.DS
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
import org.springframework.transaction.annotation.Propagation
|
||||||
|
import org.springframework.transaction.annotation.Transactional
|
||||||
|
import top.fatweb.api.annotation.EventLogRecord
|
||||||
import top.fatweb.api.entity.system.EventLog
|
import top.fatweb.api.entity.system.EventLog
|
||||||
import top.fatweb.api.mapper.system.EventLogMapper
|
import top.fatweb.api.mapper.system.EventLogMapper
|
||||||
import top.fatweb.api.service.system.IEventLogService
|
import top.fatweb.api.service.system.IEventLogService
|
||||||
|
|
||||||
@DS("sqlite")
|
@DS("sqlite")
|
||||||
@Service
|
@Service
|
||||||
class EventLogServiceImpl : ServiceImpl<EventLogMapper, EventLog>(), IEventLogService
|
class EventLogServiceImpl : ServiceImpl<EventLogMapper, EventLog>(), IEventLogService {
|
||||||
|
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
|
override fun saveEvent(annotation: EventLogRecord, userId: Long) {
|
||||||
|
try {
|
||||||
|
this.save(EventLog().apply {
|
||||||
|
this.event = annotation.event
|
||||||
|
operateUserId = userId
|
||||||
|
})
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logger.error("Cannot record event!!!", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -223,6 +223,6 @@ class StatisticsServiceImpl(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ActiveInfoVo(getHistory("REGISTER"), getHistory("LOGIN"))
|
return ActiveInfoVo(getHistory("REGISTER"), getHistory("LOGIN"), getHistory("VERIFY"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,12 @@ package top.fatweb.api.settings
|
|||||||
import com.fasterxml.jackson.annotation.JsonCreator
|
import com.fasterxml.jackson.annotation.JsonCreator
|
||||||
import com.fasterxml.jackson.annotation.JsonValue
|
import com.fasterxml.jackson.annotation.JsonValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of mail security
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
enum class MailSecurityType(val code: String) {
|
enum class MailSecurityType(val code: String) {
|
||||||
NONE("None"),
|
NONE("None"),
|
||||||
SSL_TLS("SSL/TLS"),
|
SSL_TLS("SSL/TLS"),
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ import top.fatweb.api.settings.MailSettings
|
|||||||
import top.fatweb.api.settings.SettingsOperator
|
import top.fatweb.api.settings.SettingsOperator
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mail util
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
object MailUtil {
|
object MailUtil {
|
||||||
private val mailSender: JavaMailSenderImpl = JavaMailSenderImpl()
|
private val mailSender: JavaMailSenderImpl = JavaMailSenderImpl()
|
||||||
|
|
||||||
|
|||||||
24
src/main/kotlin/top/fatweb/api/vo/permission/RegisterVo.kt
Normal file
24
src/main/kotlin/top/fatweb/api/vo/permission/RegisterVo.kt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register value object
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "注册返回参数")
|
||||||
|
data class RegisterVo(
|
||||||
|
/**
|
||||||
|
* User ID
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Schema(description = "User ID", example = "1709986058679975938")
|
||||||
|
@JsonSerialize(using = ToStringSerializer::class)
|
||||||
|
val userId: Long?
|
||||||
|
)
|
||||||
@@ -25,7 +25,15 @@ data class ActiveInfoVo(
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
* @see HistoryVo
|
* @see HistoryVo
|
||||||
*/
|
*/
|
||||||
val loginHistory: List<HistoryVo>
|
val loginHistory: List<HistoryVo>,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify user number history
|
||||||
|
*
|
||||||
|
* @author FatttSnake, fatttsnake@gmail.com
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
val verifyHistory: List<HistoryVo>
|
||||||
) {
|
) {
|
||||||
data class HistoryVo(
|
data class HistoryVo(
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ create table if not exists t_user
|
|||||||
id bigint not null primary key,
|
id bigint not null primary key,
|
||||||
username varchar(20) not null comment '用户名',
|
username varchar(20) not null comment '用户名',
|
||||||
password char(70) not null comment '密码',
|
password char(70) not null comment '密码',
|
||||||
verify varchar(50) null comment '验证信息',
|
verify varchar(144) null comment '验证信息',
|
||||||
locking int not null comment '锁定',
|
locking int not null comment '锁定',
|
||||||
expiration datetime comment '过期时间',
|
expiration datetime comment '过期时间',
|
||||||
credentials_expiration datetime comment '认证过期时间',
|
credentials_expiration datetime comment '认证过期时间',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ create table if not exists t_user_info
|
|||||||
(
|
(
|
||||||
id bigint not null primary key,
|
id bigint not null primary key,
|
||||||
user_id bigint not null comment '用户ID',
|
user_id bigint not null comment '用户ID',
|
||||||
nickname varchar(50) null comment '昵称',
|
nickname varchar(50) not null comment '昵称',
|
||||||
avatar text null comment '头像',
|
avatar text null comment '头像',
|
||||||
email varchar(100) not null comment '邮箱',
|
email varchar(100) not null comment '邮箱',
|
||||||
create_time datetime not null default (utc_timestamp()) comment '创建时间',
|
create_time datetime not null default (utc_timestamp()) comment '创建时间',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport"
|
<meta name="viewport"
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>激活您的账号</title>
|
<title>验证您的账号</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user