From 704e3c25bf816db092d3cb57106a8a4f50373136 Mon Sep 17 00:00:00 2001 From: xupei Date: Mon, 12 Aug 2024 09:51:39 +0800 Subject: [PATCH 01/10] =?UTF-8?q?BUG=E4=BF=AE=E5=A4=8D=EF=BC=9A=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=9B=B4=E6=94=B9=E5=A5=97=E9=A4=90=EF=BC=8C=E7=A7=AF?= =?UTF-8?q?=E5=88=86/=E7=94=A8=E6=88=B7=E8=A7=92=E8=89=B2=E4=B8=8D?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../da/service/impl/AccountServiceImpl.java | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java index eec39d47..3d102279 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -300,6 +300,19 @@ public class AccountServiceImpl extends ServiceImpl impl QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("BINARY user_email", email); List accountList = accountMapper.selectList(queryWrapper); + log.info(accountList.toString()); + if (CollectionUtil.isEmpty(accountList)) { + throw new BusinessException("email.does.not.exist", ResultEnum.PROMPT.getCode()); + } + return accountList.get(0); + } + + // 忽略大小写 + private Account getAccountByEmail(String email) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_email", email); + List accountList = accountMapper.selectList(queryWrapper); + log.info(accountList.toString()); if (CollectionUtil.isEmpty(accountList)) { throw new BusinessException("email.does.not.exist", ResultEnum.PROMPT.getCode()); } @@ -1068,6 +1081,7 @@ public class AccountServiceImpl extends ServiceImpl impl int orderId = queryOrderResultSet.getInt("order_id"); int customerId = queryOrderResultSet.getInt("customer_id"); double totalSales = queryOrderResultSet.getDouble("total_sales"); + log.info("Code-Create 订单:{}, 顾客id:{}, 付款金额:{}",orderId, customerId, totalSales); String email = ""; String userName = ""; // 为什么一般没有值 @@ -1094,7 +1108,7 @@ public class AccountServiceImpl extends ServiceImpl impl Boolean flag = Boolean.FALSE; try { // 不是新用户 直接延长使用期限 - userInfo = getOneByEmail(email); + userInfo = getAccountByEmail(email); } catch (BusinessException e) { // 通过邮箱找不到用户 说明是新用户 => 创建用户 flag = Boolean.TRUE; @@ -1106,23 +1120,24 @@ public class AccountServiceImpl extends ServiceImpl impl Account account = extendValidity(validEndTime, totalSales); int systemUserType = 0; + + // 不管是不是新用户 都要更新用户角色和积分 + String credits = "0"; + if (totalSales == 5000.0){ + log.info("年付用户,初始积分6000"); + credits = CreditsEventsEnum.INIT_MONTHLY.getValue(); + systemUserType = 1; + }else if (totalSales == 500.0){ + log.info("月付用户,初始积分5000"); + credits = CreditsEventsEnum.INIT_MONTHLY.getValue(); + systemUserType = 2; + }else if (totalSales == 0.0){ + log.info("测试用户,初始积分10"); + credits = "10"; + systemUserType = 3; + } if (flag) { // 是新用户 => 新增一条数据 - String credits = "0"; - if (totalSales == 5000.0){ - log.info("年付用户,初始积分6000"); - credits = CreditsEventsEnum.INIT_MONTHLY.getValue(); - systemUserType = 1; - }else if (totalSales == 500.0){ - log.info("月付用户,初始积分5000"); - credits = CreditsEventsEnum.INIT_MONTHLY.getValue(); - systemUserType = 2; - }else if (totalSales == 0.0){ - log.info("测试用户,初始积分10"); - credits = "10"; - systemUserType = 3; - } - Boolean b = addUser(new AccountAddDTO(email, StringUtil.isNullOrEmpty(userName) ? email.substring(0, email.indexOf("@")) : userName, country, @@ -1131,6 +1146,8 @@ public class AccountServiceImpl extends ServiceImpl impl if (b) log.info("付费新用户 {} 新增成功!", email); } else { userInfo.setValidEndTime(toDayEnd(account.getValidEndTime())); + userInfo.setCredits(new BigDecimal(credits)); + userInfo.setSystemUser(systemUserType); baseMapper.updateById(userInfo); log.info("付费用户 {} 续订成功", email); } From 085dac063040225c65c4bb01d9e53be85364916f Mon Sep 17 00:00:00 2001 From: xupei Date: Thu, 15 Aug 2024 16:25:44 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=B6=88=E6=81=AF=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 + .../security/filter/AuthenticationFilter.java | 267 +++++++++--------- .../websocket/NotificationConnection.java | 43 +++ .../websocket/config/WebSocketConfig.java | 18 ++ .../controller/MessageCenterController.java | 56 ++++ .../da/mapper/primary/NotificationMapper.java | 20 ++ .../SysNotificationReadStatusMapper.java | 7 + .../ai/da/mapper/primary/entity/Account.java | 5 + .../mapper/primary/entity/Notification.java | 67 +++++ .../entity/SysNotificationReadStatus.java | 26 ++ .../com/ai/da/model/vo/GetNotificationVO.java | 15 + .../com/ai/da/model/vo/NotificationVO.java | 17 ++ .../da/model/vo/PublishSysNotificationVO.java | 19 ++ .../java/com/ai/da/python/PythonService.java | 1 + .../ai/da/service/MessageCenterService.java | 26 ++ .../da/service/impl/AccountServiceImpl.java | 2 +- .../da/service/impl/GenerateServiceImpl.java | 2 +- .../impl/MessageCenterServiceImpl.java | 243 ++++++++++++++++ .../da/service/impl/PortfolioServiceImpl.java | 21 +- .../mapper/primary/NotificationMapper.xml | 43 +++ 20 files changed, 768 insertions(+), 136 deletions(-) create mode 100644 src/main/java/com/ai/da/common/websocket/NotificationConnection.java create mode 100644 src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java create mode 100644 src/main/java/com/ai/da/controller/MessageCenterController.java create mode 100644 src/main/java/com/ai/da/mapper/primary/NotificationMapper.java create mode 100644 src/main/java/com/ai/da/mapper/primary/SysNotificationReadStatusMapper.java create mode 100644 src/main/java/com/ai/da/mapper/primary/entity/Notification.java create mode 100644 src/main/java/com/ai/da/mapper/primary/entity/SysNotificationReadStatus.java create mode 100644 src/main/java/com/ai/da/model/vo/GetNotificationVO.java create mode 100644 src/main/java/com/ai/da/model/vo/NotificationVO.java create mode 100644 src/main/java/com/ai/da/model/vo/PublishSysNotificationVO.java create mode 100644 src/main/java/com/ai/da/service/MessageCenterService.java create mode 100644 src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java create mode 100644 src/main/resources/mapper/primary/NotificationMapper.xml diff --git a/pom.xml b/pom.xml index 0816680b..e20e83e1 100644 --- a/pom.xml +++ b/pom.xml @@ -282,6 +282,12 @@ itextpdf 5.5.13.2 + + + org.springframework.boot + spring-boot-starter-websocket + + diff --git a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java index 0f61d591..bc6071c8 100644 --- a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java +++ b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java @@ -1,133 +1,134 @@ -package com.ai.da.common.security.filter; - -import cn.hutool.core.util.StrUtil; -import com.ai.da.common.context.UserContext; -import com.ai.da.common.security.config.SecurityProperties; -import com.ai.da.common.security.jwt.JWTTokenHelper; -import com.ai.da.common.utils.LocalCacheUtils; -import com.ai.da.common.utils.MultiReadHttpServletRequest; -import com.ai.da.common.utils.MultiReadHttpServletResponse; -import com.ai.da.common.utils.RequestInfoUtil; -import com.ai.da.model.vo.AuthPrincipalVo; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Configuration; -import org.springframework.lang.NonNull; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.util.StopWatch; -import org.springframework.util.StringUtils; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.annotation.Resource; -import javax.security.sasl.AuthenticationException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -/** - * @author: dangweijian - * @description: 认证拦截器 - * @create: 2020-07-10 16:50 - **/ -@Slf4j -@Configuration -public class AuthenticationFilter extends OncePerRequestFilter { - - @Resource - private JWTTokenHelper jwtTokenHelper; - @Resource - private SecurityProperties properties; - - private static final List FILTER_URL = - Arrays.asList("/favicon.ico", "/doc.html", "api/account/login", "api/account/preLogin", "api/account/sendEmail","api/account/noLoginRequired", - "/webjars/", "/swagger-resources", "/v2/api-docs", "api/account/resetPwd", - "/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId", - "/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile", - "/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew", - "/api/third/party/existNoLoginRequired","/api/third/party/getRedirectUrl", - "/api/python/flush","/api/account/healthy","/api/ali-pay/trade/notify","/api/paypal/ipn/back","/api/alipay-hk/trade/notify", - "/api/portfolio/page", "/api/portfolio/detail", "/api/portfolio/commentPage", "/api/portfolio/viewsIncrease", - "/api/account/designWorksRegister","/api/account/questionnaire","/api/stripe/trade/notify" - ); - - @Override - protected void doFilterInternal(HttpServletRequest httpServletRequest, @NonNull HttpServletResponse httpServletResponse, @NonNull FilterChain filterChain) throws ServletException, IOException { - String requestURI = httpServletRequest.getRequestURI(); - - if (calculateUrl(requestURI) || hasAuthorizationToken(httpServletRequest)) { - StopWatch stopWatch = new StopWatch(); - HttpServletRequest wrappedRequest = httpServletRequest; - HttpServletResponse wrappedResponse = httpServletResponse; - try { - stopWatch.start(); - if ((httpServletRequest.getContentType() == null && httpServletRequest.getContentLength() > 0) || (httpServletRequest.getContentType() != null && !httpServletRequest.getContentType().contains("application/json"))) { - extracted(wrappedRequest); - filterChain.doFilter(wrappedRequest, wrappedResponse); - } else { - wrappedRequest = new MultiReadHttpServletRequest(httpServletRequest); - wrappedResponse = new MultiReadHttpServletResponse(httpServletResponse); - extracted(wrappedRequest); - filterChain.doFilter(wrappedRequest, wrappedResponse); - } - } catch (Exception e) { - SecurityContextHolder.clearContext(); - throw e; - } finally { - stopWatch.stop(); - } - } else { - filterChain.doFilter(httpServletRequest, httpServletResponse); - } - } - - private Boolean calculateUrl(String requestURI) { - String filterUrl = FILTER_URL.stream().filter(url -> requestURI.contains(url)).findFirst().orElse(null); - return null == filterUrl ? Boolean.TRUE : Boolean.FALSE; - } - - private boolean hasAuthorizationToken(HttpServletRequest request) { - String authorizationHeader = request.getHeader("Authorization"); - return authorizationHeader != null && authorizationHeader.startsWith("Bearer"); - } - - private void extracted(HttpServletRequest request) throws AuthenticationException { - String jwtToken = request.getHeader(properties.getJwtTokenHeader()); -// log.debug("后台检查令牌:{}", jwtToken); - - if (StrUtil.isBlank(jwtToken)) { - String ipAddress = RequestInfoUtil.getIpAddress(request); - log.info("本次请求的ip为 : " + ipAddress); - throw new RuntimeException("请传入token!"); - } - if(jwtToken.equals("Bearer-eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyIiwic3ViIjoie1wiaWRcIjoyLFwidXNlcm5hbWVcIjpcImxpcnNcIn0iLCJpYXQiOjE2NjU3NDEwODcsImlzcyI6IkRXSiIsImF1dGhvcml0aWVzIjoiW10iLCJleHAiOjE2NzQzODEwODd9.ShM9R_NNFD7oo1OvxrEgg7PFeWinOuAKkuInUCMQupp66s64Hhv8tN0Wwr83nIN4rHPqtn95wmd4msWcvaFYJA")){ - //写死 暂时放行 - return; - } - // 检查token - boolean validate = jwtTokenHelper.validateToken(jwtToken); - if (validate) { - AuthPrincipalVo principal = jwtTokenHelper.parserToUser(jwtToken); - if (principal == null) { - throw new RuntimeException("TOKEN已过期,请重新登录!"); - } - //先清空当前线程变量,防止上一个线程遗留 - UserContext.delete(); - //存取用户信息到缓存 - UserContext.setUserHolder(principal); - //校验token - String cacheToken = LocalCacheUtils.getTokenCache(String.valueOf(principal.getId())); - - if(StringUtils.isEmpty(cacheToken)){ - throw new RuntimeException("TOKEN已过期,请重新登录!"); - } - if(!cacheToken.equals(jwtToken) ){ - throw new RuntimeException("TOKEN已过期,请重新登录!"); - } -// UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(null, null); -// SecurityContextHolder.getContext().setAuthentication(authentication); - } - } -} +package com.ai.da.common.security.filter; + +import cn.hutool.core.util.StrUtil; +import com.ai.da.common.context.UserContext; +import com.ai.da.common.security.config.SecurityProperties; +import com.ai.da.common.security.jwt.JWTTokenHelper; +import com.ai.da.common.utils.LocalCacheUtils; +import com.ai.da.common.utils.MultiReadHttpServletRequest; +import com.ai.da.common.utils.MultiReadHttpServletResponse; +import com.ai.da.common.utils.RequestInfoUtil; +import com.ai.da.model.vo.AuthPrincipalVo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.lang.NonNull; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.StopWatch; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.annotation.Resource; +import javax.security.sasl.AuthenticationException; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** + * @author: dangweijian + * @description: 认证拦截器 + * @create: 2020-07-10 16:50 + **/ +@Slf4j +@Configuration +public class AuthenticationFilter extends OncePerRequestFilter { + + @Resource + private JWTTokenHelper jwtTokenHelper; + @Resource + private SecurityProperties properties; + + private static final List FILTER_URL = + Arrays.asList("/favicon.ico", "/doc.html", "api/account/login", "api/account/preLogin", "api/account/sendEmail","api/account/noLoginRequired", + "/webjars/", "/swagger-resources", "/v2/api-docs", "api/account/resetPwd", + "/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId", + "/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile", + "/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew", + "/api/third/party/existNoLoginRequired","/api/third/party/getRedirectUrl", + "/api/python/flush","/api/account/healthy","/api/ali-pay/trade/notify","/api/paypal/ipn/back","/api/alipay-hk/trade/notify", + "/api/portfolio/page", "/api/portfolio/detail", "/api/portfolio/commentPage", "/api/portfolio/viewsIncrease", + "/api/account/designWorksRegister","/api/account/questionnaire","/api/stripe/trade/notify", + "/notification" + ); + + @Override + protected void doFilterInternal(HttpServletRequest httpServletRequest, @NonNull HttpServletResponse httpServletResponse, @NonNull FilterChain filterChain) throws ServletException, IOException { + String requestURI = httpServletRequest.getRequestURI(); + + if (calculateUrl(requestURI) || hasAuthorizationToken(httpServletRequest)) { + StopWatch stopWatch = new StopWatch(); + HttpServletRequest wrappedRequest = httpServletRequest; + HttpServletResponse wrappedResponse = httpServletResponse; + try { + stopWatch.start(); + if ((httpServletRequest.getContentType() == null && httpServletRequest.getContentLength() > 0) || (httpServletRequest.getContentType() != null && !httpServletRequest.getContentType().contains("application/json"))) { + extracted(wrappedRequest); + filterChain.doFilter(wrappedRequest, wrappedResponse); + } else { + wrappedRequest = new MultiReadHttpServletRequest(httpServletRequest); + wrappedResponse = new MultiReadHttpServletResponse(httpServletResponse); + extracted(wrappedRequest); + filterChain.doFilter(wrappedRequest, wrappedResponse); + } + } catch (Exception e) { + SecurityContextHolder.clearContext(); + throw e; + } finally { + stopWatch.stop(); + } + } else { + filterChain.doFilter(httpServletRequest, httpServletResponse); + } + } + + private Boolean calculateUrl(String requestURI) { + String filterUrl = FILTER_URL.stream().filter(url -> requestURI.contains(url)).findFirst().orElse(null); + return null == filterUrl ? Boolean.TRUE : Boolean.FALSE; + } + + private boolean hasAuthorizationToken(HttpServletRequest request) { + String authorizationHeader = request.getHeader("Authorization"); + return authorizationHeader != null && authorizationHeader.startsWith("Bearer"); + } + + private void extracted(HttpServletRequest request) throws AuthenticationException { + String jwtToken = request.getHeader(properties.getJwtTokenHeader()); +// log.debug("后台检查令牌:{}", jwtToken); + + if (StrUtil.isBlank(jwtToken)) { + String ipAddress = RequestInfoUtil.getIpAddress(request); + log.info("本次请求的ip为 : " + ipAddress); + throw new RuntimeException("请传入token!"); + } + if(jwtToken.equals("Bearer-eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyIiwic3ViIjoie1wiaWRcIjoyLFwidXNlcm5hbWVcIjpcImxpcnNcIn0iLCJpYXQiOjE2NjU3NDEwODcsImlzcyI6IkRXSiIsImF1dGhvcml0aWVzIjoiW10iLCJleHAiOjE2NzQzODEwODd9.ShM9R_NNFD7oo1OvxrEgg7PFeWinOuAKkuInUCMQupp66s64Hhv8tN0Wwr83nIN4rHPqtn95wmd4msWcvaFYJA")){ + //写死 暂时放行 + return; + } + // 检查token + boolean validate = jwtTokenHelper.validateToken(jwtToken); + if (validate) { + AuthPrincipalVo principal = jwtTokenHelper.parserToUser(jwtToken); + if (principal == null) { + throw new RuntimeException("TOKEN已过期,请重新登录!"); + } + //先清空当前线程变量,防止上一个线程遗留 + UserContext.delete(); + //存取用户信息到缓存 + UserContext.setUserHolder(principal); + //校验token + String cacheToken = LocalCacheUtils.getTokenCache(String.valueOf(principal.getId())); + + if(StringUtils.isEmpty(cacheToken)){ + throw new RuntimeException("TOKEN已过期,请重新登录!"); + } + if(!cacheToken.equals(jwtToken) ){ + throw new RuntimeException("TOKEN已过期,请重新登录!"); + } +// UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(null, null); +// SecurityContextHolder.getContext().setAuthentication(authentication); + } + } +} diff --git a/src/main/java/com/ai/da/common/websocket/NotificationConnection.java b/src/main/java/com/ai/da/common/websocket/NotificationConnection.java new file mode 100644 index 00000000..f9a9cb52 --- /dev/null +++ b/src/main/java/com/ai/da/common/websocket/NotificationConnection.java @@ -0,0 +1,43 @@ +package com.ai.da.common.websocket; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +@ServerEndpoint(value = "/notification") +@Component +@Slf4j +public class NotificationConnection { + + static Map sessionMap = new ConcurrentHashMap<>(); + //连接建立时执行的操作 + @OnOpen + public void onOpen(Session session){ + sessionMap.put(session.getId(),session); + log.info("websocket is open"); + } + //收到了客户端消息执行的操作 + @OnMessage + public void onMessage(String text){ + log.info("收到了一条消息:"+text); +// return "已收到你的消息"; + } + //连接关闭的时候执行的操作 + @OnClose + public void onClose(Session session){ + sessionMap.remove(session.getId()); + log.info("websocket is close"); + } + + public void sendMsg(String message) throws IOException { + for(String key:sessionMap.keySet()){ + sessionMap.get(key).getBasicRemote().sendText(message); + } + } +} diff --git a/src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java b/src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java new file mode 100644 index 00000000..df5b252b --- /dev/null +++ b/src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.ai.da.common.websocket.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * Configuration of WebSocket + * + * @author db1995 + */ +@Configuration +public class WebSocketConfig { + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/src/main/java/com/ai/da/controller/MessageCenterController.java b/src/main/java/com/ai/da/controller/MessageCenterController.java new file mode 100644 index 00000000..385c7557 --- /dev/null +++ b/src/main/java/com/ai/da/controller/MessageCenterController.java @@ -0,0 +1,56 @@ +package com.ai.da.controller; + +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.common.response.Response; +import com.ai.da.model.vo.GetNotificationVO; +import com.ai.da.model.vo.NotificationVO; +import com.ai.da.model.vo.PublishSysNotificationVO; +import com.ai.da.service.MessageCenterService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; + +@Api(tags = "消息中心模块") +@Slf4j +@RestController +@RequestMapping("/api/message") +public class MessageCenterController { + + @Resource + private MessageCenterService messageCenterService; + + // 获取未读消息总数 + @ApiOperation(value = "获取未读消息数") + @GetMapping("/getUnreadCount") + public Response> getUnreadMessage(){ + return Response.success(messageCenterService.getAllTypeMessageUnreadCount()); + } + + // 获取历史消息 + @ApiOperation(value = "获取历史消息") + @PostMapping("/getHistoryNotification") + public Response> getHistoryNotification(@Valid @RequestBody GetNotificationVO getNotificationVO) { + return Response.success(messageCenterService.getHistoryNotification(getNotificationVO)); + } + + // 已读消息 + @ApiOperation(value = "设置消息状态为已读") + @PostMapping("/setReadStatus") + public Response setReadStatus(@RequestParam("notificationIdList") List notificationIdList, @RequestParam("type") String type) { + return Response.success(messageCenterService.setReadStatus(notificationIdList, type)); + } + + // 发布系统消息 + @ApiOperation(value = "发布系统消息") + @PostMapping("/publishSysMessage") + public Response publishSysMessage(@Valid @RequestBody PublishSysNotificationVO message) { + messageCenterService.publishSystemNotification(message); + return Response.success("success"); + } +} diff --git a/src/main/java/com/ai/da/mapper/primary/NotificationMapper.java b/src/main/java/com/ai/da/mapper/primary/NotificationMapper.java new file mode 100644 index 00000000..54427ace --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/NotificationMapper.java @@ -0,0 +1,20 @@ +package com.ai.da.mapper.primary; + +import com.ai.da.common.config.mybatis.plus.CommonMapper; +import com.ai.da.mapper.primary.entity.Notification; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +public interface NotificationMapper extends CommonMapper { + + List> getTypeCount(Long receiverId); + + /** 解决mybatis-plus自动过滤 is_deleted为1的数据 问题 */ + Notification getUniqueLikeAndFollow(String type, Long senderId, Long receiverId, Long portfolioId); + + void updateUniqueLikeAndFollow(Long id, LocalDateTime time); + + void deleteNotification(Long id, LocalDateTime time); +} diff --git a/src/main/java/com/ai/da/mapper/primary/SysNotificationReadStatusMapper.java b/src/main/java/com/ai/da/mapper/primary/SysNotificationReadStatusMapper.java new file mode 100644 index 00000000..fedf035f --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/SysNotificationReadStatusMapper.java @@ -0,0 +1,7 @@ +package com.ai.da.mapper.primary; + +import com.ai.da.common.config.mybatis.plus.CommonMapper; +import com.ai.da.mapper.primary.entity.SysNotificationReadStatus; + +public interface SysNotificationReadStatusMapper extends CommonMapper { +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Account.java b/src/main/java/com/ai/da/mapper/primary/entity/Account.java index 8e39896b..285acd90 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/Account.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/Account.java @@ -99,4 +99,9 @@ public class Account implements Serializable { * 4 : 参加活动获取30天有效期和6000个积分的用户 */ private Integer systemUser; + + /** + * 头像 + */ + private String avatar; } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Notification.java b/src/main/java/com/ai/da/mapper/primary/entity/Notification.java new file mode 100644 index 00000000..2e743a8f --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/Notification.java @@ -0,0 +1,67 @@ +package com.ai.da.mapper.primary.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@TableName("t_notification") +@Data +public class Notification extends BaseEntity{ + /** + * 操作类型 system/like/comment/follow + */ + private String type; + /** + * 发起操作者用户id + */ + private Long senderId; + /** + * 被操作对象用户id + */ + private Long receiverId; + /** + * 点赞评论时的作品id + */ + private Long portfolioId; + /** + * 消息内容 + */ + private String content; + /** + * 评论id + */ + private Long commentId; + /** + * 个人消息已读状态 + */ + private Integer isRead; + /** + * 系统消息发布状态 + */ + private Integer publishFlag; + + /** + * 是否被删除 + */ + private Integer isDeleted; + + public Notification() { + } + + public Notification(String type, Long senderId, Long receiverId, Long portfolioId) { + this.type = type; + this.senderId = senderId; + this.receiverId = receiverId; + this.portfolioId = portfolioId; + } + + public Notification(String type, Long senderId, Long receiverId, Long portfolioId, String content, Long commentId) { + this.type = type; + this.senderId = senderId; + this.receiverId = receiverId; + this.portfolioId = portfolioId; + this.content = content; + this.commentId = commentId; + } +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/SysNotificationReadStatus.java b/src/main/java/com/ai/da/mapper/primary/entity/SysNotificationReadStatus.java new file mode 100644 index 00000000..4e0537dc --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/SysNotificationReadStatus.java @@ -0,0 +1,26 @@ +package com.ai.da.mapper.primary.entity; + +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@TableName("t_sys_notification_read_status") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SysNotificationReadStatus extends BaseEntity{ + /** + * 系统消息id + */ + private Long system_notification_id; + + /** + * 已读当前消息的用户id将被存储 + */ + private Long account_id; +} diff --git a/src/main/java/com/ai/da/model/vo/GetNotificationVO.java b/src/main/java/com/ai/da/model/vo/GetNotificationVO.java new file mode 100644 index 00000000..e241e163 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/GetNotificationVO.java @@ -0,0 +1,15 @@ +package com.ai.da.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@ApiModel +@Data +public class GetNotificationVO extends PageQueryBaseVo{ + + @ApiModelProperty("system/like/comment/follow") + private String type; +} \ No newline at end of file diff --git a/src/main/java/com/ai/da/model/vo/NotificationVO.java b/src/main/java/com/ai/da/model/vo/NotificationVO.java new file mode 100644 index 00000000..e6645661 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/NotificationVO.java @@ -0,0 +1,17 @@ +package com.ai.da.model.vo; + +import com.ai.da.mapper.primary.entity.Notification; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class NotificationVO extends Notification { + + private String senderUserName; + + private String senderUserAvatar; + + private String portfolioName; + +} diff --git a/src/main/java/com/ai/da/model/vo/PublishSysNotificationVO.java b/src/main/java/com/ai/da/model/vo/PublishSysNotificationVO.java new file mode 100644 index 00000000..1379aca0 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/PublishSysNotificationVO.java @@ -0,0 +1,19 @@ +package com.ai.da.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("发布系统消息") +public class PublishSysNotificationVO { + + @ApiModelProperty("系统消息标题") + private String title; + + @ApiModelProperty("系统消息内容") + private String content; + + @ApiModelProperty("系统消息 活动链接") + private String link; +} diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index 3dd32bb3..edb5c573 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -3349,6 +3349,7 @@ public class PythonService { } } catch (IOException e) { log.error("promptTranslation 用户输入翻译失败; error message => " + e.getMessage()); + response.close(); throw new RuntimeException(e); } finally { diff --git a/src/main/java/com/ai/da/service/MessageCenterService.java b/src/main/java/com/ai/da/service/MessageCenterService.java new file mode 100644 index 00000000..f4f26f43 --- /dev/null +++ b/src/main/java/com/ai/da/service/MessageCenterService.java @@ -0,0 +1,26 @@ +package com.ai.da.service; + +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.mapper.primary.entity.Notification; +import com.ai.da.model.vo.GetNotificationVO; +import com.ai.da.model.vo.NotificationVO; +import com.ai.da.model.vo.PublishSysNotificationVO; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; +import java.util.Map; + +public interface MessageCenterService extends IService { + + Map getAllTypeMessageUnreadCount(); + + PageBaseResponse getHistoryNotification(GetNotificationVO getNotificationVO); + + void prePushMessage(Notification notification); + + void cancelPushMessage(String type, Long senderId, Long receiverId, Long portfolioId, Long commentId); + + Boolean setReadStatus(List notificationIdList, String type); + + void publishSystemNotification(PublishSysNotificationVO message); +} diff --git a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java index 3d102279..829ce33c 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -1024,7 +1024,7 @@ public class AccountServiceImpl extends ServiceImpl impl account.setIsTrial(1); account.setIsBeginner(1); account.setCreateDate(new Date()); - account.setCredits(BigDecimal.valueOf(500)); + account.setCredits(BigDecimal.valueOf(100)); accountMapper.insert(account); AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); response.setEmail(account.getUserEmail()); diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index 46e68d41..95f17e90 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -744,7 +744,7 @@ public class GenerateServiceImpl extends ServiceImpl i redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1)); - if (!status.equals("Invalid")){ + if (!status.equals("Invalid")) { // 4、扣除积分 Boolean b = creditsService.taskCreditsDeduction(accountId, taskId); // 3、记录积分变更 diff --git a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java new file mode 100644 index 00000000..114ac00c --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java @@ -0,0 +1,243 @@ +package com.ai.da.service.impl; + +import com.ai.da.common.constant.CommonConstant; +import com.ai.da.common.context.UserContext; +import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.common.utils.CopyUtil; +import com.ai.da.common.utils.MinioUtil; +import com.ai.da.common.websocket.NotificationConnection; +import com.ai.da.mapper.primary.NotificationMapper; +import com.ai.da.mapper.primary.SysNotificationReadStatusMapper; +import com.ai.da.mapper.primary.entity.Account; +import com.ai.da.mapper.primary.entity.Notification; +import com.ai.da.mapper.primary.entity.SysNotificationReadStatus; +import com.ai.da.model.vo.GetNotificationVO; +import com.ai.da.model.vo.NotificationVO; +import com.ai.da.model.vo.PublishSysNotificationVO; +import com.ai.da.service.AccountService; +import com.ai.da.service.MessageCenterService; +import com.ai.da.service.PortfolioService; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +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.google.gson.Gson; +import com.mysql.cj.util.StringUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + + +@Service +@Slf4j +public class MessageCenterServiceImpl extends ServiceImpl implements MessageCenterService { + + @Resource + private NotificationConnection notificationConnection; + @Resource + private SysNotificationReadStatusMapper sysNotificationReadStatusMapper; + @Resource + private AccountService accountService; + @Resource + private MinioUtil minioUtil; + @Resource + private PortfolioService portfolioService; + + + @Override + public Map getAllTypeMessageUnreadCount() { + List> typeCount = baseMapper.getTypeCount(UserContext.getUserHolder().getId()); + Map msgTypeCount = typeCount.stream() + .collect(Collectors.toMap( + map -> (String) map.get("type"), + map -> Objects.isNull(map.get("count")) ? 0L : (Long) map.get("count"))); + msgTypeCount.put("system", getUnreadSystemNotification()); + log.info(msgTypeCount.toString()); + // 整理数据 加上系统消息未读数 + return msgTypeCount; + } + + + // 获取历史消息 可指定消息类型 分页查询 + @Override + public PageBaseResponse getHistoryNotification(GetNotificationVO getNotificationVO) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (!StringUtils.isNullOrEmpty(getNotificationVO.getType())) { + queryWrapper.eq("type", getNotificationVO.getType()); + } + queryWrapper.eq("receiver_id", UserContext.getUserHolder().getId()); + Page notificationPage = baseMapper.selectPage(new Page<>(getNotificationVO.getPage(), getNotificationVO.getSize()), queryWrapper); + IPage convert = notificationPage.convert(o -> { + NotificationVO notificationVO = CopyUtil.copyObject(o, NotificationVO.class); + Account account = accountService.getById(notificationVO.getSenderId()); + notificationVO.setSenderUserName(account.getUserName()); + notificationVO.setSenderUserAvatar(StringUtils.isNullOrEmpty(account.getAvatar()) ? null : minioUtil.getPreSignedUrl(account.getAvatar(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + notificationVO.setPortfolioName(portfolioService.getById(notificationVO.getPortfolioId()).getPortfolioName()); + return notificationVO; + }); + + return PageBaseResponse.success(convert); + } + + public void prePushMessage(Notification notification){ + // 先判断点赞、关注记录是不是唯一 + if (!getUniqueLikeAndFollow(notification)){ + // 1、将数据存数据库 + if (!notification.getType().equals("system")) { + notification.setIsRead(0); + } + notification.setIsDeleted(0); + notification.setCreateTime(LocalDateTime.now()); + save(notification); + } + // 推送消息 + pushMessage(notification.getType(), notification.getSenderId()); + } + + + /** + * 只记录唯一点赞和关注 + * 重复点赞、关注只会记录最新的一次操作 + * @param notification + * @return + */ + public Boolean getUniqueLikeAndFollow(Notification notification){ + Notification existNotification= null; + // 对单个作品的点赞和对某个人的关注 具有唯一性 + if (notification.getType().equals("like") || notification.getType().equals("follow")){ + existNotification = baseMapper.getUniqueLikeAndFollow(notification.getType(), notification.getSenderId(), + notification.getReceiverId(), notification.getPortfolioId()); + } + + if (!Objects.isNull(existNotification)){ + // 有记录,则更新 1、删除状态 为0 2、已读状态 为0 3、创建时间 为最新时间 4、更新时间 为最新时间 + baseMapper.updateUniqueLikeAndFollow(existNotification.getId(), LocalDateTime.now()); + return Boolean.TRUE; + } + + return Boolean.FALSE; + } + + + // 消息推送 只需要返回当前操作类型和该操作未读消息数量 + public void pushMessage(String type, Long senderId) { + // 推送消息到前端 + ArrayList> resp = new ArrayList<>(); + HashMap data = new HashMap<>(); + Long count; + if (!type.equals("system")) { + // 个人未读消息 + count = getUnreadCountByType(type, senderId); + } else { + // 系统未读消息 + count = getUnreadSystemNotification(); + } + + data.put(type, count); + resp.add(data); + String jsonString = JSON.toJSONString(resp); + log.info("消息推送 : {}", jsonString); + + try { + notificationConnection.sendMsg(jsonString); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // 取消点赞、删除评论、取消关注 + public void cancelPushMessage(String type, Long senderId, Long receiverId, Long portfolioId, Long commentId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("type", type) + .eq("sender_id", senderId) + .eq("receiver_id", receiverId) + .eq("is_deleted", 0); + + if (!type.equals("follow")){ + queryWrapper.eq("portfolio_id", portfolioId); + } + if (type.equals("comment")) { + queryWrapper.eq("comment_id", commentId); + } + Notification notification = baseMapper.selectOne(queryWrapper); + if (!Objects.isNull(notification)) { + baseMapper.deleteNotification(notification.getId(), LocalDateTime.now()); + } + // 推送消息 + pushMessage(type, senderId); + } + + // 获取个人指定消息类型未读消息数量 + private Long getUnreadCountByType(String type, Long receiverId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("type", type) + .eq("is_read", 0) + .eq("receiver_id", receiverId); + + return baseMapper.selectCount(queryWrapper); + } + + private Long getUnreadSystemNotification() { + // 计算总的系统通知数量 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("type", "system"); + Long totalSysCount = baseMapper.selectCount(queryWrapper); + + // 计算单个用户读了多少条系统数据 + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("account_id", UserContext.getUserHolder().getId()); + Long readCount = sysNotificationReadStatusMapper.selectCount(wrapper); + + // 计算差 + return totalSysCount - readCount; + } + + // 设置个人消息的已读状态 (允许一次已读多条个人消息) + public Boolean setReadStatus(List notificationIdList, String type) { + + if (type.equals("system")) { + setReadStatusSystem(notificationIdList); + } else { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.in("id", notificationIdList) +// .eq("type", type) + .set("is_read", 1) + .set("update_time", LocalDateTime.now()); + + baseMapper.update(null, updateWrapper); + } + return Boolean.TRUE; + + } + + // 设置系统消息的已读状态 (允许一次已读多条系统消息) + public void setReadStatusSystem(List notificationIdList) { + Long id = UserContext.getUserHolder().getId(); + for (Long notificationId : notificationIdList) { + SysNotificationReadStatus sysNotificationReadStatus = new SysNotificationReadStatus(notificationId, id); + sysNotificationReadStatus.setCreateTime(LocalDateTime.now()); + sysNotificationReadStatusMapper.insert(sysNotificationReadStatus); + } + } + + // todo 全部已读 + + // 发布系统消息 + public void publishSystemNotification(PublishSysNotificationVO message) { + Notification notification = new Notification(); + notification.setType("system"); + notification.setSenderId(UserContext.getUserHolder().getId()); + notification.setContent(new Gson().toJson(message)); + // todo 是否需要定时发送系统通知 + prePushMessage(notification); + } + + +} diff --git a/src/main/java/com/ai/da/service/impl/PortfolioServiceImpl.java b/src/main/java/com/ai/da/service/impl/PortfolioServiceImpl.java index a002c37d..5ca97162 100644 --- a/src/main/java/com/ai/da/service/impl/PortfolioServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/PortfolioServiceImpl.java @@ -25,7 +25,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; -import sun.security.krb5.internal.crypto.Des; import javax.annotation.Resource; import java.math.BigDecimal; @@ -795,10 +794,16 @@ public class PortfolioServiceImpl extends ServiceImpl + + + + + + + + + UPDATE `t_notification` + SET + is_read = 0, + create_time = #{time}, + update_time = #{time}, + is_deleted = 0 + WHERE id = #{id} + + + + UPDATE `t_notification` + SET + update_time = #{time}, + is_deleted = 1 + WHERE id = #{id} + + + From ac28ba233c55074c03ca2304b457707359a0bd41 Mon Sep 17 00:00:00 2001 From: xupei Date: Fri, 16 Aug 2024 10:32:15 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E6=B6=88=E6=81=AF=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F-=E4=B8=80=E9=94=AE=E5=B7=B2=E8=AF=BB?= =?UTF-8?q?=EF=BC=9B=E5=8F=8D=E5=A4=8D=E7=82=B9=E8=B5=9E=E3=80=81=E5=85=B3?= =?UTF-8?q?=E6=B3=A8=E5=8F=8A=E5=8F=96=E6=B6=88=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=A4=84=E7=90=86=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MessageCenterController.java | 7 ++++++ .../da/mapper/primary/NotificationMapper.java | 4 ++++ .../ai/da/service/MessageCenterService.java | 2 ++ .../impl/MessageCenterServiceImpl.java | 22 ++++++++++++++---- .../mapper/primary/NotificationMapper.xml | 23 +++++++++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/ai/da/controller/MessageCenterController.java b/src/main/java/com/ai/da/controller/MessageCenterController.java index 385c7557..66bb764c 100644 --- a/src/main/java/com/ai/da/controller/MessageCenterController.java +++ b/src/main/java/com/ai/da/controller/MessageCenterController.java @@ -53,4 +53,11 @@ public class MessageCenterController { messageCenterService.publishSystemNotification(message); return Response.success("success"); } + + @ApiOperation(value = "一键已读") + @PostMapping("/oneClickRead") + public Response setReadAll(@RequestParam("type") String type) { + messageCenterService.setReadAll(type); + return Response.success("success"); + } } diff --git a/src/main/java/com/ai/da/mapper/primary/NotificationMapper.java b/src/main/java/com/ai/da/mapper/primary/NotificationMapper.java index 54427ace..bdce12a3 100644 --- a/src/main/java/com/ai/da/mapper/primary/NotificationMapper.java +++ b/src/main/java/com/ai/da/mapper/primary/NotificationMapper.java @@ -17,4 +17,8 @@ public interface NotificationMapper extends CommonMapper { void updateUniqueLikeAndFollow(Long id, LocalDateTime time); void deleteNotification(Long id, LocalDateTime time); + + void setPersonalNotificationAllRead(String type, Long receiverId, LocalDateTime time); + + List getUnreadSysNotification(Long accountId); } diff --git a/src/main/java/com/ai/da/service/MessageCenterService.java b/src/main/java/com/ai/da/service/MessageCenterService.java index f4f26f43..35930a5a 100644 --- a/src/main/java/com/ai/da/service/MessageCenterService.java +++ b/src/main/java/com/ai/da/service/MessageCenterService.java @@ -22,5 +22,7 @@ public interface MessageCenterService extends IService { Boolean setReadStatus(List notificationIdList, String type); + void setReadAll(String type); + void publishSystemNotification(PublishSysNotificationVO message); } diff --git a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java index 114ac00c..02c69ff8 100644 --- a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java @@ -64,7 +64,6 @@ public class MessageCenterServiceImpl extends ServiceImpl getHistoryNotification(GetNotificationVO getNotificationVO) { @@ -127,14 +126,14 @@ public class MessageCenterServiceImpl extends ServiceImpl> resp = new ArrayList<>(); HashMap data = new HashMap<>(); Long count; if (!type.equals("system")) { // 个人未读消息 - count = getUnreadCountByType(type, senderId); + count = getUnreadCountByType(type, receiverId); } else { // 系统未读消息 count = getUnreadSystemNotification(); @@ -227,7 +226,22 @@ public class MessageCenterServiceImpl extends ServiceImpl unreadSysNotificationIds = baseMapper.getUnreadSysNotification(accountId); + // 2、将未读的设为已读 + if (!unreadSysNotificationIds.isEmpty()) setReadStatusSystem(unreadSysNotificationIds); + } + pushMessage(type, accountId); + } // 发布系统消息 public void publishSystemNotification(PublishSysNotificationVO message) { diff --git a/src/main/resources/mapper/primary/NotificationMapper.xml b/src/main/resources/mapper/primary/NotificationMapper.xml index d6bc65e9..eaedaaa5 100644 --- a/src/main/resources/mapper/primary/NotificationMapper.xml +++ b/src/main/resources/mapper/primary/NotificationMapper.xml @@ -40,4 +40,27 @@ WHERE id = #{id} + + update `t_notification` + SET + is_read = 1, + update_time = #{time} + WHERE type = #{type} + AND receiver_id = #{receiverId} + AND is_read = 0 + AND is_deleted = 0 + + + + + From fa86a2af45a1ee3685c52aa39c6f5fc998787b78 Mon Sep 17 00:00:00 2001 From: xupei Date: Mon, 19 Aug 2024 11:52:53 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=B3=E6=B3=A8?= =?UTF-8?q?=E3=80=81=E5=8F=96=E6=B6=88=E5=85=B3=E6=B3=A8=E3=80=81=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=85=B3=E6=B3=A8=E5=88=97=E8=A1=A8=E3=80=81=E7=B2=89?= =?UTF-8?q?=E4=B8=9D=E5=88=97=E8=A1=A8=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/da/controller/PortfolioController.java | 35 ++++- .../da/mapper/primary/UserFollowMapper.java | 9 ++ .../mapper/primary/entity/Notification.java | 6 + .../da/mapper/primary/entity/UserFollow.java | 26 ++++ .../java/com/ai/da/model/vo/PortfolioVO.java | 2 + .../com/ai/da/service/PortfolioService.java | 12 ++ .../impl/MessageCenterServiceImpl.java | 22 ++- .../da/service/impl/PortfolioServiceImpl.java | 129 ++++++++++++++---- src/main/resources/messages_en.properties | 5 + src/main/resources/messages_zh.properties | 5 + 10 files changed, 217 insertions(+), 34 deletions(-) create mode 100644 src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java create mode 100644 src/main/java/com/ai/da/mapper/primary/entity/UserFollow.java diff --git a/src/main/java/com/ai/da/controller/PortfolioController.java b/src/main/java/com/ai/da/controller/PortfolioController.java index 09e8bd39..c69c7485 100644 --- a/src/main/java/com/ai/da/controller/PortfolioController.java +++ b/src/main/java/com/ai/da/controller/PortfolioController.java @@ -1,12 +1,11 @@ package com.ai.da.controller; +import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.Response; +import com.ai.da.mapper.primary.entity.Account; import com.ai.da.model.dto.*; -import com.ai.da.model.vo.CommentVO; -import com.ai.da.model.vo.PortfolioVO; -import com.ai.da.model.vo.UserLikeChooseVO; -import com.ai.da.model.vo.UserLikeGroupVO; +import com.ai.da.model.vo.*; import com.ai.da.service.PortfolioService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -16,6 +15,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.List; @Api(tags = "Portfolio模块") @Slf4j @@ -117,4 +117,31 @@ public class PortfolioController { public Response commentDelete(@Valid @RequestBody CommentDTO commentDTO) { return Response.success(portfolioService.commentDelete(commentDTO)); } + + @ApiOperation(value = "关注") + @GetMapping("/follow") + public Response follow(@RequestParam("followeeId") Long followeeId) { + portfolioService.follow(followeeId); + return Response.success(BusinessException.getMessageFromResource("subscription.success")); + } + + @ApiOperation(value = "取消关注") + @GetMapping("/cancelFollow") + public Response cancelFollow(@RequestParam("followeeId") Long followeeId) { + portfolioService.cancelFollow(followeeId); + return Response.success(BusinessException.getMessageFromResource("unsubscribe.success")); + } + + @ApiOperation(value = "获取关注列表") + @PostMapping("/getFolloweeList") + public Response> getFolloweeList(@Valid @RequestBody PageQueryBaseVo pageQueryBaseVo) { + return Response.success(portfolioService.getFolloweeList(pageQueryBaseVo)); + } + + @ApiOperation(value = "获取粉丝列表") + @PostMapping("/getFollowerList") + public Response> getFollowerList(@Valid @RequestBody PageQueryBaseVo pageQueryBaseVo) { + return Response.success(portfolioService.getFollowerList(pageQueryBaseVo)); + } + } diff --git a/src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java b/src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java new file mode 100644 index 00000000..77e2b6d8 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java @@ -0,0 +1,9 @@ +package com.ai.da.mapper.primary; + +import com.ai.da.common.config.mybatis.plus.CommonMapper; +import com.ai.da.mapper.primary.entity.UserFollow; + + +public interface UserFollowMapper extends CommonMapper { + +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Notification.java b/src/main/java/com/ai/da/mapper/primary/entity/Notification.java index 2e743a8f..12242ad3 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/Notification.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/Notification.java @@ -49,6 +49,12 @@ public class Notification extends BaseEntity{ public Notification() { } + public Notification(String type, Long senderId, Long receiverId) { + this.type = type; + this.senderId = senderId; + this.receiverId = receiverId; + } + public Notification(String type, Long senderId, Long receiverId, Long portfolioId) { this.type = type; this.senderId = senderId; diff --git a/src/main/java/com/ai/da/mapper/primary/entity/UserFollow.java b/src/main/java/com/ai/da/mapper/primary/entity/UserFollow.java new file mode 100644 index 00000000..82e7a810 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/UserFollow.java @@ -0,0 +1,26 @@ +package com.ai.da.mapper.primary.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@TableName("t_user_follow") +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserFollow extends BaseEntity{ + + /** + * 被关注者用户id + */ + private Long followeeId; + /** + * 关注者用户id + */ + private Long followerId; + + +} diff --git a/src/main/java/com/ai/da/model/vo/PortfolioVO.java b/src/main/java/com/ai/da/model/vo/PortfolioVO.java index c7c0a088..ee37c350 100644 --- a/src/main/java/com/ai/da/model/vo/PortfolioVO.java +++ b/src/main/java/com/ai/da/model/vo/PortfolioVO.java @@ -28,4 +28,6 @@ public class PortfolioVO extends Portfolio { private Integer selected; private Integer jumpable; + + private Integer isFollow; } diff --git a/src/main/java/com/ai/da/service/PortfolioService.java b/src/main/java/com/ai/da/service/PortfolioService.java index b809857c..00da09d7 100644 --- a/src/main/java/com/ai/da/service/PortfolioService.java +++ b/src/main/java/com/ai/da/service/PortfolioService.java @@ -1,14 +1,18 @@ package com.ai.da.service; import com.ai.da.common.response.PageBaseResponse; +import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Portfolio; import com.ai.da.model.dto.*; import com.ai.da.model.vo.CommentVO; +import com.ai.da.model.vo.PageQueryBaseVo; import com.ai.da.model.vo.PortfolioVO; import com.ai.da.model.vo.UserLikeChooseVO; import com.baomidou.mybatisplus.extension.service.IService; import org.springframework.web.multipart.MultipartFile; +import java.util.List; + public interface PortfolioService extends IService { Boolean publish(MultipartFile canvas, String data); @@ -41,4 +45,12 @@ public interface PortfolioService extends IService { Boolean delete(Long id); Portfolio getByIdAll(Long originalPortfolioId); + + void follow(Long followeeId); + + void cancelFollow(Long followeeId); + + List getFolloweeList(PageQueryBaseVo pageQueryBaseVo); + + List getFollowerList(PageQueryBaseVo pageQueryBaseVo); } diff --git a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java index 02c69ff8..cf7bb758 100644 --- a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java @@ -67,21 +67,33 @@ public class MessageCenterServiceImpl extends ServiceImpl getHistoryNotification(GetNotificationVO getNotificationVO) { + Long accountId = UserContext.getUserHolder().getId(); QueryWrapper queryWrapper = new QueryWrapper<>(); if (!StringUtils.isNullOrEmpty(getNotificationVO.getType())) { queryWrapper.eq("type", getNotificationVO.getType()); } - queryWrapper.eq("receiver_id", UserContext.getUserHolder().getId()); + if (!getNotificationVO.getType().equals("system")){ + queryWrapper.eq("receiver_id", accountId); + } Page notificationPage = baseMapper.selectPage(new Page<>(getNotificationVO.getPage(), getNotificationVO.getSize()), queryWrapper); + + List unreadSysNotificationIds = baseMapper.getUnreadSysNotification(accountId); IPage convert = notificationPage.convert(o -> { NotificationVO notificationVO = CopyUtil.copyObject(o, NotificationVO.class); Account account = accountService.getById(notificationVO.getSenderId()); notificationVO.setSenderUserName(account.getUserName()); notificationVO.setSenderUserAvatar(StringUtils.isNullOrEmpty(account.getAvatar()) ? null : minioUtil.getPreSignedUrl(account.getAvatar(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - notificationVO.setPortfolioName(portfolioService.getById(notificationVO.getPortfolioId()).getPortfolioName()); + notificationVO.setPortfolioName(Objects.isNull(notificationVO.getPortfolioId()) ? null : portfolioService.getById(notificationVO.getPortfolioId()).getPortfolioName()); + // 设置单个人 系统消息是否已读 + if (notificationVO.getType().equals("system")){ + if (unreadSysNotificationIds.contains(notificationVO.getId())){ + notificationVO.setIsRead(0); + }else { + notificationVO.setIsRead(1); + } + } return notificationVO; }); - return PageBaseResponse.success(convert); } @@ -195,7 +207,7 @@ public class MessageCenterServiceImpl extends ServiceImpl 0 ? totalSysCount - readCount : 0; } // 设置个人消息的已读状态 (允许一次已读多条个人消息) @@ -212,8 +224,8 @@ public class MessageCenterServiceImpl extends ServiceImpl implements PortfolioService { @@ -59,8 +60,8 @@ public class PortfolioServiceImpl extends ServiceImpl likedPortfolioIdList = redisUtil.getLikedPortfolios(userHolder.getId()); if (!CollectionUtils.isEmpty(likedPortfolioIdList)) { qw.lambda().in(Portfolio::getId, likedPortfolioIdList); - }else { + } else { return PageBaseResponse.success(new Page<>()); } } qw.lambda().orderByDesc(Portfolio::getUpdateDate); - IPage page = portfolioMapper.selectPage(new Page<>(query.getPage(), query.getSize()),qw); + IPage page = portfolioMapper.selectPage(new Page<>(query.getPage(), query.getSize()), qw); IPage convert = page.convert((Function) portfolio -> { if (portfolio != null) { PortfolioVO vo = CopyUtil.copyObject(portfolio, PortfolioVO.class); @@ -480,13 +483,23 @@ public class PortfolioServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("followee_id", portfolio.getAccountId()).eq("follower_id", userHolder.getId()); + UserFollow userFollow = userFollowMapper.selectOne(queryWrapper); + if (Objects.isNull(userFollow)){ + vo.setIsFollow(0); + }else { + vo.setIsFollow(1); + } } redisUtil.increaseViewCount(portfolioDTO.getId()); vo.setViewNums(redisUtil.getViewCount(portfolioDTO.getId())); @@ -499,7 +512,7 @@ public class PortfolioServiceImpl extends ServiceImpl getSelectedQw = new QueryWrapper<>(); getSelectedQw.lambda().eq(UserLikeGroup::getAccountId, userHolder.getId()); @@ -519,7 +532,7 @@ public class PortfolioServiceImpl extends ServiceImpl userLikeGroups = userLikeGroupMapper.selectList(getSelectedQw); if (CollectionUtils.isEmpty(userLikeGroups)) { vo.setSelected(0); - }else { + } else { vo.setSelected(1); } } @@ -546,12 +559,12 @@ public class PortfolioServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("followee_id", followeeId).eq("follower_id", accountId); + UserFollow userFollow = userFollowMapper.selectOne(queryWrapper); + if (!Objects.isNull(userFollow)) { + throw new BusinessException("you.have.already.followed.this.user", 1); + } + // 3、添加新follower到关注列表 + UserFollow newFollower = new UserFollow(followeeId, accountId); + newFollower.setCreateTime(LocalDateTime.now()); + userFollowMapper.insert(newFollower); + // 4、推送消息 + messageCenterService.prePushMessage(new Notification("follow", accountId, followeeId)); + } + + // 取消关注 + public void cancelFollow(Long followeeId){ + Long accountId = UserContext.getUserHolder().getId(); + // 1、确定是否关注了该用户 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("followee_id", followeeId).eq("follower_id", accountId); + UserFollow userFollow = userFollowMapper.selectOne(queryWrapper); + // 2、删除关注记录 + if (!Objects.isNull(userFollow)) { + userFollowMapper.deleteById(userFollow.getId()); + // 3、逻辑删除关注消息 + messageCenterService.cancelPushMessage("follow", accountId, followeeId, null, null); + }else { + throw new BusinessException("you.have.not.followed.the.current.user", 1); + } + } + + // 获取某个用户的关注列表 + public List getFolloweeList(PageQueryBaseVo pageQueryBaseVo){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("follower_id", UserContext.getUserHolder().getId()).select("followee_id"); + Page followPage = userFollowMapper.selectPage(new Page<>(pageQueryBaseVo.getPage(), pageQueryBaseVo.getSize()), queryWrapper); + + if (!followPage.getRecords().isEmpty()){ + List followeeIds = followPage.getRecords().stream().map(UserFollow::getFolloweeId).collect(Collectors.toList()); + return accountMapper.selectBatchIds(followeeIds); + } + return new ArrayList<>(); + } + + // 获取某个用户的粉丝列表 + public List getFollowerList(PageQueryBaseVo pageQueryBaseVo){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("followee_id", UserContext.getUserHolder().getId()).select("follower_id"); + Page followPage = userFollowMapper.selectPage(new Page<>(pageQueryBaseVo.getPage(), pageQueryBaseVo.getSize()), queryWrapper); + + if (!followPage.getRecords().isEmpty()){ + List followerIds = followPage.getRecords().stream().map(UserFollow::getFollowerId).collect(Collectors.toList()); + return accountMapper.selectBatchIds(followerIds); + } + return new ArrayList<>(); + } + } diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index aa36fa05..3e1f25ca 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -139,6 +139,11 @@ slogan.style.cannot.be.empty=Slogan style text cannot be empty. slogan.image.cannot.be.empty=Slogan image cannot be empty. questionnaire.filled.out=You have filled out the current questionnaire. user.has.no.account=The current user has no account! +you.cannot.follow.yourself=You cannot follow yourself +you.have.already.followed.this.user=You have already followed this user +subscription.success=Subscription Success +unsubscribe.success=Unsubscribe Success +you.have.not.followed.the.current.user=You have not followed the current user # 可能会报异常 # Informative: diff --git a/src/main/resources/messages_zh.properties b/src/main/resources/messages_zh.properties index e4bbeb87..043c8106 100644 --- a/src/main/resources/messages_zh.properties +++ b/src/main/resources/messages_zh.properties @@ -134,6 +134,11 @@ slogan.style.cannot.be.empty=标语风格文本不能为空。 slogan.image.cannot.be.empty=标语图片不能为空。 questionnaire.filled.out=您已填写过当前问卷。 user.has.no.account=当前用户没有账号。 +you.cannot.follow.yourself=您不能关注您自己 +you.have.already.followed.this.user=您已经关注当前用户 +subscription.success=关注成功 +unsubscribe.success=取消关注成功 +you.have.not.followed.the.current.user=您还未关注当前用户 # 可能会报异常 # Informative: From 203c88dd70c55b00d80eec7d456d24df1f6d3829 Mon Sep 17 00:00:00 2001 From: xupei Date: Mon, 19 Aug 2024 15:10:41 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=B4=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/da/common/constant/CommonConstant.java | 2 + .../ai/da/controller/AccountController.java | 14 ++++++- .../com/ai/da/model/vo/AccountLoginVO.java | 6 +++ .../com/ai/da/model/vo/NotificationVO.java | 2 + .../java/com/ai/da/model/vo/PortfolioVO.java | 2 + .../com/ai/da/service/AccountService.java | 3 ++ .../com/ai/da/service/PortfolioService.java | 4 ++ .../da/service/impl/AccountServiceImpl.java | 37 +++++++++++++++++++ .../impl/MessageCenterServiceImpl.java | 10 +++-- .../da/service/impl/PortfolioServiceImpl.java | 21 ++++++++++- .../mapper/primary/NotificationMapper.xml | 1 + 11 files changed, 97 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/ai/da/common/constant/CommonConstant.java b/src/main/java/com/ai/da/common/constant/CommonConstant.java index 15372e9b..3f29a938 100644 --- a/src/main/java/com/ai/da/common/constant/CommonConstant.java +++ b/src/main/java/com/ai/da/common/constant/CommonConstant.java @@ -59,4 +59,6 @@ public class CommonConstant { public static final List IS_SUBSCRIBE = Arrays.asList("yes", "no"); + public static final String DEFAULT_AVATAR = "aida-users/87/avatar/default.jpg"; + } diff --git a/src/main/java/com/ai/da/controller/AccountController.java b/src/main/java/com/ai/da/controller/AccountController.java index 4dadaf3d..4579ae15 100644 --- a/src/main/java/com/ai/da/controller/AccountController.java +++ b/src/main/java/com/ai/da/controller/AccountController.java @@ -1,8 +1,8 @@ package com.ai.da.controller; +import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.Response; -import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.model.dto.*; import com.ai.da.model.vo.AccountLoginVO; @@ -12,7 +12,9 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -194,4 +196,14 @@ public class AccountController { public Response> setUserValidToDayEnd(){ return Response.success(accountService.setUserValidToDayEnd()); } + + // 用户上传头像 + @ApiOperation(value = "上传头像") + @PostMapping(path = "/uploadAvatar"/*, consumes = MediaType.MULTIPART_FORM_DATA_VALUE*/) + public Response uploadAvatar(@RequestParam("file") MultipartFile file) { + if (null == file || StringUtils.isEmpty(file.getOriginalFilename())) { + throw new BusinessException("file.cannot.be.empty"); + } + return Response.success(accountService.uploadAvatar(file)); + } } diff --git a/src/main/java/com/ai/da/model/vo/AccountLoginVO.java b/src/main/java/com/ai/da/model/vo/AccountLoginVO.java index 15b28c89..ab23b872 100644 --- a/src/main/java/com/ai/da/model/vo/AccountLoginVO.java +++ b/src/main/java/com/ai/da/model/vo/AccountLoginVO.java @@ -34,4 +34,10 @@ public class AccountLoginVO { private Integer systemUser; + private String avatar; + + private Long followeeCount; + + private Long followerCount; + } diff --git a/src/main/java/com/ai/da/model/vo/NotificationVO.java b/src/main/java/com/ai/da/model/vo/NotificationVO.java index e6645661..823d53f2 100644 --- a/src/main/java/com/ai/da/model/vo/NotificationVO.java +++ b/src/main/java/com/ai/da/model/vo/NotificationVO.java @@ -14,4 +14,6 @@ public class NotificationVO extends Notification { private String portfolioName; + private String senderAvatar; + } diff --git a/src/main/java/com/ai/da/model/vo/PortfolioVO.java b/src/main/java/com/ai/da/model/vo/PortfolioVO.java index ee37c350..a7610898 100644 --- a/src/main/java/com/ai/da/model/vo/PortfolioVO.java +++ b/src/main/java/com/ai/da/model/vo/PortfolioVO.java @@ -30,4 +30,6 @@ public class PortfolioVO extends Portfolio { private Integer jumpable; private Integer isFollow; + + private String avatar; } diff --git a/src/main/java/com/ai/da/service/AccountService.java b/src/main/java/com/ai/da/service/AccountService.java index a6a39011..0450042e 100644 --- a/src/main/java/com/ai/da/service/AccountService.java +++ b/src/main/java/com/ai/da/service/AccountService.java @@ -7,6 +7,7 @@ import com.ai.da.model.vo.AccountLoginVO; import com.ai.da.model.vo.AccountPreLoginVO; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.util.List; @@ -157,4 +158,6 @@ public interface AccountService extends IService { IPage getPageByIds(List ids, int pageNum, int size); List getByIds(List ids); + + String uploadAvatar(MultipartFile file); } diff --git a/src/main/java/com/ai/da/service/PortfolioService.java b/src/main/java/com/ai/da/service/PortfolioService.java index 00da09d7..f9a47ff6 100644 --- a/src/main/java/com/ai/da/service/PortfolioService.java +++ b/src/main/java/com/ai/da/service/PortfolioService.java @@ -50,7 +50,11 @@ public interface PortfolioService extends IService { void cancelFollow(Long followeeId); + Long getFolloweeCount(); + List getFolloweeList(PageQueryBaseVo pageQueryBaseVo); + Long getFollowerCount(); + List getFollowerList(PageQueryBaseVo pageQueryBaseVo); } diff --git a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java index 829ce33c..01b903e4 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -2,6 +2,7 @@ package com.ai.da.service.impl; import cn.hutool.core.collection.CollectionUtil; import com.ai.da.common.config.exception.BusinessException; +import com.ai.da.common.constant.CommonConstant; import com.ai.da.common.context.UserContext; import com.ai.da.common.enums.AuthenticationOperationTypeEnum; import com.ai.da.common.enums.CreditsEventsEnum; @@ -32,9 +33,11 @@ import com.zaxxer.hikari.HikariDataSource; import io.netty.util.internal.StringUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -83,6 +86,11 @@ public class AccountServiceImpl extends ServiceImpl impl @Resource private CreditsService creditsService; + @Resource + private MinioUtil minioUtil; + @Value("${minio.bucketName.users}") + private String userBucket; + @Override @Transactional(rollbackFor = Exception.class) public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) { @@ -137,6 +145,9 @@ public class AccountServiceImpl extends ServiceImpl impl return new AccountPreLoginVO(account.getId()); } + @Resource + private PortfolioService portfolioService; + @Transactional(rollbackFor = Exception.class) @Override public AccountLoginVO login(AccountLoginDTO accountLoginDTO, HttpServletRequest request) { @@ -189,6 +200,16 @@ public class AccountServiceImpl extends ServiceImpl impl } response.setUserId(account.getId()); response.setSystemUser(account.getSystemUser()); + // 设置头像 + String avatar; + if (StringUtil.isNullOrEmpty(account.getAvatar())){ + avatar = CommonConstant.DEFAULT_AVATAR; + }else { + avatar = account.getAvatar(); + } + response.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + response.setFolloweeCount(portfolioService.getFolloweeCount()); + response.setFollowerCount(portfolioService.getFollowerCount()); //判断是否常用ip 不是则发邮件提示 calculateExceptionIp(RequestInfoUtil.getIpAddress(request), account); return response; @@ -1421,7 +1442,23 @@ public class AccountServiceImpl extends ServiceImpl impl return baseMapper.selectList(queryWrapper); } + public String uploadAvatar(MultipartFile file){ + Long accountId = UserContext.getUserHolder().getId(); + // 1、上传图片到minio + String avatarPath = minioUtil.upload(userBucket, accountId.toString() + "/avatar", file); + // 2、查询该用户之前的头像 + String avatar = baseMapper.selectById(accountId).getAvatar(); + if (!StringUtil.isNullOrEmpty(avatar) && !avatar.equals(CommonConstant.DEFAULT_AVATAR)){ + minioUtil.deleteObject(avatar); + } + // 3、替换新的头像 + Account account = new Account(); + account.setId(accountId); + account.setAvatar(avatarPath); + baseMapper.updateById(account); + return minioUtil.getPreSignedUrl(avatarPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); + } } diff --git a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java index cf7bb758..2f0ac1d8 100644 --- a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java @@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.gson.Gson; import com.mysql.cj.util.StringUtils; +import io.netty.util.internal.StringUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -80,9 +81,9 @@ public class MessageCenterServiceImpl extends ServiceImpl unreadSysNotificationIds = baseMapper.getUnreadSysNotification(accountId); IPage convert = notificationPage.convert(o -> { NotificationVO notificationVO = CopyUtil.copyObject(o, NotificationVO.class); - Account account = accountService.getById(notificationVO.getSenderId()); - notificationVO.setSenderUserName(account.getUserName()); - notificationVO.setSenderUserAvatar(StringUtils.isNullOrEmpty(account.getAvatar()) ? null : minioUtil.getPreSignedUrl(account.getAvatar(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + Account senderAccount = accountService.getById(notificationVO.getSenderId()); + notificationVO.setSenderUserName(senderAccount.getUserName()); + notificationVO.setSenderUserAvatar(StringUtils.isNullOrEmpty(senderAccount.getAvatar()) ? null : minioUtil.getPreSignedUrl(senderAccount.getAvatar(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); notificationVO.setPortfolioName(Objects.isNull(notificationVO.getPortfolioId()) ? null : portfolioService.getById(notificationVO.getPortfolioId()).getPortfolioName()); // 设置单个人 系统消息是否已读 if (notificationVO.getType().equals("system")){ @@ -91,6 +92,9 @@ public class MessageCenterServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("follower_id", UserContext.getUserHolder().getId()).select("followee_id"); + return userFollowMapper.selectCount(queryWrapper); + } + // 获取某个用户的关注列表 public List getFolloweeList(PageQueryBaseVo pageQueryBaseVo){ QueryWrapper queryWrapper = new QueryWrapper<>(); @@ -1010,6 +1023,12 @@ public class PortfolioServiceImpl extends ServiceImpl(); } + public Long getFollowerCount(){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("followee_id", UserContext.getUserHolder().getId()).select("follower_id"); + return userFollowMapper.selectCount(queryWrapper); + } + // 获取某个用户的粉丝列表 public List getFollowerList(PageQueryBaseVo pageQueryBaseVo){ QueryWrapper queryWrapper = new QueryWrapper<>(); diff --git a/src/main/resources/mapper/primary/NotificationMapper.xml b/src/main/resources/mapper/primary/NotificationMapper.xml index eaedaaa5..27c59370 100644 --- a/src/main/resources/mapper/primary/NotificationMapper.xml +++ b/src/main/resources/mapper/primary/NotificationMapper.xml @@ -7,6 +7,7 @@ FROM `t_notification` WHERE receiver_id = #{receiverId} AND is_read = 0 + AND is_deleted = 0 GROUP BY type From 28df672a7d39af6378d8517e0a20c52fc6458812 Mon Sep 17 00:00:00 2001 From: xupei Date: Wed, 21 Aug 2024 10:23:55 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=85=B3=E6=B3=A8=E3=80=81=E7=B2=89=E4=B8=9D=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ai/da/common/utils/RedisUtil.java | 13 ++ .../ai/da/controller/AccountController.java | 15 ++- .../controller/MessageCenterController.java | 10 +- .../ai/da/controller/PortfolioController.java | 8 +- .../da/mapper/primary/UserFollowMapper.java | 10 ++ .../com/ai/da/model/dto/GetFollowListDTO.java | 19 +++ .../GetNotificationDTO.java} | 5 +- .../PublishSysNotificationDTO.java} | 4 +- .../da/model/dto/QueryPortfolioPageDTO.java | 2 + .../com/ai/da/model/vo/AccountFollowVO.java | 24 ++++ .../com/ai/da/model/vo/NotificationVO.java | 2 + .../ai/da/model/vo/PersonalHomepageVO.java | 31 +++++ .../com/ai/da/service/AccountService.java | 5 + .../ai/da/service/MessageCenterService.java | 8 +- .../com/ai/da/service/PortfolioService.java | 17 +-- .../da/service/impl/AccountServiceImpl.java | 53 ++++++++- .../impl/MessageCenterServiceImpl.java | 16 +-- .../da/service/impl/PortfolioServiceImpl.java | 111 ++++++++++++------ .../mapper/primary/UserFollowMapper.xml | 55 +++++++++ 19 files changed, 334 insertions(+), 74 deletions(-) create mode 100644 src/main/java/com/ai/da/model/dto/GetFollowListDTO.java rename src/main/java/com/ai/da/model/{vo/GetNotificationVO.java => dto/GetNotificationDTO.java} (67%) rename src/main/java/com/ai/da/model/{vo/PublishSysNotificationVO.java => dto/PublishSysNotificationDTO.java} (84%) create mode 100644 src/main/java/com/ai/da/model/vo/AccountFollowVO.java create mode 100644 src/main/java/com/ai/da/model/vo/PersonalHomepageVO.java create mode 100644 src/main/resources/mapper/primary/UserFollowMapper.xml diff --git a/src/main/java/com/ai/da/common/utils/RedisUtil.java b/src/main/java/com/ai/da/common/utils/RedisUtil.java index 0d5c6153..ffb0f424 100644 --- a/src/main/java/com/ai/da/common/utils/RedisUtil.java +++ b/src/main/java/com/ai/da/common/utils/RedisUtil.java @@ -216,4 +216,17 @@ public class RedisUtil { return redisTemplate.opsForValue().increment(key, 0); } + public final static String PERSONAL_HOMEPAGE_VIEW_KEY = "PersonalHomepage:view:"; + + public void increasePersonalHomepageViewCount(Long accountId) { + String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId; + redisTemplate.opsForValue().increment(key); + } + + public Long getPersonalHomepageViewCount(Long accountId) { + String key = PERSONAL_HOMEPAGE_VIEW_KEY + accountId; + return redisTemplate.opsForValue().increment(key, 0); + } + + } diff --git a/src/main/java/com/ai/da/controller/AccountController.java b/src/main/java/com/ai/da/controller/AccountController.java index 4579ae15..8cf6a5a9 100644 --- a/src/main/java/com/ai/da/controller/AccountController.java +++ b/src/main/java/com/ai/da/controller/AccountController.java @@ -7,6 +7,7 @@ import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.model.dto.*; import com.ai.da.model.vo.AccountLoginVO; import com.ai.da.model.vo.AccountPreLoginVO; +import com.ai.da.model.vo.PersonalHomepageVO; import com.ai.da.service.AccountService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -199,11 +200,23 @@ public class AccountController { // 用户上传头像 @ApiOperation(value = "上传头像") - @PostMapping(path = "/uploadAvatar"/*, consumes = MediaType.MULTIPART_FORM_DATA_VALUE*/) + @PostMapping(path = "/uploadAvatar") public Response uploadAvatar(@RequestParam("file") MultipartFile file) { if (null == file || StringUtils.isEmpty(file.getOriginalFilename())) { throw new BusinessException("file.cannot.be.empty"); } return Response.success(accountService.uploadAvatar(file)); } + + @ApiOperation(value = "个人主页浏览量增加") + @GetMapping("/viewsIncrease") + public Response viewsGet(@RequestParam("id") Long id) { + return Response.success(accountService.viewsIncrease(id)); + } + + @ApiOperation(value = "获取个人主页信息") + @GetMapping("/personalHomepage") + public Response getPersonalHomepage(@RequestParam("id") Long id){ + return Response.success(accountService.getPersonalHomepage(id)); + } } diff --git a/src/main/java/com/ai/da/controller/MessageCenterController.java b/src/main/java/com/ai/da/controller/MessageCenterController.java index 66bb764c..3f625cb8 100644 --- a/src/main/java/com/ai/da/controller/MessageCenterController.java +++ b/src/main/java/com/ai/da/controller/MessageCenterController.java @@ -2,9 +2,9 @@ package com.ai.da.controller; import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.Response; -import com.ai.da.model.vo.GetNotificationVO; +import com.ai.da.model.dto.GetNotificationDTO; import com.ai.da.model.vo.NotificationVO; -import com.ai.da.model.vo.PublishSysNotificationVO; +import com.ai.da.model.dto.PublishSysNotificationDTO; import com.ai.da.service.MessageCenterService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -35,8 +35,8 @@ public class MessageCenterController { // 获取历史消息 @ApiOperation(value = "获取历史消息") @PostMapping("/getHistoryNotification") - public Response> getHistoryNotification(@Valid @RequestBody GetNotificationVO getNotificationVO) { - return Response.success(messageCenterService.getHistoryNotification(getNotificationVO)); + public Response> getHistoryNotification(@Valid @RequestBody GetNotificationDTO getNotificationDTO) { + return Response.success(messageCenterService.getHistoryNotification(getNotificationDTO)); } // 已读消息 @@ -49,7 +49,7 @@ public class MessageCenterController { // 发布系统消息 @ApiOperation(value = "发布系统消息") @PostMapping("/publishSysMessage") - public Response publishSysMessage(@Valid @RequestBody PublishSysNotificationVO message) { + public Response publishSysMessage(@Valid @RequestBody PublishSysNotificationDTO message) { messageCenterService.publishSystemNotification(message); return Response.success("success"); } diff --git a/src/main/java/com/ai/da/controller/PortfolioController.java b/src/main/java/com/ai/da/controller/PortfolioController.java index c69c7485..1ad6d81d 100644 --- a/src/main/java/com/ai/da/controller/PortfolioController.java +++ b/src/main/java/com/ai/da/controller/PortfolioController.java @@ -134,14 +134,14 @@ public class PortfolioController { @ApiOperation(value = "获取关注列表") @PostMapping("/getFolloweeList") - public Response> getFolloweeList(@Valid @RequestBody PageQueryBaseVo pageQueryBaseVo) { - return Response.success(portfolioService.getFolloweeList(pageQueryBaseVo)); + public Response> getFolloweeList(@Valid @RequestBody GetFollowListDTO getFollowListDTO) { + return Response.success(portfolioService.getFolloweeList(getFollowListDTO)); } @ApiOperation(value = "获取粉丝列表") @PostMapping("/getFollowerList") - public Response> getFollowerList(@Valid @RequestBody PageQueryBaseVo pageQueryBaseVo) { - return Response.success(portfolioService.getFollowerList(pageQueryBaseVo)); + public Response> getFollowerList(@Valid @RequestBody GetFollowListDTO getFollowListDTO) { + return Response.success(portfolioService.getFollowerList(getFollowListDTO)); } } diff --git a/src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java b/src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java index 77e2b6d8..ff45177c 100644 --- a/src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java +++ b/src/main/java/com/ai/da/mapper/primary/UserFollowMapper.java @@ -2,8 +2,18 @@ package com.ai.da.mapper.primary; import com.ai.da.common.config.mybatis.plus.CommonMapper; import com.ai.da.mapper.primary.entity.UserFollow; +import com.ai.da.model.vo.AccountFollowVO; + +import java.util.List; public interface UserFollowMapper extends CommonMapper { + List getFolloweeListByFollower(Long followerAccountId, Integer limit, Integer offset, String order); + + List getFollowerListByFollowee(Long followeeAccountId, Integer limit, Integer offset, String order); + + List getFolloweeListByName(String name, Long followerId); + + List getFollowerListByName(String name, Long followeeId); } diff --git a/src/main/java/com/ai/da/model/dto/GetFollowListDTO.java b/src/main/java/com/ai/da/model/dto/GetFollowListDTO.java new file mode 100644 index 00000000..c2878ecb --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/GetFollowListDTO.java @@ -0,0 +1,19 @@ +package com.ai.da.model.dto; + +import com.ai.da.model.vo.PageQueryBaseVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +@ApiModel("按条件分页查询关注列表") +public class GetFollowListDTO extends PageQueryBaseVo { + + @ApiModelProperty("查找指定用户名") + private String searchByName; + + @ApiModelProperty("按关注时间排序 DESC 降序 || ASC 升序") + private String order; +} diff --git a/src/main/java/com/ai/da/model/vo/GetNotificationVO.java b/src/main/java/com/ai/da/model/dto/GetNotificationDTO.java similarity index 67% rename from src/main/java/com/ai/da/model/vo/GetNotificationVO.java rename to src/main/java/com/ai/da/model/dto/GetNotificationDTO.java index e241e163..781ffc59 100644 --- a/src/main/java/com/ai/da/model/vo/GetNotificationVO.java +++ b/src/main/java/com/ai/da/model/dto/GetNotificationDTO.java @@ -1,5 +1,6 @@ -package com.ai.da.model.vo; +package com.ai.da.model.dto; +import com.ai.da.model.vo.PageQueryBaseVo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -8,7 +9,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @ApiModel @Data -public class GetNotificationVO extends PageQueryBaseVo{ +public class GetNotificationDTO extends PageQueryBaseVo { @ApiModelProperty("system/like/comment/follow") private String type; diff --git a/src/main/java/com/ai/da/model/vo/PublishSysNotificationVO.java b/src/main/java/com/ai/da/model/dto/PublishSysNotificationDTO.java similarity index 84% rename from src/main/java/com/ai/da/model/vo/PublishSysNotificationVO.java rename to src/main/java/com/ai/da/model/dto/PublishSysNotificationDTO.java index 1379aca0..11a0c56b 100644 --- a/src/main/java/com/ai/da/model/vo/PublishSysNotificationVO.java +++ b/src/main/java/com/ai/da/model/dto/PublishSysNotificationDTO.java @@ -1,4 +1,4 @@ -package com.ai.da.model.vo; +package com.ai.da.model.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -6,7 +6,7 @@ import lombok.Data; @Data @ApiModel("发布系统消息") -public class PublishSysNotificationVO { +public class PublishSysNotificationDTO { @ApiModelProperty("系统消息标题") private String title; diff --git a/src/main/java/com/ai/da/model/dto/QueryPortfolioPageDTO.java b/src/main/java/com/ai/da/model/dto/QueryPortfolioPageDTO.java index 8176ba00..71e2c3d3 100644 --- a/src/main/java/com/ai/da/model/dto/QueryPortfolioPageDTO.java +++ b/src/main/java/com/ai/da/model/dto/QueryPortfolioPageDTO.java @@ -14,4 +14,6 @@ public class QueryPortfolioPageDTO extends PageQueryBaseVo { private Integer getMyPortfolio; private Integer getLikePortfolio; + + private Long accountId; } diff --git a/src/main/java/com/ai/da/model/vo/AccountFollowVO.java b/src/main/java/com/ai/da/model/vo/AccountFollowVO.java new file mode 100644 index 00000000..5680ed76 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/AccountFollowVO.java @@ -0,0 +1,24 @@ +package com.ai.da.model.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AccountFollowVO { + private Long userId; + + private String userName; + + private String avatar; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private LocalDateTime followTime; + + private Integer mutualFollowing; +} diff --git a/src/main/java/com/ai/da/model/vo/NotificationVO.java b/src/main/java/com/ai/da/model/vo/NotificationVO.java index 823d53f2..cd4eaedd 100644 --- a/src/main/java/com/ai/da/model/vo/NotificationVO.java +++ b/src/main/java/com/ai/da/model/vo/NotificationVO.java @@ -16,4 +16,6 @@ public class NotificationVO extends Notification { private String senderAvatar; + private Integer isFollow; + } diff --git a/src/main/java/com/ai/da/model/vo/PersonalHomepageVO.java b/src/main/java/com/ai/da/model/vo/PersonalHomepageVO.java new file mode 100644 index 00000000..b6f0f058 --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/PersonalHomepageVO.java @@ -0,0 +1,31 @@ +package com.ai.da.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("个人主页返回信息") +public class PersonalHomepageVO { + + @ApiModelProperty("用户名") + private String userName; + + @ApiModelProperty("用户头像") + private String avatar; + + @ApiModelProperty("用户作品总数") + private Long portfolioCount; + + @ApiModelProperty("粉丝总数") + private Long followerCount; + + @ApiModelProperty("关注者总数") + private Long followeeCount; + + @ApiModelProperty("个人主页总浏览量") + private Long homepageViewCount; + + @ApiModelProperty("是否关注了主页用户") + private Integer isFollow; +} diff --git a/src/main/java/com/ai/da/service/AccountService.java b/src/main/java/com/ai/da/service/AccountService.java index 0450042e..8d97d549 100644 --- a/src/main/java/com/ai/da/service/AccountService.java +++ b/src/main/java/com/ai/da/service/AccountService.java @@ -5,6 +5,7 @@ import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.model.dto.*; import com.ai.da.model.vo.AccountLoginVO; import com.ai.da.model.vo.AccountPreLoginVO; +import com.ai.da.model.vo.PersonalHomepageVO; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import org.springframework.web.multipart.MultipartFile; @@ -160,4 +161,8 @@ public interface AccountService extends IService { List getByIds(List ids); String uploadAvatar(MultipartFile file); + + PersonalHomepageVO getPersonalHomepage(Long accountId); + + Boolean viewsIncrease(Long id); } diff --git a/src/main/java/com/ai/da/service/MessageCenterService.java b/src/main/java/com/ai/da/service/MessageCenterService.java index 35930a5a..84bb9cd1 100644 --- a/src/main/java/com/ai/da/service/MessageCenterService.java +++ b/src/main/java/com/ai/da/service/MessageCenterService.java @@ -2,9 +2,9 @@ package com.ai.da.service; import com.ai.da.common.response.PageBaseResponse; import com.ai.da.mapper.primary.entity.Notification; -import com.ai.da.model.vo.GetNotificationVO; +import com.ai.da.model.dto.GetNotificationDTO; import com.ai.da.model.vo.NotificationVO; -import com.ai.da.model.vo.PublishSysNotificationVO; +import com.ai.da.model.dto.PublishSysNotificationDTO; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -14,7 +14,7 @@ public interface MessageCenterService extends IService { Map getAllTypeMessageUnreadCount(); - PageBaseResponse getHistoryNotification(GetNotificationVO getNotificationVO); + PageBaseResponse getHistoryNotification(GetNotificationDTO getNotificationDTO); void prePushMessage(Notification notification); @@ -24,5 +24,5 @@ public interface MessageCenterService extends IService { void setReadAll(String type); - void publishSystemNotification(PublishSysNotificationVO message); + void publishSystemNotification(PublishSysNotificationDTO message); } diff --git a/src/main/java/com/ai/da/service/PortfolioService.java b/src/main/java/com/ai/da/service/PortfolioService.java index f9a47ff6..a67b5e4c 100644 --- a/src/main/java/com/ai/da/service/PortfolioService.java +++ b/src/main/java/com/ai/da/service/PortfolioService.java @@ -4,10 +4,7 @@ import com.ai.da.common.response.PageBaseResponse; import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Portfolio; import com.ai.da.model.dto.*; -import com.ai.da.model.vo.CommentVO; -import com.ai.da.model.vo.PageQueryBaseVo; -import com.ai.da.model.vo.PortfolioVO; -import com.ai.da.model.vo.UserLikeChooseVO; +import com.ai.da.model.vo.*; import com.baomidou.mybatisplus.extension.service.IService; import org.springframework.web.multipart.MultipartFile; @@ -50,11 +47,15 @@ public interface PortfolioService extends IService { void cancelFollow(Long followeeId); - Long getFolloweeCount(); + Long getFolloweeCount(Long accountId); - List getFolloweeList(PageQueryBaseVo pageQueryBaseVo); + List getFolloweeList(GetFollowListDTO getFollowListDTO); - Long getFollowerCount(); + Long getFollowerCount(Long accountId); - List getFollowerList(PageQueryBaseVo pageQueryBaseVo); + List getFollowerList(GetFollowListDTO getFollowListDTO); + + Integer getIfFollowed(Long followeeId, Long followerId); + + Long getPortfolioCount(Long accountId); } diff --git a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java index 01b903e4..7b96b3a2 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -17,10 +17,7 @@ import com.ai.da.mapper.primary.entity.*; import com.ai.da.model.dto.*; import com.ai.da.model.enums.AutoApproved; import com.ai.da.model.enums.Language; -import com.ai.da.model.vo.AccountLoginVO; -import com.ai.da.model.vo.AccountPreLoginVO; -import com.ai.da.model.vo.AuthPrincipalVo; -import com.ai.da.model.vo.QuestionnaireVO; +import com.ai.da.model.vo.*; import com.ai.da.service.*; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -88,9 +85,13 @@ public class AccountServiceImpl extends ServiceImpl impl @Resource private MinioUtil minioUtil; + @Value("${minio.bucketName.users}") private String userBucket; + @Resource + private RedisUtil redisUtil; + @Override @Transactional(rollbackFor = Exception.class) public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) { @@ -208,8 +209,8 @@ public class AccountServiceImpl extends ServiceImpl impl avatar = account.getAvatar(); } response.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - response.setFolloweeCount(portfolioService.getFolloweeCount()); - response.setFollowerCount(portfolioService.getFollowerCount()); + response.setFolloweeCount(portfolioService.getFolloweeCount(account.getId())); + response.setFollowerCount(portfolioService.getFollowerCount(account.getId())); //判断是否常用ip 不是则发邮件提示 calculateExceptionIp(RequestInfoUtil.getIpAddress(request), account); return response; @@ -1461,4 +1462,44 @@ public class AccountServiceImpl extends ServiceImpl impl return minioUtil.getPreSignedUrl(avatarPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); } + public PersonalHomepageVO getPersonalHomepage(Long accountId){ + // 需要返回 用户头像 用户名 作品总量 粉丝量 关注量 主页访问量 当前用户是否被查看者关注 + Long currentUserId = UserContext.getUserHolder().getId(); + PersonalHomepageVO personalHomepageVO = new PersonalHomepageVO(); + + Account account = baseMapper.selectById(accountId); + personalHomepageVO.setUserName(account.getUserName()); + String avatar = StringUtil.isNullOrEmpty(account.getAvatar()) ? CommonConstant.DEFAULT_AVATAR : account.getAvatar(); + personalHomepageVO.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + + personalHomepageVO.setPortfolioCount(portfolioService.getPortfolioCount(accountId)); + personalHomepageVO.setFolloweeCount(portfolioService.getFolloweeCount(accountId)); + personalHomepageVO.setFollowerCount(portfolioService.getFollowerCount(accountId)); + personalHomepageVO.setHomepageViewCount(viewPersonalHomepageCount(0L)); + + + if (accountId.equals(currentUserId)){ + personalHomepageVO.setIsFollow(0); + Long viewCount = viewPersonalHomepageCount(accountId); + // 只有本人才能看到个人主页浏览量 + personalHomepageVO.setHomepageViewCount(viewCount == null ? 0 : viewCount); + }else { + personalHomepageVO.setIsFollow(portfolioService.getIfFollowed(accountId, currentUserId)); + // 非本人浏览主页时增加浏览量 + viewsIncrease(accountId); + } + return personalHomepageVO; + } + + @Override + public Boolean viewsIncrease(Long id) { + redisUtil.increasePersonalHomepageViewCount(id); + return Boolean.TRUE; + } + + private Long viewPersonalHomepageCount(Long accountId) { + redisUtil.getPersonalHomepageViewCount(accountId); + return null; + } + } diff --git a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java index 2f0ac1d8..e1f5638a 100644 --- a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java @@ -11,9 +11,9 @@ import com.ai.da.mapper.primary.SysNotificationReadStatusMapper; import com.ai.da.mapper.primary.entity.Account; import com.ai.da.mapper.primary.entity.Notification; import com.ai.da.mapper.primary.entity.SysNotificationReadStatus; -import com.ai.da.model.vo.GetNotificationVO; +import com.ai.da.model.dto.GetNotificationDTO; import com.ai.da.model.vo.NotificationVO; -import com.ai.da.model.vo.PublishSysNotificationVO; +import com.ai.da.model.dto.PublishSysNotificationDTO; import com.ai.da.service.AccountService; import com.ai.da.service.MessageCenterService; import com.ai.da.service.PortfolioService; @@ -67,16 +67,16 @@ public class MessageCenterServiceImpl extends ServiceImpl getHistoryNotification(GetNotificationVO getNotificationVO) { + public PageBaseResponse getHistoryNotification(GetNotificationDTO getNotificationDTO) { Long accountId = UserContext.getUserHolder().getId(); QueryWrapper queryWrapper = new QueryWrapper<>(); - if (!StringUtils.isNullOrEmpty(getNotificationVO.getType())) { - queryWrapper.eq("type", getNotificationVO.getType()); + if (!StringUtils.isNullOrEmpty(getNotificationDTO.getType())) { + queryWrapper.eq("type", getNotificationDTO.getType()); } - if (!getNotificationVO.getType().equals("system")){ + if (!getNotificationDTO.getType().equals("system")){ queryWrapper.eq("receiver_id", accountId); } - Page notificationPage = baseMapper.selectPage(new Page<>(getNotificationVO.getPage(), getNotificationVO.getSize()), queryWrapper); + Page notificationPage = baseMapper.selectPage(new Page<>(getNotificationDTO.getPage(), getNotificationDTO.getSize()), queryWrapper); List unreadSysNotificationIds = baseMapper.getUnreadSysNotification(accountId); IPage convert = notificationPage.convert(o -> { @@ -260,7 +260,7 @@ public class MessageCenterServiceImpl extends ServiceImpl qw = new QueryWrapper<>(); if (query.getGetMyPortfolio() == 1) { qw.lambda().eq(Portfolio::getAccountId, userHolder.getId()); + } else if (!Objects.isNull(query.getAccountId())) { + qw.lambda().eq(Portfolio::getAccountId, query.getAccountId()); } if (query.getGetLikePortfolio() == 1) { List likedPortfolioIdList = redisUtil.getLikedPortfolios(userHolder.getId()); @@ -497,14 +497,8 @@ public class PortfolioServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("followee_id", portfolio.getAccountId()).eq("follower_id", userHolder.getId()); - UserFollow userFollow = userFollowMapper.selectOne(queryWrapper); - if (Objects.isNull(userFollow)){ - vo.setIsFollow(0); - }else { - vo.setIsFollow(1); - } + Integer ifFollowed = getIfFollowed(portfolio.getAccountId(), userHolder.getId()); + vo.setIsFollow(ifFollowed); avatar = StringUtil.isNullOrEmpty(account.getAvatar()) ? CommonConstant.DEFAULT_AVATAR : account.getAvatar(); } vo.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); @@ -988,7 +982,7 @@ public class PortfolioServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); @@ -999,47 +993,96 @@ public class PortfolioServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("follower_id", UserContext.getUserHolder().getId()).select("followee_id"); + queryWrapper.eq("follower_id", accountId).select("followee_id"); return userFollowMapper.selectCount(queryWrapper); } - // 获取某个用户的关注列表 - public List getFolloweeList(PageQueryBaseVo pageQueryBaseVo){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("follower_id", UserContext.getUserHolder().getId()).select("followee_id"); - Page followPage = userFollowMapper.selectPage(new Page<>(pageQueryBaseVo.getPage(), pageQueryBaseVo.getSize()), queryWrapper); + // 获取某个用户的关注列表 + 按名字查询 + public List getFolloweeList(GetFollowListDTO getFollowListDTO) { + Long accountId = UserContext.getUserHolder().getId(); + // 1、判断是否有按用户名查询 + List followeeList; + if (!StringUtil.isNullOrEmpty(getFollowListDTO.getSearchByName())) { + followeeList = userFollowMapper.getFolloweeListByName(getFollowListDTO.getSearchByName(), accountId); + }else { + // 2、查全部 分页查询 + String order = StringUtil.isNullOrEmpty(getFollowListDTO.getOrder()) ? "DESC" : getFollowListDTO.getOrder().equals("DESC") ? "DESC" : "ASC"; + Integer limit= getFollowListDTO.getSize() > 0 ? getFollowListDTO.getSize() : 20; + Integer offset = getFollowListDTO.getPage() > 0 ? (getFollowListDTO.getPage() - 1) * getFollowListDTO.getSize() : 0; + followeeList = userFollowMapper.getFolloweeListByFollower(accountId, limit, offset, order); + } - if (!followPage.getRecords().isEmpty()){ - List followeeIds = followPage.getRecords().stream().map(UserFollow::getFolloweeId).collect(Collectors.toList()); - return accountMapper.selectBatchIds(followeeIds); + if (!followeeList.isEmpty()){ + followeeList.forEach(followee -> { + String avatar = StringUtil.isNullOrEmpty(followee.getAvatar()) ? CommonConstant.DEFAULT_AVATAR : followee.getAvatar(); + followee.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + }); + return followeeList; } return new ArrayList<>(); } - public Long getFollowerCount(){ + public Long getFollowerCount(Long accountId) { QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("followee_id", UserContext.getUserHolder().getId()).select("follower_id"); + queryWrapper.eq("followee_id", accountId).select("follower_id"); return userFollowMapper.selectCount(queryWrapper); } - // 获取某个用户的粉丝列表 - public List getFollowerList(PageQueryBaseVo pageQueryBaseVo){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("followee_id", UserContext.getUserHolder().getId()).select("follower_id"); - Page followPage = userFollowMapper.selectPage(new Page<>(pageQueryBaseVo.getPage(), pageQueryBaseVo.getSize()), queryWrapper); + // 获取某个用户的粉丝列表 + 按名字查询 需返回是否关注该粉丝 + public List getFollowerList(GetFollowListDTO getFollowListDTO) { + Long accountId = UserContext.getUserHolder().getId(); - if (!followPage.getRecords().isEmpty()){ - List followerIds = followPage.getRecords().stream().map(UserFollow::getFollowerId).collect(Collectors.toList()); - return accountMapper.selectBatchIds(followerIds); + // 获取当前用户的所有粉丝 + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("follower_id", accountId).select("followee_id","create_time"); + List userFollows = userFollowMapper.selectList(qw); + Map followeeMap = userFollows.stream().collect(Collectors.toMap(UserFollow::getFolloweeId, UserFollow::getCreateTime)); + + List followerList; + // 1、判断是否有按用户名查询粉丝 + if (!StringUtil.isNullOrEmpty(getFollowListDTO.getSearchByName())) { + followerList = userFollowMapper.getFollowerListByName(getFollowListDTO.getSearchByName(), accountId); + }else { + // 2、查全部 分页查询 + String order = StringUtil.isNullOrEmpty(getFollowListDTO.getOrder()) ? "DESC" : getFollowListDTO.getOrder().equals("DESC") ? "DESC" : "ASC"; + Integer limit= getFollowListDTO.getSize() > 0 ? getFollowListDTO.getSize() : 20; + Integer offset = getFollowListDTO.getPage() > 0 ? (getFollowListDTO.getPage() - 1) * getFollowListDTO.getSize() : 0; + followerList = userFollowMapper.getFollowerListByFollowee(accountId, limit,offset, order); + } + + if (!followerList.isEmpty()){ + // 判断当前用户是否与粉丝互关 + followerList.forEach(follower -> { + String avatar = StringUtil.isNullOrEmpty(follower.getAvatar()) ? CommonConstant.DEFAULT_AVATAR : follower.getAvatar(); + follower.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + follower.setMutualFollowing(Objects.isNull(followeeMap.get(follower.getUserId())) ? 0 : 1); + follower.setFollowTime(followeeMap.get(follower.getUserId())); + }); + return followerList; } return new ArrayList<>(); } + public Integer getIfFollowed(Long followeeId, Long followerId) { + // 设置当前用户是否关注了所查看作品的作者 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("followee_id", followeeId).eq("follower_id", followerId); + UserFollow userFollow = userFollowMapper.selectOne(queryWrapper); + return Objects.isNull(userFollow) ? 0 : 1; + } + + public Long getPortfolioCount(Long accountId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("account_id", accountId); + + return baseMapper.selectCount(queryWrapper); + } + } diff --git a/src/main/resources/mapper/primary/UserFollowMapper.xml b/src/main/resources/mapper/primary/UserFollowMapper.xml new file mode 100644 index 00000000..06e40a81 --- /dev/null +++ b/src/main/resources/mapper/primary/UserFollowMapper.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + From c5da68dc47e072f99f91b563db2c6624904b3198 Mon Sep 17 00:00:00 2001 From: xupei Date: Wed, 21 Aug 2024 14:31:10 +0800 Subject: [PATCH 07/10] =?UTF-8?q?1=E3=80=81=E8=8E=B7=E5=8F=96=E5=85=B3?= =?UTF-8?q?=E6=B3=A8=E3=80=81=E7=B2=89=E4=B8=9D=E5=88=97=E8=A1=A8=E3=80=81?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E8=AF=A6=E7=BB=86=20=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=BB=9F=E4=B8=80=202=E3=80=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=91=98=E7=B3=BB=E7=BB=9F=20=E6=8C=89=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=90=8D=E6=88=96=E7=94=A8=E6=88=B7=E9=82=AE=E7=AE=B1?= =?UTF-8?q?=20=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7design=E9=A2=91=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ConvenientInquiryController.java | 5 +++-- .../com/ai/da/mapper/primary/DesignMapper.java | 2 +- .../java/com/ai/da/model/vo/AccountFollowVO.java | 15 ++++++++++++--- .../java/com/ai/da/model/vo/NotificationVO.java | 12 +++++++++--- .../da/service/impl/MessageCenterServiceImpl.java | 6 +++--- .../ai/da/service/impl/PortfolioServiceImpl.java | 4 ++-- .../resources/mapper/primary/DesignMapper.xml | 6 ++++++ .../resources/mapper/primary/UserFollowMapper.xml | 8 ++++---- 8 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/ai/da/controller/ConvenientInquiryController.java b/src/main/java/com/ai/da/controller/ConvenientInquiryController.java index 119baa5a..c1ff0f2d 100644 --- a/src/main/java/com/ai/da/controller/ConvenientInquiryController.java +++ b/src/main/java/com/ai/da/controller/ConvenientInquiryController.java @@ -51,7 +51,8 @@ public class ConvenientInquiryController { @ApiOperation("获取指定时间区间内所有用户design的使用情况") @GetMapping("/getDesignStatistic") - public Response> getDesignStatistic(@RequestParam String startTime, @RequestParam String endTime) { + public Response> getDesignStatistic(@RequestParam String startTime, @RequestParam String endTime, + @RequestParam(required = false) String userName, @RequestParam(required = false) String email) { Long accountId = UserContext.getUserHolder().getId(); if (accountId.equals(31L) || accountId.equals(87L) || accountId.equals(83L) || accountId.equals(6L) || accountId.equals(4L) || accountId.equals(73L)) { if (StringUtil.isNullOrEmpty(startTime)) startTime = "2024-02-01 00:00:00"; @@ -60,7 +61,7 @@ public class ConvenientInquiryController { Date date = new Date(); endTime = simpleDateFormat.format(date); } - List designStatistic = designMapper.getDesignStatistic(startTime, endTime); + List designStatistic = designMapper.getDesignStatistic(startTime, endTime, userName, email); return Response.success(designStatistic); } else { return Response.fail("Sorry, you don't have permission"); diff --git a/src/main/java/com/ai/da/mapper/primary/DesignMapper.java b/src/main/java/com/ai/da/mapper/primary/DesignMapper.java index e6b1aa58..7db2a609 100644 --- a/src/main/java/com/ai/da/mapper/primary/DesignMapper.java +++ b/src/main/java/com/ai/da/mapper/primary/DesignMapper.java @@ -18,5 +18,5 @@ public interface DesignMapper extends CommonMapper { //返回插入数据后生成的主键 Long insertDesign(Design design); - List getDesignStatistic(String startTime, String endTime); + List getDesignStatistic(String startTime, String endTime, String userName, String email); } diff --git a/src/main/java/com/ai/da/model/vo/AccountFollowVO.java b/src/main/java/com/ai/da/model/vo/AccountFollowVO.java index 5680ed76..39a4e708 100644 --- a/src/main/java/com/ai/da/model/vo/AccountFollowVO.java +++ b/src/main/java/com/ai/da/model/vo/AccountFollowVO.java @@ -11,14 +11,23 @@ import java.time.LocalDateTime; @NoArgsConstructor @AllArgsConstructor public class AccountFollowVO { - private Long userId; + /** + * userId + */ + private Long senderId; private String userName; private String avatar; + /** + * followTime + */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") - private LocalDateTime followTime; + private LocalDateTime createTime; - private Integer mutualFollowing; + /** + * mutualFollowing 互粉 + */ + private Integer isFollow; } diff --git a/src/main/java/com/ai/da/model/vo/NotificationVO.java b/src/main/java/com/ai/da/model/vo/NotificationVO.java index cd4eaedd..32699ce6 100644 --- a/src/main/java/com/ai/da/model/vo/NotificationVO.java +++ b/src/main/java/com/ai/da/model/vo/NotificationVO.java @@ -8,13 +8,19 @@ import lombok.EqualsAndHashCode; @Data public class NotificationVO extends Notification { - private String senderUserName; + /** + * senderUserName + */ + private String userName; - private String senderUserAvatar; +// private String senderUserAvatar; private String portfolioName; - private String senderAvatar; + /** + * sender头像 + */ + private String avatar; private Integer isFollow; diff --git a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java index e1f5638a..83d719d6 100644 --- a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java @@ -82,8 +82,8 @@ public class MessageCenterServiceImpl extends ServiceImpl convert = notificationPage.convert(o -> { NotificationVO notificationVO = CopyUtil.copyObject(o, NotificationVO.class); Account senderAccount = accountService.getById(notificationVO.getSenderId()); - notificationVO.setSenderUserName(senderAccount.getUserName()); - notificationVO.setSenderUserAvatar(StringUtils.isNullOrEmpty(senderAccount.getAvatar()) ? null : minioUtil.getPreSignedUrl(senderAccount.getAvatar(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + notificationVO.setUserName(senderAccount.getUserName()); +// notificationVO.setSenderUserAvatar(StringUtils.isNullOrEmpty(senderAccount.getAvatar()) ? null : minioUtil.getPreSignedUrl(senderAccount.getAvatar(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); notificationVO.setPortfolioName(Objects.isNull(notificationVO.getPortfolioId()) ? null : portfolioService.getById(notificationVO.getPortfolioId()).getPortfolioName()); // 设置单个人 系统消息是否已读 if (notificationVO.getType().equals("system")){ @@ -94,7 +94,7 @@ public class MessageCenterServiceImpl extends ServiceImpl { String avatar = StringUtil.isNullOrEmpty(follower.getAvatar()) ? CommonConstant.DEFAULT_AVATAR : follower.getAvatar(); follower.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - follower.setMutualFollowing(Objects.isNull(followeeMap.get(follower.getUserId())) ? 0 : 1); - follower.setFollowTime(followeeMap.get(follower.getUserId())); + follower.setIsFollow(Objects.isNull(followeeMap.get(follower.getSenderId())) ? 0 : 1); +// follower.setFollowTime(followeeMap.get(follower.getUserId())); }); return followerList; } diff --git a/src/main/resources/mapper/primary/DesignMapper.xml b/src/main/resources/mapper/primary/DesignMapper.xml index 6fc69739..0c33c320 100644 --- a/src/main/resources/mapper/primary/DesignMapper.xml +++ b/src/main/resources/mapper/primary/DesignMapper.xml @@ -39,6 +39,12 @@ and b.create_date not like '%:01' and b.create_date not like '%:02' + + and a.user_name = #{userName} + + + and a.user_email = #{email} + GROUP BY b.account_id ORDER BY b.account_id asc) d left join trial_order c on d.user_email = c.email diff --git a/src/main/resources/mapper/primary/UserFollowMapper.xml b/src/main/resources/mapper/primary/UserFollowMapper.xml index 06e40a81..60b7a588 100644 --- a/src/main/resources/mapper/primary/UserFollowMapper.xml +++ b/src/main/resources/mapper/primary/UserFollowMapper.xml @@ -2,7 +2,7 @@