24 Commits

Author SHA1 Message Date
bao
d20ce917a2 init: 合并代码 2025-12-24 23:55:00 +08:00
bao
d8b16e0287 Merge remote-tracking branch 'refs/remotes/origin/master' into feature-Post
# Conflicts:
#	src/main/java/com/bao/dating/controller/PostController.java
2025-12-24 23:54:29 +08:00
bao
d5ec858b06 init: 添加工具类 2025-12-24 23:13:50 +08:00
bao
7331553528 init: 优化代码 2025-12-24 21:34:13 +08:00
bao
6a51eb48e4 Merge branch 'refs/heads/dev' 2025-12-23 14:09:57 +08:00
bao
2fe875a6ae Merge remote-tracking branch 'refs/remotes/origin/feature-Comment' into dev 2025-12-23 14:07:54 +08:00
lihaiyang
c96af708df 评论功能 2025-12-23 13:48:40 +08:00
bao
fcdba51570 合并分区 2025-12-23 00:37:34 +08:00
bao
3485577874 合并分区 2025-12-23 00:36:34 +08:00
bao
dbf303c03d Merge remote-tracking branch 'refs/remotes/origin/feature-PostLike' into dev
# Conflicts:
#	src/main/java/com/bao/dating/mapper/PostMapper.java
#	src/main/java/com/bao/dating/service/PostService.java
#	src/main/java/com/bao/dating/service/impl/PostServiceImpl.java
2025-12-23 00:31:28 +08:00
KilLze
08018ede83 优化文件上传功能 2025-12-20 17:17:09 +08:00
KilLze
0149008eb0 优化文件上传功能 2025-12-20 17:13:59 +08:00
2c4504090c 完成收藏模块 2025-12-20 11:27:05 +08:00
ee708724ab 完成收藏模块 2025-12-20 11:19:56 +08:00
KilLze
0ce96c3104 优化审核,审核未通过依旧会加入数据库,并将动态状态改为2(未通过),若有嫌疑则改为1进行人工审核,通过则为0
新增动态修改功能,可以修改文本,图片,标签,修改内容若审核未通过则将状态改为2,若有嫌疑则改为1进行人工审核,通过则改为0
2025-12-19 20:21:47 +08:00
KilLze
756fbd1a31 修改遍历图片审查,实现图片全部审察 2025-12-19 02:20:02 +08:00
bao
17877753d5 Merge pull request 'feature-PostLike' (#3) from feature-PostLike into master
Reviewed-on: makefriends/dating#3
2025-12-19 02:07:09 +08:00
bao
8d9f2285e4 测试 like123 2025-12-19 02:05:22 +08:00
bao
b1ea85b5e4 测试 like 2025-12-19 02:02:48 +08:00
bao
e5f411e342 测试 like 2025-12-19 01:58:09 +08:00
bao
80ede2ad2f Merge remote-tracking branch 'origin/feature-PostLike' into feature-PostLike
# Conflicts:
#	src/main/java/com/bao/dating/controller/PostController.java
2025-12-19 01:56:47 +08:00
bao
088e5612d3 测试 2025-12-19 01:56:15 +08:00
bao
2d3ac68886 测试 2025-12-19 01:55:23 +08:00
bao
bc3ffac3db 测试 2025-12-19 01:54:29 +08:00
32 changed files with 1442 additions and 100 deletions

43
pom.xml
View File

@@ -19,6 +19,13 @@
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@@ -103,6 +110,38 @@
<version>0.2.8</version>
</dependency>
<!-- JWT 相关依赖 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- 阿里云短信服务SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>3.0.0</version>
</dependency>
<!-- Spring Mail 邮件发送 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
@@ -123,8 +162,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>9</source>
<target>9</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>

View File

@@ -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; // 评论时间
}

View File

