增加后台管理模块
This commit is contained in:
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 成就服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-09-08
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.emotion.service.impl;
|
||||
|
||||
import com.emotion.dto.request.AdminLoginRequest;
|
||||
import com.emotion.dto.response.AdminAuthResponse;
|
||||
import com.emotion.dto.response.AdminInfoResponse;
|
||||
import com.emotion.entity.Admin;
|
||||
import com.emotion.exception.AuthException;
|
||||
import com.emotion.service.AdminAuthService;
|
||||
import com.emotion.service.AdminService;
|
||||
import com.emotion.util.JwtUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 管理员认证服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @date 2025-10-27
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
|
||||
@Autowired
|
||||
private AdminService adminService;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Autowired
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
|
||||
private static final String ADMIN_TOKEN_PREFIX = "admin_token:";
|
||||
private static final String ADMIN_REFRESH_TOKEN_PREFIX = "admin_refresh_token:";
|
||||
private static final int TOKEN_EXPIRE_HOURS = 24;
|
||||
private static final int REFRESH_TOKEN_EXPIRE_DAYS = 7;
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Override
|
||||
public AdminAuthResponse login(AdminLoginRequest request) {
|
||||
Admin admin = adminService.getByAccount(request.getAccount());
|
||||
|
||||
if (admin == null) {
|
||||
throw new AuthException("账号或密码错误");
|
||||
}
|
||||
|
||||
if (admin.getStatus() != 1) {
|
||||
throw new AuthException("账号已被禁用");
|
||||
}
|
||||
|
||||
if (!passwordEncoder.matches(request.getPassword(), admin.getPassword())) {
|
||||
throw new AuthException("账号或密码错误");
|
||||
}
|
||||
|
||||
log.info("管理员登录成功: account={}, adminId={}", request.getAccount(), admin.getId());
|
||||
|
||||
String accessToken = generateAccessToken(admin);
|
||||
String refreshToken = generateRefreshToken(admin);
|
||||
|
||||
updateLoginInfo(admin);
|
||||
|
||||
AdminAuthResponse response = new AdminAuthResponse();
|
||||
response.setAccessToken(accessToken);
|
||||
response.setRefreshToken(refreshToken);
|
||||
response.setExpiresIn((long) TOKEN_EXPIRE_HOURS * 3600);
|
||||
response.setAdminInfo(convertToAdminInfoResponse(admin));
|
||||
response.setLoginTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminInfoResponse getCurrentAdminInfo(String adminId) {
|
||||
Admin admin = adminService.getById(adminId);
|
||||
if (admin == null) {
|
||||
throw new AuthException("管理员不存在");
|
||||
}
|
||||
return convertToAdminInfoResponse(admin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean logout(HttpServletRequest request) {
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
||||
String token = authHeader.substring(7);
|
||||
String adminId = jwtUtil.getUserIdFromToken(token);
|
||||
|
||||
if (adminId != null) {
|
||||
redisTemplate.delete(ADMIN_TOKEN_PREFIX + adminId);
|
||||
log.info("管理员登出成功: adminId={}", adminId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminAuthResponse refreshToken(String refreshToken) {
|
||||
if (!jwtUtil.validateToken(refreshToken)) {
|
||||
throw new AuthException("刷新令牌无效或已过期");
|
||||
}
|
||||
|
||||
String adminId = jwtUtil.getUserIdFromToken(refreshToken);
|
||||
String userType = jwtUtil.getUserTypeFromToken(refreshToken);
|
||||
|
||||
if (!"admin".equals(userType)) {
|
||||
throw new AuthException("无效的刷新令牌");
|
||||
}
|
||||
|
||||
String cachedToken = (String) redisTemplate.opsForValue().get(ADMIN_REFRESH_TOKEN_PREFIX + adminId);
|
||||
if (cachedToken == null || !cachedToken.equals(refreshToken)) {
|
||||
throw new AuthException("刷新令牌已失效");
|
||||
}
|
||||
|
||||
Admin admin = adminService.getById(adminId);
|
||||
if (admin == null) {
|
||||
throw new AuthException("管理员不存在");
|
||||
}
|
||||
|
||||
if (admin.getStatus() != 1) {
|
||||
throw new AuthException("账号已被禁用");
|
||||
}
|
||||
|
||||
String newAccessToken = generateAccessToken(admin);
|
||||
String newRefreshToken = generateRefreshToken(admin);
|
||||
|
||||
AdminAuthResponse response = new AdminAuthResponse();
|
||||
response.setAccessToken(newAccessToken);
|
||||
response.setRefreshToken(newRefreshToken);
|
||||
response.setExpiresIn((long) TOKEN_EXPIRE_HOURS * 3600);
|
||||
response.setAdminInfo(convertToAdminInfoResponse(admin));
|
||||
response.setLoginTime(LocalDateTime.now().format(DATE_TIME_FORMATTER));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateToken(HttpServletRequest request) {
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String token = authHeader.substring(7);
|
||||
if (!jwtUtil.validateToken(token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String userType = jwtUtil.getUserTypeFromToken(token);
|
||||
return "admin".equals(userType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdminIdFromToken(String token) {
|
||||
return jwtUtil.getUserIdFromToken(token);
|
||||
}
|
||||
|
||||
private String generateAccessToken(Admin admin) {
|
||||
String token = jwtUtil.generateToken(admin.getId(), admin.getUsername(), "admin");
|
||||
redisTemplate.opsForValue().set(
|
||||
ADMIN_TOKEN_PREFIX + admin.getId(),
|
||||
token,
|
||||
TOKEN_EXPIRE_HOURS,
|
||||
TimeUnit.HOURS
|
||||
);
|
||||
return token;
|
||||
}
|
||||
|
||||
private String generateRefreshToken(Admin admin) {
|
||||
String token = jwtUtil.generateRefreshToken(admin.getId(), admin.getUsername(), "admin");
|
||||
redisTemplate.opsForValue().set(
|
||||
ADMIN_REFRESH_TOKEN_PREFIX + admin.getId(),
|
||||
token,
|
||||
REFRESH_TOKEN_EXPIRE_DAYS,
|
||||
TimeUnit.DAYS
|
||||
);
|
||||
return token;
|
||||
}
|
||||
|
||||
private void updateLoginInfo(Admin admin) {
|
||||
admin.setLastLoginTime(LocalDateTime.now());
|
||||
admin.setLoginCount(admin.getLoginCount() == null ? 1 : admin.getLoginCount() + 1);
|
||||
adminService.updateById(admin);
|
||||
}
|
||||
|
||||
private AdminInfoResponse convertToAdminInfoResponse(Admin admin) {
|
||||
AdminInfoResponse response = new AdminInfoResponse();
|
||||
BeanUtils.copyProperties(admin, response);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
package com.emotion.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.emotion.common.PageResult;
|
||||
import com.emotion.dto.request.AdminCreateRequest;
|
||||
import com.emotion.dto.request.AdminPageRequest;
|
||||
import com.emotion.dto.request.AdminUpdateRequest;
|
||||
import com.emotion.dto.response.AdminResponse;
|
||||
import com.emotion.entity.Admin;
|
||||
import com.emotion.exception.BusinessException;
|
||||
import com.emotion.mapper.AdminMapper;
|
||||
import com.emotion.service.AdminService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 管理员服务实现类
|
||||
*
|
||||
* @author huazhongmin
|
||||
* @date 2025-10-27
|
||||
*/
|
||||
@Service
|
||||
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
|
||||
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
|
||||
@Override
|
||||
public PageResult<AdminResponse> getPageWithResponse(AdminPageRequest request) {
|
||||
Page<Admin> page = new Page<>(request.getCurrent(), request.getSize());
|
||||
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
if (StringUtils.hasText(request.getKeyword())) {
|
||||
wrapper.and(w -> w.like(Admin::getAccount, request.getKeyword())
|
||||
.or().like(Admin::getUsername, request.getKeyword())
|
||||
.or().like(Admin::getEmail, request.getKeyword())
|
||||
.or().like(Admin::getPhone, request.getKeyword()));
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getAccount())) {
|
||||
wrapper.like(Admin::getAccount, request.getAccount());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getUsername())) {
|
||||
wrapper.like(Admin::getUsername, request.getUsername());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getEmail())) {
|
||||
wrapper.like(Admin::getEmail, request.getEmail());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getPhone())) {
|
||||
wrapper.like(Admin::getPhone, request.getPhone());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getRole())) {
|
||||
wrapper.eq(Admin::getRole, request.getRole());
|
||||
}
|
||||
|
||||
if (request.getStatus() != null) {
|
||||
wrapper.eq(Admin::getStatus, request.getStatus());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getDepartment())) {
|
||||
wrapper.like(Admin::getDepartment, request.getDepartment());
|
||||
}
|
||||
|
||||
wrapper.eq(Admin::getIsDeleted, 0);
|
||||
|
||||
if (StringUtils.hasText(request.getOrderBy())) {
|
||||
if ("asc".equalsIgnoreCase(request.getOrderDirection())) {
|
||||
wrapper.orderByAsc(Admin::getCreateTime);
|
||||
} else {
|
||||
wrapper.orderByDesc(Admin::getCreateTime);
|
||||
}
|
||||
} else {
|
||||
wrapper.orderByDesc(Admin::getCreateTime);
|
||||
}
|
||||
|
||||
IPage<Admin> adminPage = this.page(page, wrapper);
|
||||
|
||||
List<AdminResponse> responseList = adminPage.getRecords().stream()
|
||||
.map(this::convertToResponse)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return PageResult.<AdminResponse>builder()
|
||||
.records(responseList)
|
||||
.total(adminPage.getTotal())
|
||||
.current(adminPage.getCurrent())
|
||||
.size(adminPage.getSize())
|
||||
.pages(adminPage.getPages())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminResponse getAdminResponseById(String id) {
|
||||
Admin admin = this.getById(id);
|
||||
if (admin == null) {
|
||||
return null;
|
||||
}
|
||||
return convertToResponse(admin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminResponse createAdminWithResponse(AdminCreateRequest request) {
|
||||
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getAccount, request.getAccount())
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
if (this.count(wrapper) > 0) {
|
||||
throw new BusinessException("账号已存在");
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getEmail())) {
|
||||
wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getEmail, request.getEmail())
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
if (this.count(wrapper) > 0) {
|
||||
throw new BusinessException("邮箱已存在");
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getPhone())) {
|
||||
wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getPhone, request.getPhone())
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
if (this.count(wrapper) > 0) {
|
||||
throw new BusinessException("手机号已存在");
|
||||
}
|
||||
}
|
||||
|
||||
Admin admin = new Admin();
|
||||
BeanUtils.copyProperties(request, admin);
|
||||
admin.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
admin.setStatus(1);
|
||||
admin.setLoginCount(0);
|
||||
|
||||
boolean saved = this.save(admin);
|
||||
if (!saved) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return convertToResponse(admin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminResponse updateAdminWithResponse(AdminUpdateRequest request) {
|
||||
Admin admin = this.getById(request.getId());
|
||||
if (admin == null) {
|
||||
throw new BusinessException("管理员不存在");
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getEmail()) && !request.getEmail().equals(admin.getEmail())) {
|
||||
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getEmail, request.getEmail())
|
||||
.ne(Admin::getId, request.getId())
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
if (this.count(wrapper) > 0) {
|
||||
throw new BusinessException("邮箱已存在");
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getPhone()) && !request.getPhone().equals(admin.getPhone())) {
|
||||
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getPhone, request.getPhone())
|
||||
.ne(Admin::getId, request.getId())
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
if (this.count(wrapper) > 0) {
|
||||
throw new BusinessException("手机号已存在");
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(request.getUsername())) {
|
||||
admin.setUsername(request.getUsername());
|
||||
}
|
||||
if (StringUtils.hasText(request.getEmail())) {
|
||||
admin.setEmail(request.getEmail());
|
||||
}
|
||||
if (StringUtils.hasText(request.getPhone())) {
|
||||
admin.setPhone(request.getPhone());
|
||||
}
|
||||
if (StringUtils.hasText(request.getAvatar())) {
|
||||
admin.setAvatar(request.getAvatar());
|
||||
}
|
||||
if (StringUtils.hasText(request.getRole())) {
|
||||
admin.setRole(request.getRole());
|
||||
}
|
||||
if (request.getPermissions() != null) {
|
||||
admin.setPermissions(request.getPermissions());
|
||||
}
|
||||
if (request.getStatus() != null) {
|
||||
admin.setStatus(request.getStatus());
|
||||
}
|
||||
if (StringUtils.hasText(request.getDepartment())) {
|
||||
admin.setDepartment(request.getDepartment());
|
||||
}
|
||||
if (StringUtils.hasText(request.getPosition())) {
|
||||
admin.setPosition(request.getPosition());
|
||||
}
|
||||
|
||||
boolean updated = this.updateById(admin);
|
||||
if (!updated) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return convertToResponse(admin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Admin getByAccount(String account) {
|
||||
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getAccount, account)
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
return this.getOne(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Admin getByEmail(String email) {
|
||||
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getEmail, email)
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
return this.getOne(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Admin getByPhone(String phone) {
|
||||
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Admin::getPhone, phone)
|
||||
.eq(Admin::getIsDeleted, 0);
|
||||
return this.getOne(wrapper);
|
||||
}
|
||||
|
||||
private AdminResponse convertToResponse(Admin admin) {
|
||||
AdminResponse response = new AdminResponse();
|
||||
BeanUtils.copyProperties(admin, response);
|
||||
|
||||
if (admin.getLastLoginTime() != null) {
|
||||
response.setLastLoginTime(admin.getLastLoginTime().format(DATE_TIME_FORMATTER));
|
||||
}
|
||||
if (admin.getCreateTime() != null) {
|
||||
response.setCreateTime(admin.getCreateTime().format(DATE_TIME_FORMATTER));
|
||||
}
|
||||
if (admin.getUpdateTime() != null) {
|
||||
response.setUpdateTime(admin.getUpdateTime().format(DATE_TIME_FORMATTER));
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ import java.util.Arrays;
|
||||
/**
|
||||
* AI聊天服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* 认证服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 评论服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 社区帖子服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 会话服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* Coze API调用记录服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 日记评论服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 用户日记服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 情绪分析服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 情绪记录服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 成长话题服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-09-08
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 访客用户服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-09-08
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 消息服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-09-08
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 奖励服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-09-08
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -14,7 +14,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
/**
|
||||
* 令牌服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Service
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import java.time.format.DateTimeFormatter;
|
||||
/**
|
||||
* 话题互动服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 用户服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 用户统计服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-24
|
||||
*/
|
||||
@Service
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
/**
|
||||
* WebSocket服务实现类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @author huazhongmin
|
||||
* @date 2025-07-25
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
Reference in New Issue
Block a user