From bc3ffac3db2ed93d4ec538ae1ee602fdf2fe6c2d Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Fri, 19 Dec 2025 01:54:29 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bao/dating/controller/PostController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/bao/dating/controller/PostController.java b/src/main/java/com/bao/dating/controller/PostController.java index 526a2ae..2dde13e 100644 --- a/src/main/java/com/bao/dating/controller/PostController.java +++ b/src/main/java/com/bao/dating/controller/PostController.java @@ -20,6 +20,7 @@ public class PostController { private PostService postService; /** + * text * 上传媒体文件接口 * @param files 媒体文件数组 * @return 上传后的文件URL列表 From 2d3ac688867300ef8c03e013f762d591b74181ee Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Fri, 19 Dec 2025 01:55:23 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bao/dating/controller/PostController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/bao/dating/controller/PostController.java b/src/main/java/com/bao/dating/controller/PostController.java index 526a2ae..78e9fa7 100644 --- a/src/main/java/com/bao/dating/controller/PostController.java +++ b/src/main/java/com/bao/dating/controller/PostController.java @@ -20,6 +20,7 @@ public class PostController { private PostService postService; /** + * 测试 * 上传媒体文件接口 * @param files 媒体文件数组 * @return 上传后的文件URL列表 From 088e5612d31f19ee09f783a84795582b250106d9 Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Fri, 19 Dec 2025 01:56:15 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bao/dating/controller/PostController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bao/dating/controller/PostController.java b/src/main/java/com/bao/dating/controller/PostController.java index 78e9fa7..9caeb2e 100644 --- a/src/main/java/com/bao/dating/controller/PostController.java +++ b/src/main/java/com/bao/dating/controller/PostController.java @@ -20,7 +20,7 @@ public class PostController { private PostService postService; /** - * 测试 + * 测试 123123 * 上传媒体文件接口 * @param files 媒体文件数组 * @return 上传后的文件URL列表 From e5f411e342bc54a99b996a7c7cf925ca6c203d6b Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Fri, 19 Dec 2025 01:58:09 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E6=B5=8B=E8=AF=95=20like?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bao/dating/controller/PostController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bao/dating/controller/PostController.java b/src/main/java/com/bao/dating/controller/PostController.java index 526a2ae..4525669 100644 --- a/src/main/java/com/bao/dating/controller/PostController.java +++ b/src/main/java/com/bao/dating/controller/PostController.java @@ -20,7 +20,7 @@ public class PostController { private PostService postService; /** - * 上传媒体文件接口 + * 上传媒体文件接口 like * @param files 媒体文件数组 * @return 上传后的文件URL列表 */ From 8d9f2285e4699d5f1b194723f516d54f59f729b8 Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Fri, 19 Dec 2025 02:05:22 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E6=B5=8B=E8=AF=95=20like123?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bao/dating/controller/text.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/com/bao/dating/controller/text.java diff --git a/src/main/java/com/bao/dating/controller/text.java b/src/main/java/com/bao/dating/controller/text.java new file mode 100644 index 0000000..7806c8a --- /dev/null +++ b/src/main/java/com/bao/dating/controller/text.java @@ -0,0 +1,4 @@ +package com.bao.dating.controller; + +public class text { +} From 756fbd1a310994749683a0060d0ccc9952902e67 Mon Sep 17 00:00:00 2001 From: KilLze Date: Fri, 19 Dec 2025 02:08:48 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=81=8D=E5=8E=86?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=AE=A1=E6=9F=A5=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=85=A8=E9=83=A8=E5=AE=A1=E5=AF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dating/common/aliyun/GreenImageScan.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/bao/dating/common/aliyun/GreenImageScan.java b/src/main/java/com/bao/dating/common/aliyun/GreenImageScan.java index 75cacec..cd6c7c2 100644 --- a/src/main/java/com/bao/dating/common/aliyun/GreenImageScan.java +++ b/src/main/java/com/bao/dating/common/aliyun/GreenImageScan.java @@ -61,19 +61,24 @@ public class GreenImageScan { if (scanImageResponse.getStatusCode() == 200) { - List subResults = scanImageResponse.body.data.results.get(0).getSubResults(); + List results = scanImageResponse.body.data.results; - ListIterator listIterator = subResults.listIterator(); - while (listIterator.hasNext()) { - ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults item = listIterator.next(); - - if (!item.suggestion.equals("pass")) { - resultMap.put("suggestion", item.suggestion); - resultMap.put("label", item.label); - return resultMap; + // 遍历每一张图片的审核结果 + for (ScanImageResponseBody.ScanImageResponseBodyDataResults result : results) { + List subResults = result.getSubResults(); + + // 检查这张图片的所有子审核项 + for (ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults subResult : subResults) { + // 如果有任何一项未通过审核,则整个审核不通过 + if (!subResult.suggestion.equals("pass")) { + resultMap.put("suggestion", subResult.suggestion); + resultMap.put("label", subResult.label); + return resultMap; + } } } - // 所有审核项都通过时,返回pass结果 + + // 所有图片的所有审核项都通过时,返回pass结果 resultMap.put("suggestion", "pass"); resultMap.put("label", "normal"); return resultMap; @@ -94,4 +99,4 @@ public class GreenImageScan { return null; } } -} +} \ No newline at end of file From 0ce96c310492840204da2ac0db3fa6b306595128 Mon Sep 17 00:00:00 2001 From: KilLze Date: Fri, 19 Dec 2025 20:21:47 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=EF=BC=8C=E5=AE=A1=E6=A0=B8=E6=9C=AA=E9=80=9A=E8=BF=87=E4=BE=9D?= =?UTF-8?q?=E6=97=A7=E4=BC=9A=E5=8A=A0=E5=85=A5=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=B0=86=E5=8A=A8=E6=80=81=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=94=B9=E4=B8=BA2=EF=BC=88=E6=9C=AA=E9=80=9A=E8=BF=87?= =?UTF-8?q?=EF=BC=89=EF=BC=8C=E8=8B=A5=E6=9C=89=E5=AB=8C=E7=96=91=E5=88=99?= =?UTF-8?q?=E6=94=B9=E4=B8=BA1=E8=BF=9B=E8=A1=8C=E4=BA=BA=E5=B7=A5?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=EF=BC=8C=E9=80=9A=E8=BF=87=E5=88=99=E4=B8=BA?= =?UTF-8?q?0=20=E6=96=B0=E5=A2=9E=E5=8A=A8=E6=80=81=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=8F=AF=E4=BB=A5=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=96=87=E6=9C=AC=EF=BC=8C=E5=9B=BE=E7=89=87=EF=BC=8C=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=EF=BC=8C=E4=BF=AE=E6=94=B9=E5=86=85=E5=AE=B9=E8=8B=A5?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E6=9C=AA=E9=80=9A=E8=BF=87=E5=88=99=E5=B0=86?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=94=B9=E4=B8=BA2=EF=BC=8C=E8=8B=A5?= =?UTF-8?q?=E6=9C=89=E5=AB=8C=E7=96=91=E5=88=99=E6=94=B9=E4=B8=BA1?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BA=BA=E5=B7=A5=E5=AE=A1=E6=A0=B8=EF=BC=8C?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=88=99=E6=94=B9=E4=B8=BA0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bao/dating/controller/PostController.java | 33 +++- .../com/bao/dating/mapper/PostMapper.java | 27 ++- .../bao/dating/pojo/dto/PostRequestDTO.java | 7 +- .../com/bao/dating/pojo/vo/PostEditVO.java | 19 ++ .../com/bao/dating/service/PostService.java | 22 ++- .../dating/service/impl/PostServiceImpl.java | 164 ++++++++++++++---- .../com/bao/dating/mapper/PostMapper.xml | 52 +++++- 7 files changed, 276 insertions(+), 48 deletions(-) create mode 100644 src/main/java/com/bao/dating/pojo/vo/PostEditVO.java diff --git a/src/main/java/com/bao/dating/controller/PostController.java b/src/main/java/com/bao/dating/controller/PostController.java index 526a2ae..2db3b33 100644 --- a/src/main/java/com/bao/dating/controller/PostController.java +++ b/src/main/java/com/bao/dating/controller/PostController.java @@ -5,6 +5,7 @@ import com.bao.dating.common.Result; import com.bao.dating.common.ResultCode; import com.bao.dating.pojo.dto.PostRequestDTO; import com.bao.dating.pojo.entity.Post; +import com.bao.dating.pojo.vo.PostEditVO; import com.bao.dating.service.PostService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -32,13 +33,14 @@ public class PostController { /** * 发布动态接口 - JSON格式请求 - * @param postRequestDTO 动态信息 + * @param postDTO 动态信息 + * @param userId 用户ID * @return 发布的动态对象 */ @PostMapping(consumes = "application/json") - public Result createPostJson(@RequestBody PostRequestDTO postRequestDTO) { + public Result createPostJson(@RequestBody PostRequestDTO postDTO, @RequestParam Long userId) { // 调用 Service 层处理发布动态业务逻辑 - Post result = postService.createPost(postRequestDTO); + Post result = postService.createPost(userId, postDTO); return Result.success(ResultCode.SUCCESS_REVIEW, "动态发布成功,等待审核。", result); } @@ -49,8 +51,31 @@ public class PostController { * @return 删除结果 */ @DeleteMapping("/{postId}") - public Result deleteById(@PathVariable Integer postId){ + public Result deleteById(@PathVariable Long postId){ postService.deletePostById(postId); return Result.success(ResultCode.SUCCESS_DELETE, "动态删除成功", null); } + + /** + * 根据ID查询动态接口 + * @param postId 动态ID + * @return 动态对象 + */ + @GetMapping("/{postId}") + public Result getPostById(@PathVariable Long postId) { + PostEditVO postEditVO = postService.getPostForEdit(postId); + return Result.success(ResultCode.SUCCESS,"查询成功", postEditVO); + } + + /** + * 更新动态接口 + * @param postId 动态ID + * @param postRequestDTO 动态信息 + * @return 更新后的动态对象 + */ + @PutMapping("/{postId}") + public Result updatePost(@PathVariable Long postId, @RequestBody PostRequestDTO postRequestDTO) { + PostEditVO result = postService.updatePost(postId, postRequestDTO); + return Result.success(ResultCode.SUCCESS_REVIEW, "动态更新成功", result); + } } \ No newline at end of file diff --git a/src/main/java/com/bao/dating/mapper/PostMapper.java b/src/main/java/com/bao/dating/mapper/PostMapper.java index 4e31426..d4bd5b2 100644 --- a/src/main/java/com/bao/dating/mapper/PostMapper.java +++ b/src/main/java/com/bao/dating/mapper/PostMapper.java @@ -2,24 +2,39 @@ package com.bao.dating.mapper; import com.bao.dating.pojo.entity.Post; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; @Mapper public interface PostMapper { /** * 插入动态 * - * @param post 动态对象 - * @return 插入的行数 + * @param post */ - int insert(Post post); + void insert(Post post); /** * 根据ID删除动态 * * @param postId 动态ID - * @return 删除的行数 */ - int deletePostById(Integer postId); + void deletePostById(@Param("postId") Long postId); + + /** + * 根据ID查询动态 + * + * @param postId + * @return + */ + Post selectById(@Param("postId") Long postId); + + /** + * 根据ID更新动态 + * + * @param post + * @return + */ + void updateById(Post post); /** * 查询点赞数 @@ -44,4 +59,4 @@ public interface PostMapper { * @return 影响行数 */ int decreaseLikeCount(Long postId); -} +} \ No newline at end of file diff --git a/src/main/java/com/bao/dating/pojo/dto/PostRequestDTO.java b/src/main/java/com/bao/dating/pojo/dto/PostRequestDTO.java index fde914d..27b23b9 100644 --- a/src/main/java/com/bao/dating/pojo/dto/PostRequestDTO.java +++ b/src/main/java/com/bao/dating/pojo/dto/PostRequestDTO.java @@ -1,14 +1,15 @@ package com.bao.dating.pojo.dto; import lombok.Data; -import org.springframework.web.multipart.MultipartFile; import java.util.List; +/** + * 动态数据传输对象 + */ @Data public class PostRequestDTO { - private Long userId; private String content; + private List mediaOssKeys; private List tags; - private List mediaUrls; } \ No newline at end of file diff --git a/src/main/java/com/bao/dating/pojo/vo/PostEditVO.java b/src/main/java/com/bao/dating/pojo/vo/PostEditVO.java new file mode 100644 index 0000000..87e6bdd --- /dev/null +++ b/src/main/java/com/bao/dating/pojo/vo/PostEditVO.java @@ -0,0 +1,19 @@ +package com.bao.dating.pojo.vo; + +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 修改内容查询返回数据 + */ +@Data +public class PostEditVO { + private Long postId; + private String content; + private List mediaOssKeys; + private List tags; + private Integer isPublic; + private LocalDateTime updatedAt; +} \ No newline at end of file diff --git a/src/main/java/com/bao/dating/service/PostService.java b/src/main/java/com/bao/dating/service/PostService.java index a60fff8..975e78a 100644 --- a/src/main/java/com/bao/dating/service/PostService.java +++ b/src/main/java/com/bao/dating/service/PostService.java @@ -2,6 +2,7 @@ package com.bao.dating.service; import com.bao.dating.pojo.dto.PostRequestDTO; import com.bao.dating.pojo.entity.Post; +import com.bao.dating.pojo.vo.PostEditVO; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -16,15 +17,30 @@ public interface PostService { /** * 创建动态 - * @param postRequestDTO 动态请求数据传输对象 + * @param userId 用户ID + * @param postRequestDTO 动态数据传输对象 * @return 创建的动态对象 */ - Post createPost(PostRequestDTO postRequestDTO); + Post createPost(Long userId, PostRequestDTO postRequestDTO); /** * 删除动态 * @param postId 动态ID * @return 删除的动态对象 */ - void deletePostById(Integer postId); + void deletePostById(Long postId); + + /** + * 查询动态详情(用于编辑) + * @param postId 动态ID + */ + PostEditVO getPostForEdit(Long postId); + + /** + * 修改动态 + * @param postId 动态ID + * @param postRequestDTO 修改的动态数据传输对象 + * @return 修改后的动态对象 + */ + PostEditVO updatePost(Long postId, PostRequestDTO postRequestDTO); } \ No newline at end of file diff --git a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java index 96d802d..76abdff 100644 --- a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java @@ -5,9 +5,11 @@ import com.bao.dating.common.aliyun.GreenTextScan; import com.bao.dating.mapper.PostMapper; import com.bao.dating.pojo.dto.PostRequestDTO; import com.bao.dating.pojo.entity.Post; +import com.bao.dating.pojo.vo.PostEditVO; import com.bao.dating.service.PostService; import com.bao.dating.util.AliOssUtil; import com.bao.dating.util.FileUtil; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -77,11 +79,23 @@ public class PostServiceImpl implements PostService { /** * 创建动态 * - * @param postRequestDTO 动态请求数据传输对象 + * @param userId 用户ID + * @param postRequestDTO 动态数据传输对象 * @return 创建的动态对象 */ @Override - public Post createPost(PostRequestDTO postRequestDTO) { + public Post createPost(Long userId, PostRequestDTO postRequestDTO) { + + // 创建动态对象 + Post post = new Post(); + post.setUserId(userId); + post.setContent(postRequestDTO.getContent()); + post.setTags(postRequestDTO.getTags()); + post.setMediaOssKeys(new ArrayList<>()); + // 如果有传入的媒体链接,则使用它们 + if (postRequestDTO.getMediaOssKeys() != null && !postRequestDTO.getMediaOssKeys().isEmpty()) { + post.setMediaOssKeys(postRequestDTO.getMediaOssKeys()); + } // 1. 文本内容审核 Map textResult; @@ -90,45 +104,45 @@ public class PostServiceImpl implements PostService { } catch (Exception e) { throw new RuntimeException("文本审核失败"); } - + // 文本审核结果 String textSuggestion = (String) textResult.get("suggestion"); - if ("block".equals(textSuggestion)) { - throw new RuntimeException("动态内容违规,禁止发布"); - } // 2. 图片审核(如果有) - if (postRequestDTO.getMediaUrls() != null && !postRequestDTO.getMediaUrls().isEmpty()) { + if (postRequestDTO.getMediaOssKeys() != null && !postRequestDTO.getMediaOssKeys().isEmpty()) { Map imageResult; try { - imageResult = greenImageScan.imageScan(postRequestDTO.getMediaUrls()); + imageResult = greenImageScan.imageScan(postRequestDTO.getMediaOssKeys()); } catch (Exception e) { throw new RuntimeException(e); } - - if ("block".equals(imageResult.get("suggestion"))) { - throw new RuntimeException("图片内容违规,禁止发布"); + // 图片审核结果 + String imageSuggestion = (String) imageResult.get("suggestion"); + + // 根据审核结果设置状态 + if ("block".equals(textSuggestion) || "block".equals(imageSuggestion)) { + // 审核未通过,允许用户修改 + post.setIsPublic(2); + } else if ("review".equals(textSuggestion) || "review".equals(imageSuggestion)) { + // 待审核,需人工审核 + post.setIsPublic(1); + } else { + // 审核通过 + post.setIsPublic(0); + } + } else { + // 只有文本内容的情况 + if ("block".equals(textSuggestion)) { + // 审核未通过,允许用户修改 + post.setIsPublic(2); + } else if ("review".equals(textSuggestion)) { + // 待审核,需人工审核 + post.setIsPublic(1); + } else { + // 审核通过 + post.setIsPublic(0); } } - - Post post = new Post(); - post.setUserId(Long.valueOf(postRequestDTO.getUserId())); - post.setContent(postRequestDTO.getContent()); - post.setTags(postRequestDTO.getTags()); - post.setMediaOssKeys(new ArrayList<>()); - // 如果有传入的媒体链接,则使用它们 - if (postRequestDTO.getMediaUrls() != null && !postRequestDTO.getMediaUrls().isEmpty()) { - post.setMediaOssKeys(postRequestDTO.getMediaUrls()); - } - - // 4. 根据审核结果设置状态 - if ("review".equals(textSuggestion)) { - // 待审核,需人工审核 - post.setIsPublic(0); - } else { - // 审核通过 - post.setIsPublic(1); - } post.setUpdatedAt(LocalDateTime.now()); post.setCreatedAt(LocalDateTime.now()); @@ -144,7 +158,95 @@ public class PostServiceImpl implements PostService { * @return 删除的动态对象 */ @Override - public void deletePostById(Integer postId) { + public void deletePostById(Long postId) { postMapper.deletePostById(postId); } + + @Override + public PostEditVO getPostForEdit(Long postId) { + + Post post = postMapper.selectById(postId); + if (post == null) { + throw new RuntimeException("动态不存在"); + } + PostEditVO postEditVO = new PostEditVO(); + BeanUtils.copyProperties(post, postEditVO); + return postEditVO; + } + + /** + * 修改动态 + * @param postId 动态ID + * @param postRequestDTO 修改的动态数据传输对象 + * @return + */ + @Override + public PostEditVO updatePost(Long postId, PostRequestDTO postRequestDTO) { + // 查询动态 + Post post = postMapper.selectById(postId); + if (post == null) { + throw new RuntimeException("动态不存在"); + } + post.setContent(postRequestDTO.getContent()); + if (postRequestDTO.getMediaOssKeys() != null && !postRequestDTO.getMediaOssKeys().isEmpty()) { + post.setMediaOssKeys(postRequestDTO.getMediaOssKeys()); + } + + // 1. 文本内容审核 + Map textResult; + try { + textResult = greenTextScan.greeTextScan(postRequestDTO.getContent()); + } catch (Exception e) { + throw new RuntimeException("文本审核失败"); + } + // 文本审核结果 + String textSuggestion = (String) textResult.get("suggestion"); + + // 2. 图片审核(如果有) + if (postRequestDTO.getMediaOssKeys() != null && !postRequestDTO.getMediaOssKeys().isEmpty()) { + Map imageResult; + try { + imageResult = greenImageScan.imageScan(postRequestDTO.getMediaOssKeys()); + } catch (Exception e) { + throw new RuntimeException(e); + } + // 图片审核结果 + String imageSuggestion = (String) imageResult.get("suggestion"); + + // 根据审核结果设置状态 + if ("block".equals(textSuggestion) || "block".equals(imageSuggestion)) { + // 审核未通过,允许用户修改 + post.setIsPublic(2); + } else if ("review".equals(textSuggestion) || "review".equals(imageSuggestion)) { + // 待审核,需人工审核 + post.setIsPublic(1); + } else { + // 审核通过 + post.setIsPublic(0); + } + } else { + // 只有文本内容的情况 + if ("block".equals(textSuggestion)) { + // 审核未通过,允许用户修改 + post.setIsPublic(2); + } else if ("review".equals(textSuggestion)) { + // 待审核,需人工审核 + post.setIsPublic(1); + } else { + // 审核通过 + post.setIsPublic(0); + } + } + post.setTags(postRequestDTO.getTags()); + post.setUpdatedAt(LocalDateTime.now()); + + // 更新动态 + postMapper.updateById(post); + + // 返回动态详情 + PostEditVO postEditVO = new PostEditVO(); + BeanUtils.copyProperties(post, postEditVO); + return postEditVO; + } + } \ No newline at end of file diff --git a/src/main/resources/com/bao/dating/mapper/PostMapper.xml b/src/main/resources/com/bao/dating/mapper/PostMapper.xml index fcb9c1d..c0dd465 100644 --- a/src/main/resources/com/bao/dating/mapper/PostMapper.xml +++ b/src/main/resources/com/bao/dating/mapper/PostMapper.xml @@ -29,10 +29,60 @@ - + DELETE FROM post WHERE post_id = #{postId} + + + + + + + + + + + + + + + + + + + UPDATE post + + + content = #{content}, + + + tags = #{tags, typeHandler=com.bao.dating.handler.ListToVarcharTypeHandler}, + + + media_oss_keys = + #{mediaOssKeys, typeHandler=com.bao.dating.handler.ListToVarcharTypeHandler}, + + is_public = #{isPublic}, + updated_at = #{updatedAt} + + WHERE post_id = #{postId} + + update dating.post set like_count = like_count + 1 where post.post_id = #{postId} From ee708724abecceece52728af8862b0086a9aa52d Mon Sep 17 00:00:00 2001 From: lanyangyang-yzx <15344130122@163.com> Date: Sat, 20 Dec 2025 11:19:56 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=94=B6=E8=97=8F?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bao/dating/mapper/PostMapper.java | 31 +++++++++++++++++++ .../com/bao/dating/service/PostService.java | 7 +++++ .../dating/service/impl/PostServiceImpl.java | 11 +++++++ .../com/bao/dating/mapper/PostMapper.xml | 16 ++++++++++ 4 files changed, 65 insertions(+) diff --git a/src/main/java/com/bao/dating/mapper/PostMapper.java b/src/main/java/com/bao/dating/mapper/PostMapper.java index 4e31426..c4b47d5 100644 --- a/src/main/java/com/bao/dating/mapper/PostMapper.java +++ b/src/main/java/com/bao/dating/mapper/PostMapper.java @@ -2,6 +2,7 @@ package com.bao.dating.mapper; import com.bao.dating.pojo.entity.Post; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; @Mapper public interface PostMapper { @@ -44,4 +45,34 @@ public interface PostMapper { * @return 影响行数 */ int decreaseLikeCount(Long postId); + + /** + * 查询当前动态属于哪个用户id + * @param postId 动态id + * @return 用户id + */ + Long selectUserIdByPostId(@Param("post_id") Long postId); + + /** + * 查询点赞数 + * + * @param postId + * @return + */ + int selectFavoriteCount(Long postId); + + /** + * 收藏数+1 + * + * @param postId 动态ID + * @return 影响行数 + */ + int increaseFavoriteCount(Long postId); + /** + * 收藏数-1 + * + * @param postId 动态ID + * @return 影响行数 + */ + int decreaseFavoriteCount(Long postId); } diff --git a/src/main/java/com/bao/dating/service/PostService.java b/src/main/java/com/bao/dating/service/PostService.java index a60fff8..b74f9f6 100644 --- a/src/main/java/com/bao/dating/service/PostService.java +++ b/src/main/java/com/bao/dating/service/PostService.java @@ -27,4 +27,11 @@ public interface PostService { * @return 删除的动态对象 */ void deletePostById(Integer postId); + + /** + * 查询 + * @param postId 动态id + * @return 用户id + */ + Long selectUserIdByPostId(Long postId); } \ No newline at end of file diff --git a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java index 96d802d..5b7c3cb 100644 --- a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java @@ -147,4 +147,15 @@ public class PostServiceImpl implements PostService { public void deletePostById(Integer postId) { postMapper.deletePostById(postId); } + + /** + * 查询用户id + * @param postId 动态id + * @return + */ + + @Override + public Long selectUserIdByPostId(Long postId) { + return postMapper.selectUserIdByPostId(postId); + } } \ No newline at end of file diff --git a/src/main/resources/com/bao/dating/mapper/PostMapper.xml b/src/main/resources/com/bao/dating/mapper/PostMapper.xml index fcb9c1d..fb5630e 100644 --- a/src/main/resources/com/bao/dating/mapper/PostMapper.xml +++ b/src/main/resources/com/bao/dating/mapper/PostMapper.xml @@ -42,10 +42,26 @@ update dating.post set like_count= like_count - 1 where post.post_id = #{postId} + + + update post set favorite_count = favorite_count + 1 where post_id = #{post_id} + + + + update post set favorite_count = favorite_count - 1 where post_id = #{post_id} + + + + + \ No newline at end of file From 2c4504090cb58fb073e796f28a469bdb09cec7ff Mon Sep 17 00:00:00 2001 From: lanyangyang-yzx <15344130122@163.com> Date: Sat, 20 Dec 2025 11:27:05 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=94=B6=E8=97=8F?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PostFavoriteController.java | 34 +++++++++++ .../bao/dating/mapper/PostFavoriteMapper.java | 15 +++++ .../dating/service/PostFavoriteService.java | 10 +++ .../service/impl/PostFavoriteServiceImpl.java | 61 +++++++++++++++++++ .../bao/dating/mapper/PostFavoriteMapper.xml | 17 ++++++ 5 files changed, 137 insertions(+) create mode 100644 src/main/java/com/bao/dating/controller/PostFavoriteController.java create mode 100644 src/main/java/com/bao/dating/mapper/PostFavoriteMapper.java create mode 100644 src/main/java/com/bao/dating/service/PostFavoriteService.java create mode 100644 src/main/java/com/bao/dating/service/impl/PostFavoriteServiceImpl.java create mode 100644 src/main/resources/com/bao/dating/mapper/PostFavoriteMapper.xml diff --git a/src/main/java/com/bao/dating/controller/PostFavoriteController.java b/src/main/java/com/bao/dating/controller/PostFavoriteController.java new file mode 100644 index 0000000..fd44e56 --- /dev/null +++ b/src/main/java/com/bao/dating/controller/PostFavoriteController.java @@ -0,0 +1,34 @@ +package com.bao.dating.controller; + +import com.bao.dating.common.Result; +import com.bao.dating.common.ResultCode; +import com.bao.dating.pojo.entity.User; +import com.bao.dating.service.PostFavoriteService; +import com.bao.dating.service.PostService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("/posts") +public class PostFavoriteController { + @Autowired + private PostFavoriteService postFavoriteService; + @PostMapping("/{post_id}/favorites") + public Result> addPostFavorite(@PathVariable("post_id")Long postId, User user){ + if (user == null){ + return Result.error(ResultCode.PARAM_ERROR); + } + Long userId = user.getUserId(); + return postFavoriteService.postFavorite(userId,postId); + } + @DeleteMapping("/{post_id}/favorites") + public Result deletePostFavorite(@PathVariable("post_id")Long postId, User user){ + if (user == null){ + return Result.error(ResultCode.PARAM_ERROR); + } + Long userId = user.getUserId(); + return postFavoriteService.deletePostFavorite(userId, postId); + } +} diff --git a/src/main/java/com/bao/dating/mapper/PostFavoriteMapper.java b/src/main/java/com/bao/dating/mapper/PostFavoriteMapper.java new file mode 100644 index 0000000..a0aa443 --- /dev/null +++ b/src/main/java/com/bao/dating/mapper/PostFavoriteMapper.java @@ -0,0 +1,15 @@ +package com.bao.dating.mapper; + +import com.bao.dating.pojo.entity.PostFavorite; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface PostFavoriteMapper { + //查询当前已收藏所有用户 + List selectUserIDByPostID(@Param("postId") Long postId); + int addPostFavorite(PostFavorite postFavorite); + int deletePostFavorite(@Param("postId") Long postId); +} diff --git a/src/main/java/com/bao/dating/service/PostFavoriteService.java b/src/main/java/com/bao/dating/service/PostFavoriteService.java new file mode 100644 index 0000000..32ded85 --- /dev/null +++ b/src/main/java/com/bao/dating/service/PostFavoriteService.java @@ -0,0 +1,10 @@ +package com.bao.dating.service; + +import com.bao.dating.common.Result; + +import java.util.Map; + +public interface PostFavoriteService { + Result> postFavorite(Long userid,Long postId); + Result deletePostFavorite(Long userid,Long postId); +} diff --git a/src/main/java/com/bao/dating/service/impl/PostFavoriteServiceImpl.java b/src/main/java/com/bao/dating/service/impl/PostFavoriteServiceImpl.java new file mode 100644 index 0000000..9424f11 --- /dev/null +++ b/src/main/java/com/bao/dating/service/impl/PostFavoriteServiceImpl.java @@ -0,0 +1,61 @@ +package com.bao.dating.service.impl; + +import com.bao.dating.common.Result; +import com.bao.dating.common.ResultCode; +import com.bao.dating.mapper.PostFavoriteMapper; +import com.bao.dating.mapper.PostMapper; +import com.bao.dating.pojo.entity.PostFavorite; +import com.bao.dating.service.PostFavoriteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class PostFavoriteServiceImpl implements PostFavoriteService { + @Autowired + private PostFavoriteMapper postFavoriteMapper; + @Autowired + private PostMapper postMapper; + @Override + @Transactional + public Result> postFavorite(Long userid, Long postId) { + Long userId = postMapper.selectUserIdByPostId(postId); + if (userid.equals(userId)){ + return Result.error(ResultCode.FORBIDDEN,"无法收藏自己发布动态"); + } + List allUserId = postFavoriteMapper.selectUserIDByPostID(postId); + if (allUserId.contains(userid)){ + return Result.error(ResultCode.FORBIDDEN,"已收藏"); + } + PostFavorite postFavorite = new PostFavorite(); + postFavorite.setPostId(postId); + postFavorite.setUserId(userid); + postFavorite.setCreatedAt(LocalDateTime.now()); + postFavoriteMapper.addPostFavorite(postFavorite); + postMapper.increaseFavoriteCount(postId); + Long count = (long) postMapper.selectFavoriteCount(postId); + Map data = new HashMap<>(); + data.put("favorite_id",postFavorite.getFavoriteId()); + data.put("post_id",postId); + data.put("user_id",userid); + data.put("current_favorites_count",count); + return Result.success(ResultCode.SUCCESS_REVIEW,"收藏成功",data); + } + + @Override + @Transactional + public Result deletePostFavorite(Long userid, Long postId) { + List allUserId = postFavoriteMapper.selectUserIDByPostID(postId); + if (! allUserId.contains(userid)){ + return Result.error(ResultCode.FORBIDDEN,"请先收藏"); + } + postFavoriteMapper.deletePostFavorite(postId); + postMapper.decreaseFavoriteCount(postId); + return null; + } +} diff --git a/src/main/resources/com/bao/dating/mapper/PostFavoriteMapper.xml b/src/main/resources/com/bao/dating/mapper/PostFavoriteMapper.xml new file mode 100644 index 0000000..41b5195 --- /dev/null +++ b/src/main/resources/com/bao/dating/mapper/PostFavoriteMapper.xml @@ -0,0 +1,17 @@ + + + + + + insert into post_favorite values (null,#{userId},#{postId},#{createdAt}) + + + + delete from post_favorite where post_id = #{postId} + + + + \ No newline at end of file From 0149008eb077bdfbdf86759f5aa870a7cced0d53 Mon Sep 17 00:00:00 2001 From: KilLze Date: Sat, 20 Dec 2025 17:13:59 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{util => common/aliyun}/AliOssUtil.java | 7 +++-- .../{ => common/aliyun}/util/FileUtil.java | 2 +- .../bao/dating/config/OssConfiguration.java | 26 ------------------- .../dating/properties/AliOssProperties.java | 15 ----------- .../dating/service/impl/PostServiceImpl.java | 4 +-- 5 files changed, 8 insertions(+), 46 deletions(-) rename src/main/java/com/bao/dating/{util => common/aliyun}/AliOssUtil.java (89%) rename src/main/java/com/bao/dating/{ => common/aliyun}/util/FileUtil.java (95%) delete mode 100644 src/main/java/com/bao/dating/config/OssConfiguration.java delete mode 100644 src/main/java/com/bao/dating/properties/AliOssProperties.java diff --git a/src/main/java/com/bao/dating/util/AliOssUtil.java b/src/main/java/com/bao/dating/common/aliyun/AliOssUtil.java similarity index 89% rename from src/main/java/com/bao/dating/util/AliOssUtil.java rename to src/main/java/com/bao/dating/common/aliyun/AliOssUtil.java index f4035b3..f0f49fb 100644 --- a/src/main/java/com/bao/dating/util/AliOssUtil.java +++ b/src/main/java/com/bao/dating/common/aliyun/AliOssUtil.java @@ -1,4 +1,4 @@ -package com.bao.dating.util; +package com.bao.dating.common.aliyun; import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; @@ -7,12 +7,15 @@ import com.aliyun.oss.OSSException; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; @Data -@AllArgsConstructor @Slf4j +@Component +@ConfigurationProperties(prefix = "aliyun.oss") public class AliOssUtil { private String endpoint; diff --git a/src/main/java/com/bao/dating/util/FileUtil.java b/src/main/java/com/bao/dating/common/aliyun/util/FileUtil.java similarity index 95% rename from src/main/java/com/bao/dating/util/FileUtil.java rename to src/main/java/com/bao/dating/common/aliyun/util/FileUtil.java index 5543dcd..d481ca1 100644 --- a/src/main/java/com/bao/dating/util/FileUtil.java +++ b/src/main/java/com/bao/dating/common/aliyun/util/FileUtil.java @@ -1,4 +1,4 @@ -package com.bao.dating.util; +package com.bao.dating.common.aliyun.util; /** * 文件工具类 diff --git a/src/main/java/com/bao/dating/config/OssConfiguration.java b/src/main/java/com/bao/dating/config/OssConfiguration.java deleted file mode 100644 index 01189d1..0000000 --- a/src/main/java/com/bao/dating/config/OssConfiguration.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.bao.dating.config; - - -import com.bao.dating.properties.AliOssProperties; -import com.bao.dating.util.AliOssUtil; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * 配置类,用于创建AliOssUtil对象 - */ -@Configuration -@Slf4j -public class OssConfiguration { - @Bean - @ConditionalOnMissingBean - public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){ - log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties); - return new AliOssUtil(aliOssProperties.getEndpoint(), - aliOssProperties.getAccessKeyId(), - aliOssProperties.getAccessKeySecret(), - aliOssProperties.getBucketName()); - } -} diff --git a/src/main/java/com/bao/dating/properties/AliOssProperties.java b/src/main/java/com/bao/dating/properties/AliOssProperties.java deleted file mode 100644 index 7756754..0000000 --- a/src/main/java/com/bao/dating/properties/AliOssProperties.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.bao.dating.properties; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -@Component -@ConfigurationProperties(prefix = "aliyun.oss") -@Data -public class AliOssProperties { - private String endpoint; - private String accessKeyId; - private String accessKeySecret; - private String bucketName; -} diff --git a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java index 76abdff..cc46f93 100644 --- a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java @@ -7,8 +7,8 @@ import com.bao.dating.pojo.dto.PostRequestDTO; import com.bao.dating.pojo.entity.Post; import com.bao.dating.pojo.vo.PostEditVO; import com.bao.dating.service.PostService; -import com.bao.dating.util.AliOssUtil; -import com.bao.dating.util.FileUtil; +import com.bao.dating.common.aliyun.AliOssUtil; +import com.bao.dating.common.aliyun.util.FileUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; From 08018ede830aad1280d2488edc4170d51557cad9 Mon Sep 17 00:00:00 2001 From: KilLze Date: Sat, 20 Dec 2025 17:17:09 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bao/dating/service/impl/PostServiceImpl.java | 2 +- .../java/com/bao/dating/{common/aliyun => }/util/FileUtil.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/java/com/bao/dating/{common/aliyun => }/util/FileUtil.java (95%) diff --git a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java index cc46f93..1dc9944 100644 --- a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java @@ -8,7 +8,7 @@ import com.bao.dating.pojo.entity.Post; import com.bao.dating.pojo.vo.PostEditVO; import com.bao.dating.service.PostService; import com.bao.dating.common.aliyun.AliOssUtil; -import com.bao.dating.common.aliyun.util.FileUtil; +import com.bao.dating.util.FileUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/bao/dating/common/aliyun/util/FileUtil.java b/src/main/java/com/bao/dating/util/FileUtil.java similarity index 95% rename from src/main/java/com/bao/dating/common/aliyun/util/FileUtil.java rename to src/main/java/com/bao/dating/util/FileUtil.java index d481ca1..5543dcd 100644 --- a/src/main/java/com/bao/dating/common/aliyun/util/FileUtil.java +++ b/src/main/java/com/bao/dating/util/FileUtil.java @@ -1,4 +1,4 @@ -package com.bao.dating.common.aliyun.util; +package com.bao.dating.util; /** * 文件工具类 From 3485577874262e4e32c85dd494cd663dbb7d862f Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Tue, 23 Dec 2025 00:36:34 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=88=86=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dating/controller/PostLikeController.java | 11 ++++++++++ .../com/bao/dating/service/PostService.java | 2 ++ .../dating/service/impl/PostServiceImpl.java | 21 ++++++++++++++++--- src/main/resources/application.yml | 6 +++--- .../bao/dating/DatingApplicationTests.java | 5 +---- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/bao/dating/controller/PostLikeController.java b/src/main/java/com/bao/dating/controller/PostLikeController.java index 2c6fa17..ef246e7 100644 --- a/src/main/java/com/bao/dating/controller/PostLikeController.java +++ b/src/main/java/com/bao/dating/controller/PostLikeController.java @@ -17,6 +17,12 @@ public class PostLikeController { @Autowired private PostLikeService postLikeService; + /** + * 点赞接口 + * @param postId + * @param body + * @return + */ @PostMapping("/{postId}/likes") public Result likePost(@PathVariable Long postId, @RequestBody Map body){ // 从请求体中取出 user_id @@ -27,6 +33,11 @@ public class PostLikeController { return postLikeService.likePost(postId,userId); } + /** + * 取消点赞接口 + * @param postId + * @param body + */ @DeleteMapping("/{postId}/likes") public void unlike(@PathVariable Long postId, @RequestBody Map body){ // 从请求体中获取 user_id diff --git a/src/main/java/com/bao/dating/service/PostService.java b/src/main/java/com/bao/dating/service/PostService.java index 1c69800..1021c0f 100644 --- a/src/main/java/com/bao/dating/service/PostService.java +++ b/src/main/java/com/bao/dating/service/PostService.java @@ -30,6 +30,8 @@ public interface PostService { */ void deletePostById(Long postId); + void deletePostById(Integer postId); + /** * 查询动态详情(用于编辑) * @param postId 动态ID diff --git a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java index c897f19..6a5e7af 100644 --- a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java @@ -104,7 +104,7 @@ public class PostServiceImpl implements PostService { } catch (Exception e) { throw new RuntimeException("文本审核失败"); } - // 文本审核结果 + String textSuggestion = (String) textResult.get("suggestion"); if ("block".equals(textSuggestion)) { throw new RuntimeException("动态内容违规,禁止发布"); @@ -145,7 +145,6 @@ public class PostServiceImpl implements PostService { post.setIsPublic(0); } } - post.setUpdatedAt(LocalDateTime.now()); post.setCreatedAt(LocalDateTime.now()); @@ -154,6 +153,11 @@ public class PostServiceImpl implements PostService { return post; } + @Override + public void deletePostById(Long postId) { + postMapper.deletePostById(postId); + } + /** * 删除动态 * @@ -161,7 +165,7 @@ public class PostServiceImpl implements PostService { * @return 删除的动态对象 */ @Override - public void deletePostById(Long postId) { + public void deletePostById(Integer postId) { postMapper.deletePostById(postId); } @@ -252,4 +256,15 @@ public class PostServiceImpl implements PostService { return postEditVO; } + /** + * 根据动态ID查询用户ID + * + * @param postId 动态ID + * @return 用户ID + */ + @Override + public Long selectUserIdByPostId(Long postId) { + return postMapper.selectUserIdByPostId(postId); + } + } \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8ab6301..79d366e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -20,9 +20,9 @@ mybatis: aliyun: oss: endpoint: oss-cn-beijing.aliyuncs.com - access-key-id: LTAI5tKo9TpWH1aW6JxWm1Gp - access-key-secret: LHk9DdHECKCwIdaIM9fkGgEuowt18W - bucket-name: heimato + access-key-id: LTAI5t5vpcbCZwweNHEDDDaF + access-key-secret: bBHBAPiCqGyVBHUv07348wsHXkKqrk + bucket-name: heimatoo accessKeyId: LTAI5t5vpcbCZwweNHEDDDaF secret: bBHBAPiCqGyVBHUv07348wsHXkKqrk scenes: antispam diff --git a/src/test/java/com/bao/dating/DatingApplicationTests.java b/src/test/java/com/bao/dating/DatingApplicationTests.java index 852efdf..46325b6 100644 --- a/src/test/java/com/bao/dating/DatingApplicationTests.java +++ b/src/test/java/com/bao/dating/DatingApplicationTests.java @@ -31,10 +31,7 @@ public class DatingApplicationTests { public void testUploadAndScanImageFromUrl() { try { // 阿里oss图片url - String imageUrl = "https://heimato.oss-cn-beijing.aliyuncs.com/75d067b3-8605-494a-a839-b0a9d32c993a.jpg" + - "?x-oss-credential=LTAI5tKo9TpWH1aW6JxWm1Gp%2F20251218%2Fcn-beijing%2Foss%2Faliyun_v4_request" + - "&x-oss-date=20251218T164128Z&x-oss-expires=32400&x-oss-signature-version=OSS4-HMAC-SHA256" + - "&x-oss-signature=e9c46381a5d33e5c541fe2e838ff3ebeeb5dbc51f792ed31ae992aa0a4109d8a"; + String imageUrl = "https://heimatoo.oss-cn-beijing.aliyuncs.com/ScreenShot_2025-12-01_135624_491.png?x-oss-credential=LTAI5t5vpcbCZwweNHEDDDaF%2F20251222%2Fcn-beijing%2Foss%2Faliyun_v4_request&x-oss-date=20251222T092951Z&x-oss-expires=32400&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-signature=c06742a4e530c7a095aa4c376c3c88e605dddcd232d0ee07da76988e5ccb7727"; // 将图片URL添加到列表中进行检测 List imageUrls = Arrays.asList(imageUrl); From fcdba51570e6ba3537d12a2e274284717bc5319c Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Tue, 23 Dec 2025 00:37:34 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=88=86=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bao/dating/service/impl/PostServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java index 6a5e7af..e6478cb 100644 --- a/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java +++ b/src/main/java/com/bao/dating/service/impl/PostServiceImpl.java @@ -166,7 +166,7 @@ public class PostServiceImpl implements PostService { */ @Override public void deletePostById(Integer postId) { - postMapper.deletePostById(postId); + postMapper.deletePostById(Long.valueOf(postId)); } @Override From c96af708df852f3010a47f4aeec7a6dc8333e1cf Mon Sep 17 00:00:00 2001 From: lihaiyang <3298329328@qq.com> Date: Tue, 23 Dec 2025 13:48:40 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E8=AF=84=E8=AE=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 11 ++++- .../java/com/bao/dating/common/Comments.java | 19 ++++++++ src/main/java/com/bao/dating/common/Post.java | 16 +++++++ .../dating/controller/CommentController.java | 48 +++++++++++++++++++ .../com/bao/dating/mapper/CommentsMapper.java | 22 +++++++++ .../bao/dating/service/CommentsService.java | 20 ++++++++ .../service/impl/CommentsServiceImpl.java | 39 +++++++++++++++ 7 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/bao/dating/common/Comments.java create mode 100644 src/main/java/com/bao/dating/common/Post.java create mode 100644 src/main/java/com/bao/dating/controller/CommentController.java create mode 100644 src/main/java/com/bao/dating/mapper/CommentsMapper.java create mode 100644 src/main/java/com/bao/dating/service/CommentsService.java create mode 100644 src/main/java/com/bao/dating/service/impl/CommentsServiceImpl.java diff --git a/pom.xml b/pom.xml index 2587f61..751755b 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,13 @@ spring-boot-starter + + + org.mybatis + mybatis + 3.5.10 + + org.springframework.boot spring-boot-starter-web @@ -123,8 +130,8 @@ maven-compiler-plugin 3.8.1 - 1.8 - 1.8 + 9 + 9 UTF-8 diff --git a/src/main/java/com/bao/dating/common/Comments.java b/src/main/java/com/bao/dating/common/Comments.java new file mode 100644 index 0000000..45e30b4 --- /dev/null +++ b/src/main/java/com/bao/dating/common/Comments.java @@ -0,0 +1,19 @@ +package com.bao.dating.common; + + +import lombok.Data; + +import java.time.LocalDateTime; + + +/** + * 评论表 + */ +@Data +public class Comments { + private Long comment_id; // 评论ID + private String content; // 评论内容 + private Long user_id; // 评论人ID + private Long post_id; // 关联动态ID + private LocalDateTime created_at; // 评论时间 +} diff --git a/src/main/java/com/bao/dating/common/Post.java b/src/main/java/com/bao/dating/common/Post.java new file mode 100644 index 0000000..10293a3 --- /dev/null +++ b/src/main/java/com/bao/dating/common/Post.java @@ -0,0 +1,16 @@ +package com.bao.dating.common; + + +import lombok.Data; + +import java.time.LocalDateTime; +/** + * 动态表 + */ +@Data +public class Post { + private Long post_id; // 动态ID + private String content; // 动态内容 + private Long user_id; // 发布人ID + private LocalDateTime created_at; // 创建时间 +} diff --git a/src/main/java/com/bao/dating/controller/CommentController.java b/src/main/java/com/bao/dating/controller/CommentController.java new file mode 100644 index 0000000..d377897 --- /dev/null +++ b/src/main/java/com/bao/dating/controller/CommentController.java @@ -0,0 +1,48 @@ +package com.bao.dating.controller; + + +import com.bao.dating.common.Comments; +import com.bao.dating.service.CommentsService; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/comments") +@CrossOrigin // 解决跨域问题(前后端分离必加) +public class CommentController { + @Resource + private CommentsService commentsService; + + /** + * 添加评论 + * @param comment 评论对象(含content、userId、dynamicId) + */ + @PostMapping("/add") + public Map addComment(@RequestBody Comments comment) { + boolean success = commentsService.addComment(comment); + return success ? Map.of("code", 200, "msg", "评论成功") : Map.of("code", 500, "msg", "评论失败"); + } + + /** + * 删除评论 + * @param user_id 评论ID + */ + @DeleteMapping("/delete/{user_id}") + public Map deleteComment(@PathVariable Long user_id) { + boolean success = commentsService.deleteComment(user_id); + return success ? Map.of("code", 200, "msg", "删除成功") : Map.of("code", 500, "msg", "删除失败"); + } + + /** + * 根据动态ID查询评论列表 + * @param post_id 动态ID + */ + @GetMapping("/list/{post_id}") + public Map getCommentList(@PathVariable Long post_id) { + List commentList = commentsService.getCommentByPostId(post_id); + return Map.of("code", 200, "data", commentList); + } +} diff --git a/src/main/java/com/bao/dating/mapper/CommentsMapper.java b/src/main/java/com/bao/dating/mapper/CommentsMapper.java new file mode 100644 index 0000000..26acdb3 --- /dev/null +++ b/src/main/java/com/bao/dating/mapper/CommentsMapper.java @@ -0,0 +1,22 @@ +package com.bao.dating.mapper; + + +import com.bao.dating.common.Comments; +import com.bao.dating.common.Post; +import org.apache.ibatis.annotations.*; + +import java.util.List; + +public interface CommentsMapper { + // 添加评论 + @Insert("INSERT INTO comments(content, user_id, post_id, created_at) VALUES(#{content}, #{user_id}, #{post_id}, #{created_at})") + int addComment(Comments comments); + + // 删除评论 + @Delete("DELETE FROM comments WHERE user_id = #{user_id}") + int deleteComments(@Param("user_id") Long user_id); + + // 根据动态ID查询评论列表 + @Select("SELECT * FROM comments WHERE post_id = #{post_id} ORDER BY created_at DESC") + List getCommentsByPostId(@Param("post_id") Long post_id); +} diff --git a/src/main/java/com/bao/dating/service/CommentsService.java b/src/main/java/com/bao/dating/service/CommentsService.java new file mode 100644 index 0000000..202a362 --- /dev/null +++ b/src/main/java/com/bao/dating/service/CommentsService.java @@ -0,0 +1,20 @@ +package com.bao.dating.service; + + +import com.bao.dating.common.Comments; + +import java.util.List; + +public interface CommentsService{ + // 添加评论 + boolean addComment(Comments comments); + + // 删除评论 + boolean deleteComment(Long user_id); + + // 根据动态ID查询评论 + List getCommentByPostId(Long post_id); + + + +} diff --git a/src/main/java/com/bao/dating/service/impl/CommentsServiceImpl.java b/src/main/java/com/bao/dating/service/impl/CommentsServiceImpl.java new file mode 100644 index 0000000..f7248da --- /dev/null +++ b/src/main/java/com/bao/dating/service/impl/CommentsServiceImpl.java @@ -0,0 +1,39 @@ +package com.bao.dating.service.impl; + +import com.bao.dating.common.Comments; + +import com.bao.dating.mapper.CommentsMapper; + + +import com.bao.dating.service.CommentsService; +import org.springframework.stereotype.Service; + + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; + +@Service +public class CommentsServiceImpl implements CommentsService { + + + + @Resource + private CommentsMapper commentsMapper; + + @Override + public boolean addComment(Comments comments) { + // 设置创建时间 + comments.setCreated_at(LocalDateTime.now()); + return commentsMapper.addComment(comments) > 0; + } + @Override + public boolean deleteComment(Long user_id) { + return commentsMapper.deleteComments(user_id) > 0; + } + + @Override + public List getCommentByPostId(Long post_id) { + return commentsMapper.getCommentsByPostId(post_id); + } +} From 73315535287efc8373bd2cc56fd7d4b9ce878ae3 Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Wed, 24 Dec 2025 21:34:13 +0800 Subject: [PATCH 15/16] =?UTF-8?q?init:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bao/dating/common/ResultCode.java | 3 ++- .../dating/controller/CommentController.java | 22 +++++++++++-------- .../java/com/bao/dating/controller/text.java | 4 ---- 3 files changed, 15 insertions(+), 14 deletions(-) delete mode 100644 src/main/java/com/bao/dating/controller/text.java diff --git a/src/main/java/com/bao/dating/common/ResultCode.java b/src/main/java/com/bao/dating/common/ResultCode.java index baf6419..d577366 100644 --- a/src/main/java/com/bao/dating/common/ResultCode.java +++ b/src/main/java/com/bao/dating/common/ResultCode.java @@ -8,7 +8,8 @@ public enum ResultCode { UNAUTHORIZED(401, "未登录或 Token 失效"), FORBIDDEN(403, "无权限"), NOT_FOUND(404, "数据不存在"), - SYSTEM_ERROR(500, "系统异常"); + SYSTEM_ERROR(500, "系统异常"), + FAIL(500, "操作失败"); private final int code; private final String msg; diff --git a/src/main/java/com/bao/dating/controller/CommentController.java b/src/main/java/com/bao/dating/controller/CommentController.java index d377897..4f49f00 100644 --- a/src/main/java/com/bao/dating/controller/CommentController.java +++ b/src/main/java/com/bao/dating/controller/CommentController.java @@ -1,17 +1,17 @@ package com.bao.dating.controller; - import com.bao.dating.common.Comments; +import com.bao.dating.common.Result; +import com.bao.dating.common.ResultCode; import com.bao.dating.service.CommentsService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; -import java.util.Map; @RestController @RequestMapping("/comments") -@CrossOrigin // 解决跨域问题(前后端分离必加) +@CrossOrigin public class CommentController { @Resource private CommentsService commentsService; @@ -21,9 +21,11 @@ public class CommentController { * @param comment 评论对象(含content、userId、dynamicId) */ @PostMapping("/add") - public Map addComment(@RequestBody Comments comment) { + public Result addComment(@RequestBody Comments comment) { boolean success = commentsService.addComment(comment); - return success ? Map.of("code", 200, "msg", "评论成功") : Map.of("code", 500, "msg", "评论失败"); + return success ? + Result.success(ResultCode.SUCCESS, "评论成功") : + Result.error(ResultCode.FAIL, "评论失败"); } /** @@ -31,9 +33,11 @@ public class CommentController { * @param user_id 评论ID */ @DeleteMapping("/delete/{user_id}") - public Map deleteComment(@PathVariable Long user_id) { + public Result deleteComment(@PathVariable Long user_id) { boolean success = commentsService.deleteComment(user_id); - return success ? Map.of("code", 200, "msg", "删除成功") : Map.of("code", 500, "msg", "删除失败"); + return success ? + Result.success(ResultCode.SUCCESS, "删除成功") : + Result.error(ResultCode.FAIL, "删除失败"); } /** @@ -41,8 +45,8 @@ public class CommentController { * @param post_id 动态ID */ @GetMapping("/list/{post_id}") - public Map getCommentList(@PathVariable Long post_id) { + public Result> getCommentList(@PathVariable Long post_id) { List commentList = commentsService.getCommentByPostId(post_id); - return Map.of("code", 200, "data", commentList); + return Result.success(ResultCode.SUCCESS, commentList); } } diff --git a/src/main/java/com/bao/dating/controller/text.java b/src/main/java/com/bao/dating/controller/text.java deleted file mode 100644 index 7806c8a..0000000 --- a/src/main/java/com/bao/dating/controller/text.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.bao.dating.controller; - -public class text { -} From d5ec858b06f77d82c27a32e4a23a1730594c61b8 Mon Sep 17 00:00:00 2001 From: bao <19271189822@163.com> Date: Wed, 24 Dec 2025 23:13:50 +0800 Subject: [PATCH 16/16] =?UTF-8?q?init:=20=E6=B7=BB=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 32 +++ .../com/bao/dating/common/aliyun/SmsUtil.java | 149 +++++++++++++ .../java/com/bao/dating/util/EmailUtil.java | 178 +++++++++++++++ .../java/com/bao/dating/util/JwtUtil.java | 204 ++++++++++++++++++ .../java/com/bao/dating/util/MD5Util.java | 91 ++++++++ src/main/resources/application.yml | 26 +++ .../com/bao/dating/util/EmailAndSmsTest.java | 75 +++++++ 7 files changed, 755 insertions(+) create mode 100644 src/main/java/com/bao/dating/common/aliyun/SmsUtil.java create mode 100644 src/main/java/com/bao/dating/util/EmailUtil.java create mode 100644 src/main/java/com/bao/dating/util/JwtUtil.java create mode 100644 src/main/java/com/bao/dating/util/MD5Util.java create mode 100644 src/test/java/com/bao/dating/util/EmailAndSmsTest.java diff --git a/pom.xml b/pom.xml index 751755b..aa960d4 100644 --- a/pom.xml +++ b/pom.xml @@ -110,6 +110,38 @@ 0.2.8 + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + + com.aliyun + dysmsapi20170525 + 3.0.0 + + + + + org.springframework.boot + spring-boot-starter-mail + + diff --git a/src/main/java/com/bao/dating/common/aliyun/SmsUtil.java b/src/main/java/com/bao/dating/common/aliyun/SmsUtil.java new file mode 100644 index 0000000..1083218 --- /dev/null +++ b/src/main/java/com/bao/dating/common/aliyun/SmsUtil.java @@ -0,0 +1,149 @@ +package com.bao.dating.common.aliyun; + +import com.aliyun.dysmsapi20170525.Client; +import com.aliyun.dysmsapi20170525.models.SendSmsRequest; +import com.aliyun.dysmsapi20170525.models.SendSmsResponse; +import com.aliyun.teaopenapi.models.Config; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * 阿里云短信服务工具类 + * @author KilLze + */ +@Data +@Slf4j +@Component +@ConfigurationProperties(prefix = "aliyun.sms") +public class SmsUtil { + + /** + * 访问密钥ID + */ + private String accessKeyId; + + /** + * 访问密钥Secret + */ + private String accessKeySecret; + + /** + * 短信服务区域节点 + */ + private String regionId = "cn-hangzhou"; + + /** + * 默认签名名称 + */ + private String signName; + + /** + * 默认模板代码 + */ + private String templateCode; + + /** + * 创建短信客户端 + * @return Client对象 + * @throws Exception 创建失败时抛出异常 + */ + private Client createClient() throws Exception { + Config config = new Config() + .setAccessKeyId(accessKeyId) + .setAccessKeySecret(accessKeySecret) + .setEndpoint("dysmsapi.aliyuncs.com"); + return new Client(config); + } + + /** + * 发送短信 + * @param phoneNumber 手机号码 + * @param templateCode 模板代码(如果为空则使用默认模板代码) + * @param templateParam 模板参数(JSON格式字符串,如:{"code":"123456"}) + * @return 是否发送成功 + */ + public boolean sendSms(String phoneNumber, String templateCode, String templateParam) { + try { + Client client = createClient(); + SendSmsRequest sendSmsRequest = new SendSmsRequest() + .setPhoneNumbers(phoneNumber) + .setSignName(signName) + .setTemplateCode(templateCode != null ? templateCode : this.templateCode) + .setTemplateParam(templateParam); + + SendSmsResponse response = client.sendSms(sendSmsRequest); + + if ("OK".equals(response.getBody().getCode())) { + log.info("短信发送成功,手机号:{},请求ID:{}", phoneNumber, response.getBody().getRequestId()); + return true; + } else { + log.error("短信发送失败,手机号:{},错误码:{},错误信息:{}", + phoneNumber, response.getBody().getCode(), response.getBody().getMessage()); + return false; + } + } catch (Exception e) { + log.error("发送短信异常,手机号:{},异常信息:{}", phoneNumber, e.getMessage(), e); + return false; + } + } + + /** + * 发送短信(使用默认模板代码) + * @param phoneNumber 手机号码 + * @param templateParam 模板参数(JSON格式字符串) + * @return 是否发送成功 + */ + public boolean sendSms(String phoneNumber, String templateParam) { + return sendSms(phoneNumber, null, templateParam); + } + + /** + * 发送验证码短信 + * @param phoneNumber 手机号码 + * @param code 验证码 + * @return 是否发送成功 + */ + public boolean sendVerificationCode(String phoneNumber, String code) { + String templateParam = String.format("{\"code\":\"%s\"}", code); + return sendSms(phoneNumber, templateParam); + } + + /** + * 发送验证码短信(使用指定模板代码) + * @param phoneNumber 手机号码 + * @param code 验证码 + * @param templateCode 模板代码 + * @return 是否发送成功 + */ + public boolean sendVerificationCode(String phoneNumber, String code, String templateCode) { + String templateParam = String.format("{\"code\":\"%s\"}", code); + return sendSms(phoneNumber, templateCode, templateParam); + } + + /** + * 发送短信(使用Map参数) + * @param phoneNumber 手机号码 + * @param templateCode 模板代码 + * @param params 模板参数Map + * @return 是否发送成功 + */ + public boolean sendSmsWithParams(String phoneNumber, String templateCode, Map params) { + StringBuilder jsonBuilder = new StringBuilder("{"); + boolean first = true; + for (Map.Entry entry : params.entrySet()) { + if (!first) { + jsonBuilder.append(","); + } + jsonBuilder.append("\"").append(entry.getKey()).append("\":\"") + .append(entry.getValue()).append("\""); + first = false; + } + jsonBuilder.append("}"); + return sendSms(phoneNumber, templateCode, jsonBuilder.toString()); + } +} + diff --git a/src/main/java/com/bao/dating/util/EmailUtil.java b/src/main/java/com/bao/dating/util/EmailUtil.java new file mode 100644 index 0000000..afcb813 --- /dev/null +++ b/src/main/java/com/bao/dating/util/EmailUtil.java @@ -0,0 +1,178 @@ +package com.bao.dating.util; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Component; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.File; + +/** + * 邮箱工具类 + * 提供邮件发送功能(支持普通文本邮件和HTML邮件) + * @author KilLze + */ +@Slf4j +@Component +public class EmailUtil { + + /** + * 邮件发送器(由Spring自动注入) + */ + private final JavaMailSender mailSender; + + /** + * 发件人邮箱地址(从配置中读取) + */ + private final String from; + + /** + * 构造函数,用于注入JavaMailSender和配置 + * @param mailSender 邮件发送器 + * @param from 发件人邮箱地址 + */ + public EmailUtil(JavaMailSender mailSender, @Value("${spring.mail.username}") String from) { + this.mailSender = mailSender; + this.from = from; + } + + /** + * 发送简单文本邮件 + * @param to 收件人邮箱地址 + * @param subject 邮件主题 + * @param text 邮件内容 + * @return 是否发送成功 + */ + public boolean sendSimpleMail(String to, String subject, String text) { + try { + SimpleMailMessage message = new SimpleMailMessage(); + message.setFrom(from); + message.setTo(to); + message.setSubject(subject); + message.setText(text); + mailSender.send(message); + log.info("简单邮件发送成功,收件人:{},主题:{}", to, subject); + return true; + } catch (Exception e) { + log.error("简单邮件发送失败,收件人:{},异常信息:{}", to, e.getMessage(), e); + return false; + } + } + + /** + * 发送HTML格式邮件 + * @param to 收件人邮箱地址 + * @param subject 邮件主题 + * @param htmlContent HTML内容 + * @return 是否发送成功 + */ + public boolean sendHtmlMail(String to, String subject, String htmlContent) { + try { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + helper.setFrom(from); + helper.setTo(to); + helper.setSubject(subject); + helper.setText(htmlContent, true); + mailSender.send(message); + log.info("HTML邮件发送成功,收件人:{},主题:{}", to, subject); + return true; + } catch (MessagingException e) { + log.error("HTML邮件发送失败,收件人:{},异常信息:{}", to, e.getMessage(), e); + return false; + } + } + + /** + * 发送带附件的邮件 + * @param to 收件人邮箱地址 + * @param subject 邮件主题 + * @param text 邮件内容 + * @param attachmentPath 附件文件路径 + * @param attachmentName 附件显示名称 + * @return 是否发送成功 + */ + public boolean sendMailWithAttachment(String to, String subject, String text, + String attachmentPath, String attachmentName) { + try { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + helper.setFrom(from); + helper.setTo(to); + helper.setSubject(subject); + helper.setText(text); + + File file = new File(attachmentPath); + if (file.exists()) { + helper.addAttachment(attachmentName, file); + } else { + log.warn("附件文件不存在:{}", attachmentPath); + return false; + } + + mailSender.send(message); + log.info("带附件邮件发送成功,收件人:{},主题:{},附件:{}", to, subject, attachmentName); + return true; + } catch (MessagingException e) { + log.error("带附件邮件发送失败,收件人:{},异常信息:{}", to, e.getMessage(), e); + return false; + } + } + + /** + * 发送验证码邮件 + * @param to 收件人邮箱地址 + * @param code 验证码 + * @return 是否发送成功 + */ + public boolean sendVerificationCode(String to, String code) { + String subject = "验证码"; + String htmlContent = String.format( + "" + + "

您的验证码

" + + "

验证码:%s

" + + "

验证码有效期为10分钟,请勿泄露给他人。

" + + "", code); + return sendHtmlMail(to, subject, htmlContent); + } + + /** + * 发送验证码邮件(自定义主题) + * @param to 收件人邮箱地址 + * @param code 验证码 + * @param subject 邮件主题 + * @return 是否发送成功 + */ + public boolean sendVerificationCode(String to, String code, String subject) { + String htmlContent = String.format( + "" + + "

您的验证码

" + + "

验证码:%s

" + + "

验证码有效期为10分钟,请勿泄露给他人。

" + + "", code); + return sendHtmlMail(to, subject, htmlContent); + } + + /** + * 批量发送邮件 + * @param toList 收件人邮箱地址数组 + * @param subject 邮件主题 + * @param text 邮件内容 + * @return 成功发送的数量 + */ + public int sendBatchMail(String[] toList, String subject, String text) { + int successCount = 0; + for (String to : toList) { + if (sendSimpleMail(to, subject, text)) { + successCount++; + } + } + log.info("批量邮件发送完成,总数:{},成功:{}", toList.length, successCount); + return successCount; + } +} + diff --git a/src/main/java/com/bao/dating/util/JwtUtil.java b/src/main/java/com/bao/dating/util/JwtUtil.java new file mode 100644 index 0000000..002b887 --- /dev/null +++ b/src/main/java/com/bao/dating/util/JwtUtil.java @@ -0,0 +1,204 @@ +package com.bao.dating.util; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; + +import javax.crypto.SecretKey; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * JWT工具类 + * 提供JWT Token的生成、解析和验证功能 + * @author KilLze + */ +public class JwtUtil { + + /** + * 默认密钥(建议从配置文件读取) + */ + private static final String DEFAULT_SECRET = "dating-application-secret-key-for-jwt-token-generation-2025"; + + /** + * 默认过期时间(毫秒)- 7天 + */ + private static final long DEFAULT_EXPIRATION = 7 * 24 * 60 * 60 * 1000L; + + /** + * 生成JWT Token + * @param subject 主题(通常是用户ID或用户名) + * @return JWT Token字符串 + */ + public static String generateToken(String subject) { + return generateToken(subject, DEFAULT_EXPIRATION); + } + + /** + * 生成JWT Token(自定义过期时间) + * @param subject 主题(通常是用户ID或用户名) + * @param expiration 过期时间(毫秒) + * @return JWT Token字符串 + */ + public static String generateToken(String subject, long expiration) { + return generateToken(subject, expiration, null); + } + + /** + * 生成JWT Token(带自定义claims) + * @param subject 主题(通常是用户ID或用户名) + * @param expiration 过期时间(毫秒) + * @param claims 自定义claims + * @return JWT Token字符串 + */ + public static String generateToken(String subject, long expiration, Map claims) { + Date now = new Date(); + Date expiryDate = new Date(now.getTime() + expiration); + + SecretKey key = getSecretKey(); + + if (claims == null) { + claims = new HashMap<>(); + } + + return Jwts.builder() + .setClaims(claims) + .setSubject(subject) + .setIssuedAt(now) + .setExpiration(expiryDate) + .signWith(key, SignatureAlgorithm.HS256) + .compact(); + } + + /** + * 生成JWT Token(使用自定义密钥) + * @param subject 主题 + * @param expiration 过期时间(毫秒) + * @param secret 自定义密钥 + * @return JWT Token字符串 + */ + public static String generateTokenWithSecret(String subject, long expiration, String secret) { + Date now = new Date(); + Date expiryDate = new Date(now.getTime() + expiration); + + SecretKey key = getSecretKey(secret); + + return Jwts.builder() + .setSubject(subject) + .setIssuedAt(now) + .setExpiration(expiryDate) + .signWith(key, SignatureAlgorithm.HS256) + .compact(); + } + + /** + * 从Token中获取Claims + * @param token JWT Token + * @return Claims对象 + */ + public static Claims getClaimsFromToken(String token) { + return getClaimsFromToken(token, DEFAULT_SECRET); + } + + /** + * 从Token中获取Claims(使用自定义密钥) + * @param token JWT Token + * @param secret 密钥 + * @return Claims对象 + */ + public static Claims getClaimsFromToken(String token, String secret) { + try { + SecretKey key = getSecretKey(secret); + return Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + throw new RuntimeException("解析JWT Token失败", e); + } + } + + /** + * 从Token中获取主题(通常是用户ID) + * @param token JWT Token + * @return 主题字符串 + */ + public static String getSubjectFromToken(String token) { + Claims claims = getClaimsFromToken(token); + return claims.getSubject(); + } + + /** + * 验证Token是否有效 + * @param token JWT Token + * @return 是否有效 + */ + public static boolean validateToken(String token) { + return validateToken(token, DEFAULT_SECRET); + } + + /** + * 验证Token是否有效(使用自定义密钥) + * @param token JWT Token + * @param secret 密钥 + * @return 是否有效 + */ + public static boolean validateToken(String token, String secret) { + try { + Claims claims = getClaimsFromToken(token, secret); + return !isTokenExpired(claims); + } catch (Exception e) { + return false; + } + } + + /** + * 检查Token是否过期 + * @param claims Claims对象 + * @return 是否过期 + */ + private static boolean isTokenExpired(Claims claims) { + Date expiration = claims.getExpiration(); + return expiration.before(new Date()); + } + + /** + * 获取Token的过期时间 + * @param token JWT Token + * @return 过期时间 + */ + public static Date getExpirationDateFromToken(String token) { + Claims claims = getClaimsFromToken(token); + return claims.getExpiration(); + } + + /** + * 获取默认密钥的SecretKey对象 + * @return SecretKey对象 + */ + private static SecretKey getSecretKey() { + return getSecretKey(DEFAULT_SECRET); + } + + /** + * 根据字符串密钥生成SecretKey对象 + * @param secret 密钥字符串 + * @return SecretKey对象 + */ + private static SecretKey getSecretKey(String secret) { + // 确保密钥长度至少为256位(32字节)以支持HS256算法 + byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8); + if (keyBytes.length < 32) { + // 如果密钥太短,进行填充 + byte[] paddedKey = new byte[32]; + System.arraycopy(keyBytes, 0, paddedKey, 0, Math.min(keyBytes.length, 32)); + return Keys.hmacShaKeyFor(paddedKey); + } + return Keys.hmacShaKeyFor(keyBytes); + } +} + diff --git a/src/main/java/com/bao/dating/util/MD5Util.java b/src/main/java/com/bao/dating/util/MD5Util.java new file mode 100644 index 0000000..cfc5518 --- /dev/null +++ b/src/main/java/com/bao/dating/util/MD5Util.java @@ -0,0 +1,91 @@ +package com.bao.dating.util; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * MD5工具类 + * 提供MD5加密功能 + * @author KilLze + */ +public class MD5Util { + + /** + * 对字符串进行MD5加密 + * @param input 待加密的字符串 + * @return MD5加密后的32位小写字符串 + */ + public static String encrypt(String input) { + if (input == null || input.isEmpty()) { + return null; + } + + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] digest = md.digest(input.getBytes()); + return bytesToHex(digest); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("MD5算法不可用", e); + } + } + + /** + * 对字符串进行MD5加密(带盐值) + * @param input 待加密的字符串 + * @param salt 盐值 + * @return MD5加密后的32位小写字符串 + */ + public static String encryptWithSalt(String input, String salt) { + if (input == null || input.isEmpty()) { + return null; + } + if (salt == null) { + salt = ""; + } + return encrypt(input + salt); + } + + /** + * 验证字符串与MD5值是否匹配 + * @param input 原始字符串 + * @param md5Hash MD5哈希值 + * @return 是否匹配 + */ + public static boolean verify(String input, String md5Hash) { + if (input == null || md5Hash == null) { + return false; + } + return encrypt(input).equalsIgnoreCase(md5Hash); + } + + /** + * 验证字符串与MD5值是否匹配(带盐值) + * @param input 原始字符串 + * @param salt 盐值 + * @param md5Hash MD5哈希值 + * @return 是否匹配 + */ + public static boolean verifyWithSalt(String input, String salt, String md5Hash) { + if (input == null || md5Hash == null) { + return false; + } + if (salt == null) { + salt = ""; + } + return encryptWithSalt(input, salt).equalsIgnoreCase(md5Hash); + } + + /** + * 将字节数组转换为十六进制字符串 + * @param bytes 字节数组 + * @return 十六进制字符串 + */ + private static String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } +} + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 79d366e..8bcdeac 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,6 +7,25 @@ spring: username: root password: JoyeeServe2025 driver-class-name: com.mysql.cj.jdbc.Driver + # 邮箱SMTP配置 + mail: + host: smtp.163.com # QQ邮箱SMTP服务器地址 + port: 465 # SMTP端口 + username: 19271189822@163.com # 发件人邮箱 + password: CAwXh39PXajy3fyH # 邮箱授权码 + default-encoding: UTF-8 + properties: + mail: + smtp: + auth: true + starttls: + enable: true + required: true + ssl: + enable: true # 使用587端口时设为false,使用465端口时设为true + connectiontimeout: 10000 # 连接超时时间(毫秒) + timeout: 10000 # 读取超时时间(毫秒) + writetimeout: 10000 # 写入超时时间(毫秒) # MyBatis 配置 mybatis: @@ -26,3 +45,10 @@ aliyun: accessKeyId: LTAI5t5vpcbCZwweNHEDDDaF secret: bBHBAPiCqGyVBHUv07348wsHXkKqrk scenes: antispam + # 阿里云短信服务配置 +# sms: +# access-key-id: LTAI5t5vpcbCZwweNHEDDDaF +# access-key-secret: bBHBAPiCqGyVBHUv07348wsHXkKqrk +# region-id: cn-hangzhou +# sign-name: +# template-code: SMS_123456789 diff --git a/src/test/java/com/bao/dating/util/EmailAndSmsTest.java b/src/test/java/com/bao/dating/util/EmailAndSmsTest.java new file mode 100644 index 0000000..49c80d9 --- /dev/null +++ b/src/test/java/com/bao/dating/util/EmailAndSmsTest.java @@ -0,0 +1,75 @@ +package com.bao.dating.util; + +import com.bao.dating.common.aliyun.SmsUtil; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.HashMap; +import java.util.Map; + +/** + * 邮箱和短信发送测试类 + * @author KilLze + */ +@SpringBootTest +public class EmailAndSmsTest { + + @Autowired + private EmailUtil emailUtil; + + @Autowired + private SmsUtil smsUtil; + + /** + * 测试发送简单文本邮件 + */ + @Test + public void testSendSimpleMail() { + String to = "n_1127@qq.com"; + String subject = "测试邮件 - 简单文本"; + String text = "这是一封测试邮件,用于测试简单文本邮件发送功能。\n\n如果您收到此邮件,说明邮件发送功能正常。"; + + boolean result = emailUtil.sendSimpleMail(to, subject, text); + System.out.println("简单邮件发送结果: " + (result ? "成功" : "失败")); + } + + /** + * 测试发送HTML格式邮件 + */ + @Test + public void testSendHtmlMail() { + String to = "n_1127@qq.com"; + String subject = "测试邮件 - HTML格式"; + String htmlContent = "" + + "

欢迎使用我们的服务

" + + "

这是一封HTML格式的测试邮件。

" + + "

邮件内容支持:

" + + "
    " + + "
  • HTML标签
  • " + + "
  • 样式设置
  • " + + "
  • 富文本内容
  • " + + "
" + + "

感谢您的使用!

" + + ""; + + boolean result = emailUtil.sendHtmlMail(to, subject, htmlContent); + System.out.println("HTML邮件发送结果: " + (result ? "成功" : "失败")); + } + + /** + * 测试发送验证码邮件 + */ + @Test + public void testSendVerificationCodeEmail() { + String to = "n_1127@qq.com"; + String code = "123456"; + + boolean result = emailUtil.sendVerificationCode(to, code); + System.out.println("验证码邮件发送结果: " + (result ? "成功" : "失败")); + System.out.println("验证码: " + code); + } + + +} +