@@ -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; // 创建时间
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -61,19 +61,24 @@ public class GreenImageScan {
if (scanImageResponse.getStatusCode() == 200) {
List<ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults> subResults = scanImageResponse.body.data.results.get(0).getSubResults();
List<ScanImageResponseBody.ScanImageResponseBodyDataResults> results = scanImageResponse.body.data.results;
ListIterator<ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults> listIterator = subResults.listIterator();
while (listIterator.hasNext()) {
ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults item = listIterator.next();
// 遍历每一张图片的审核结果
for (ScanImageResponseBody.ScanImageResponseBodyDataResults result : results) {
List<ScanImageResponseBody.ScanImageResponseBodyDataResultsSubResults> subResults = result.getSubResults();
if (!item.suggestion.equals("pass")) {
resultMap.put("suggestion", item.suggestion);
resultMap.put("label", item.label);
// 检查这张图片的所有子审核项
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;

View File

@@ -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<String, String> params) {
StringBuilder jsonBuilder = new StringBuilder("{");
boolean first = true;
for (Map.Entry<String, String> 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());
}
}

View File

@@ -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());
}
}

View File

@@ -0,0 +1,52 @@
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;
@RestController
@RequestMapping("/comments")
@CrossOrigin
public class CommentController {
@Resource
private CommentsService commentsService;
/**
* 添加评论
* @param comment 评论对象含content、userId、dynamicId
*/
@PostMapping("/add")
public Result<String> addComment(@RequestBody Comments comment) {
boolean success = commentsService.addComment(comment);
return success ?
Result.success(ResultCode.SUCCESS, "评论成功") :
Result.error(ResultCode.FAIL, "评论失败");
}
/**
* 删除评论
* @param user_id 评论ID
*/
@DeleteMapping("/delete/{user_id}")
public Result<String> deleteComment(@PathVariable Long user_id) {
boolean success = commentsService.deleteComment(user_id);
return success ?
Result.success(ResultCode.SUCCESS, "删除成功") :
Result.error(ResultCode.FAIL, "删除失败");
}
/**
* 根据动态ID查询评论列表
* @param post_id 动态ID
*/
@GetMapping("/list/{post_id}")
public Result<List<Comments>> getCommentList(@PathVariable Long post_id) {
List<Comments> commentList = commentsService.getCommentByPostId(post_id);
return Result.success(ResultCode.SUCCESS, commentList);
}
}

View File

@@ -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.*;
@@ -53,4 +54,27 @@ public class PostController {
postService.deletePostById(postId);
return Result.success(ResultCode.SUCCESS_DELETE, "动态删除成功", null);
}
/**
* 根据ID查询动态接口
* @param postId 动态ID
* @return 动态对象
*/
@GetMapping("/{postId}")
public Result<PostEditVO> 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<PostEditVO> updatePost(@PathVariable Long postId, @RequestBody PostRequestDTO postRequestDTO) {
PostEditVO result = postService.updatePost(postId, postRequestDTO);
return Result.success(ResultCode.SUCCESS_REVIEW, "动态更新成功", result);
}
}

View File

@@ -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<Map<String,Long>> 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);
}
}

View File

@@ -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<String, Long> 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<String, Long> body){
// 从请求体中获取 user_id

View File

@@ -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<Comments> getCommentsByPostId(@Param("post_id") Long post_id);
}

View File

@@ -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<Long> selectUserIDByPostID(@Param("postId") Long postId);
int addPostFavorite(PostFavorite postFavorite);
int deletePostFavorite(@Param("postId") Long postId);
}

View File

@@ -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,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);
}

View File

@@ -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<String> mediaOssKeys;
private List<String> tags;
private List<String> mediaUrls;
}

View File

@@ -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<String> mediaOssKeys;
private List<String> tags;
private Integer isPublic;
private LocalDateTime updatedAt;
}

View File

@@ -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;
}

View File

@@ -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<Comments> getCommentByPostId(Long post_id);
}

View File

@@ -0,0 +1,10 @@
package com.bao.dating.service;
import com.bao.dating.common.Result;
import java.util.Map;
public interface PostFavoriteService {
Result<Map<String,Long>> postFavorite(Long userid,Long postId);
Result<?> deletePostFavorite(Long userid,Long postId);
}

View File

@@ -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,7 +17,8 @@ public interface PostService {
/**
* 创建动态
* @param postRequestDTO 动态请求数据传输对象
*
* @param postRequestDTO 动态数据传输对象
* @return 创建的动态对象
*/
Post createPost(PostRequestDTO postRequestDTO);
@@ -26,5 +28,28 @@ public interface PostService {
* @param postId 动态ID
* @return 删除的动态对象
*/
void deletePostById(Long postId);
void deletePostById(Integer postId);
/**
* 查询动态详情(用于编辑)
* @param postId 动态ID
*/
PostEditVO getPostForEdit(Long postId);
/**
* 修改动态
* @param postId 动态ID
* @param postRequestDTO 修改的动态数据传输对象
* @return 修改后的动态对象
*/
PostEditVO updatePost(Long postId, PostRequestDTO postRequestDTO);
/**
* 查询
* @param postId 动态id
* @return 用户id
*/
Long selectUserIdByPostId(Long postId);
}

View File

@@ -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<Comments> getCommentByPostId(Long post_id) {
return commentsMapper.getCommentsByPostId(post_id);
}
}

View File

@@ -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<Map<String, Long>> postFavorite(Long userid, Long postId) {
Long userId = postMapper.selectUserIdByPostId(postId);
if (userid.equals(userId)){
return Result.error(ResultCode.FORBIDDEN,"无法收藏自己发布动态");
}
List<Long> 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<String, Long> 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<Long> allUserId = postFavoriteMapper.selectUserIDByPostID(postId);
if (! allUserId.contains(userid)){
return Result.error(ResultCode.FORBIDDEN,"请先收藏");
}
postFavoriteMapper.deletePostFavorite(postId);
postMapper.decreaseFavoriteCount(postId);
return null;
}
}

View File

@@ -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.common.aliyun.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,12 +79,23 @@ public class PostServiceImpl implements PostService {
/**
* 创建动态
*
* @param postRequestDTO 动态请求数据传输对象
* @param postRequestDTO 动态数据传输对象
* @return 创建的动态对象
*/
@Override
public Post createPost(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;
try {
@@ -97,37 +110,39 @@ public class PostServiceImpl implements PostService {
}
// 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);
}
// 图片审核结果
String imageSuggestion = (String) imageResult.get("suggestion");
if ("block".equals(imageResult.get("suggestion"))) {
throw new RuntimeException("图片内容违规,禁止发布");
}
}
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)) {
// 根据审核结果设置状态
if ("block".equals(textSuggestion) || "block".equals(imageSuggestion)) {
// 审核未通过,允许用户修改
post.setIsPublic(2);
} else if ("review".equals(textSuggestion) || "review".equals(imageSuggestion)) {
// 待审核,需人工审核
post.setIsPublic(0);
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.setUpdatedAt(LocalDateTime.now());
post.setCreatedAt(LocalDateTime.now());
@@ -137,6 +152,11 @@ public class PostServiceImpl implements PostService {
return post;
}
@Override
public void deletePostById(Long postId) {
postMapper.deletePostById(postId);
}
/**
* 删除动态
*
@@ -145,6 +165,105 @@ public class PostServiceImpl implements PostService {
*/
@Override
public void deletePostById(Integer postId) {
postMapper.deletePostById(postId);
postMapper.deletePostById(Long.valueOf(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;
}
/**
* 根据动态ID查询用户ID
*
* @param postId 动态ID
* @return 用户ID
*/
@Override
public Long selectUserIdByPostId(Long postId) {
return postMapper.selectUserIdByPostId(postId);
}
}

View File

@@ -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(
"<html><body>" +
"<h2>您的验证码</h2>" +
"<p>验证码:<strong style='color: #1890ff; font-size: 24px;'>%s</strong></p>" +
"<p>验证码有效期为10分钟请勿泄露给他人。</p>" +
"</body></html>", 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(
"<html><body>" +
"<h2>您的验证码</h2>" +
"<p>验证码:<strong style='color: #1890ff; font-size: 24px;'>%s</strong></p>" +
"<p>验证码有效期为10分钟请勿泄露给他人。</p>" +
"</body></html>", 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;
}
}

View File

@@ -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<String, Object> 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);
}
}

View File

@@ -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();
}
}

View File

@@ -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:
@@ -20,9 +39,16 @@ 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
# 阿里云短信服务配置
# sms:
# access-key-id: LTAI5t5vpcbCZwweNHEDDDaF
# access-key-secret: bBHBAPiCqGyVBHUv07348wsHXkKqrk
# region-id: cn-hangzhou
# sign-name:
# template-code: SMS_123456789

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bao.dating.mapper.PostFavoriteMapper">
<!--添加动态收藏-->
<insert id="addPostFavorite">
insert into post_favorite values (null,#{userId},#{postId},#{createdAt})
</insert>
<!--删除动态收藏-->
<delete id="deletePostFavorite">
delete from post_favorite where post_id = #{postId}
</delete>
<!--查询当前已收藏所有用户-->
<select id="selectUserIDByPostID" resultType="java.lang.Long">
SELECT user_id FROM post_favorite WHERE post_id = #{postId}
</select>
</mapper>

View File

@@ -29,10 +29,60 @@
</insert>
<!--动态删除-->
<delete id="deletePostById" parameterType="int">
<delete id="deletePostById">
DELETE FROM post WHERE post_id = #{postId}
</delete>
<!--动态查询-->
<resultMap id="PostResultMap" type="com.bao.dating.pojo.entity.Post">
<id property="postId" column="post_id"/>
<result property="userId" column="user_id"/>
<result property="content" column="content"/>
<result property="mediaOssKeys" column="media_oss_keys" typeHandler="com.bao.dating.handler.ListToVarcharTypeHandler"/>
<result property="tags" column="tags" typeHandler="com.bao.dating.handler.ListToVarcharTypeHandler"/>
<result property="location" column="location"/>
<result property="isPublic" column="is_public"/>
<result property="likeCount" column="like_count"/>
<result property="favoriteCount" column="favorite_count"/>
<result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/>
</resultMap>
<select id="selectById" resultMap="PostResultMap">
SELECT
post_id,
user_id,
content,
media_oss_keys,
tags,
location,
is_public,
like_count,
favorite_count,
created_at,
updated_at
FROM post WHERE post_id = #{postId}
</select>
<!--动态更新-->
<update id="updateById">
UPDATE post
<set>
<if test="content != null">
content = #{content},
</if>
<if test="tags != null">
tags = #{tags, typeHandler=com.bao.dating.handler.ListToVarcharTypeHandler},
</if>
<if test="mediaOssKeys != null">
media_oss_keys =
#{mediaOssKeys, typeHandler=com.bao.dating.handler.ListToVarcharTypeHandler},
</if>
is_public = #{isPublic},
updated_at = #{updatedAt}
</set>
WHERE post_id = #{postId}
</update>
<!--增加点赞数量-->
<update id="increaseLikeCount">
update dating.post set like_count = like_count + 1 where post.post_id = #{postId}
@@ -42,10 +92,26 @@
<update id="decreaseLikeCount">
update dating.post set like_count= like_count - 1 where post.post_id = #{postId}
</update>
<!--增加收藏数量-->
<update id="increaseFavoriteCount">
update post set favorite_count = favorite_count + 1 where post_id = #{post_id}
</update>
<!--减少收藏数量-->
<update id="decreaseFavoriteCount">
update post set favorite_count = favorite_count - 1 where post_id = #{post_id}
</update>
<!--查询点赞当前数量-->
<select id="selectLikeCount" resultType="java.lang.Integer">
select dating.post.like_count from dating.post where post.post_id = #{postId}
</select>
<!--查询当前动态的用户id-->
<select id="selectUserIdByPostId" resultType="java.lang.Long">
SELECT user_id FROM post WHERE post_id = #{post_id}
</select>
<!--查询当前收藏数量-->
<select id="selectFavoriteCount" resultType="java.lang.Integer">
select dating.post.favorite_count from dating.post where post.post_id = #{postId}
</select>
</mapper>

View File

@@ -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<String> imageUrls = Arrays.asList(imageUrl);

View File

@@ -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><body>" +
"<h2 style='color: #1890ff;'>欢迎使用我们的服务</h2>" +
"<p>这是一封<strong>HTML格式</strong>的测试邮件。</p>" +
"<p>邮件内容支持:</p>" +
"<ul>" +
"<li>HTML标签</li>" +
"<li>样式设置</li>" +
"<li>富文本内容</li>" +
"</ul>" +
"<p style='color: #999;'>感谢您的使用!</p>" +
"</body></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);
}
}