4 Commits

Author SHA1 Message Date
bao
e4f1385411 更新联系人相关功能:添加联系人控制器、服务层和Mapper实现 2026-01-13 11:22:44 +08:00
KilLze
4f94c43f94 修bug 2026-01-11 00:57:29 +08:00
KilLze
7a8a03510c 修bug 2026-01-11 00:28:23 +08:00
KilLze
2189575659 修bug 2026-01-11 00:25:19 +08:00
10 changed files with 149 additions and 129 deletions

View File

@@ -3,6 +3,8 @@ package com.bao.dating.controller;
import com.bao.dating.context.UserContext; import com.bao.dating.context.UserContext;
import com.bao.dating.service.ContactsService; import com.bao.dating.service.ContactsService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
@@ -12,6 +14,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @RestController
@RequestMapping("/api/contacts")
public class ContactsController { public class ContactsController {
@Resource @Resource
private ContactsService contactsService; private ContactsService contactsService;
@@ -42,4 +45,56 @@ public class ContactsController {
result.put("data", friends); result.put("data", friends);
return result; return result;
} }
/**
* 拉黑联系人接口
* @param userId 当前用户ID
* @param contactUserId 被拉黑联系人ID
* @return 接口响应
*/
@PostMapping("/blacklist/{userId}/{contactUserId}")
public ResponseEntity<Map<String, Object>> blacklistContact(
@PathVariable Long userId,
@PathVariable Long contactUserId) {
Map<String, Object> result = new HashMap<>();
boolean success = contactsService.blacklistContact(userId, contactUserId);
if (success) {
result.put("code", 200);
result.put("msg", "拉黑联系人成功");
result.put("data", null);
return ResponseEntity.ok(result);
} else {
result.put("code", 500);
result.put("msg", "拉黑联系人失败,联系人不存在或参数错误");
result.put("data", null);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* 删除联系人接口
* @param userId 当前用户ID
* @param contactUserId 被删除联系人ID
* @return 接口响应
*/
@PostMapping("/delete/{userId}/{contactUserId}")
public ResponseEntity<Map<String, Object>> deleteContact(
@PathVariable Long userId,
@PathVariable Long contactUserId) {
Map<String, Object> result = new HashMap<>();
boolean success = contactsService.deleteContact(userId, contactUserId);
if (success) {
result.put("code", 200);
result.put("msg", "删除联系人成功");
result.put("data", null);
return ResponseEntity.ok(result);
} else {
result.put("code", 500);
result.put("msg", "删除联系人失败,联系人不存在或参数错误");
result.put("data", null);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
} }

View File

@@ -4,9 +4,8 @@ import com.bao.dating.anno.Log;
import com.bao.dating.common.Result; import com.bao.dating.common.Result;
import com.bao.dating.common.ResultCode; import com.bao.dating.common.ResultCode;
import com.bao.dating.context.UserContext; import com.bao.dating.context.UserContext;
import com.bao.dating.pojo.dto.UserInfoUpdateDTO;
import com.bao.dating.pojo.dto.UserLoginDTO;
import com.bao.dating.pojo.dto.UserInfoDTO; import com.bao.dating.pojo.dto.UserInfoDTO;
import com.bao.dating.pojo.dto.UserLoginDTO;
import com.bao.dating.pojo.vo.UserInfoVO; import com.bao.dating.pojo.vo.UserInfoVO;
import com.bao.dating.pojo.vo.UserLoginVO; import com.bao.dating.pojo.vo.UserLoginVO;
import com.bao.dating.service.UserService; import com.bao.dating.service.UserService;
@@ -93,7 +92,7 @@ public class UserController {
*/ */
@Log @Log
@PostMapping("/info/update") @PostMapping("/info/update")
public Result<UserInfoVO> userInfoUpdate(@RequestBody UserInfoUpdateDTO userInfoUpdateDTO) { public Result<UserInfoVO> userInfoUpdate(@RequestBody UserInfoDTO userInfoUpdateDTO) {
Long userId = UserContext.getUserId(); Long userId = UserContext.getUserId();
userInfoUpdateDTO.setUserId(userId); userInfoUpdateDTO.setUserId(userId);
UserInfoVO userInfoVO =userService.updateUserInfo(userInfoUpdateDTO); UserInfoVO userInfoVO =userService.updateUserInfo(userInfoUpdateDTO);

View File

@@ -1,4 +0,0 @@
package com.bao.dating.controller;
public class text {
}

View File

@@ -17,4 +17,20 @@ public interface ContactMapper {
*/ */
List<Map<String, Object>> selectFriendsByUserId(@Param("userId") Long userId); List<Map<String, Object>> selectFriendsByUserId(@Param("userId") Long userId);
/**
* 拉黑联系人
* @param userId 当前用户ID
* @param contactUserId 被拉黑的联系人ID
* @return 影响行数
*/
int blacklistContact(@Param("userId") Long userId, @Param("contactUserId") Long contactUserId);
/**
* 删除联系人(逻辑删除)
* @param userId 当前用户ID
* @param contactUserId 被删除的联系人ID
* @return 影响行数
*/
int deleteContact(@Param("userId") Long userId, @Param("contactUserId") Long contactUserId);
} }

View File

@@ -1,25 +0,0 @@
package com.bao.dating.pojo.dto;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
* 用户信息更新数据传输对象
* @author KilLze
*/
@Data
public class UserInfoUpdateDTO {
private Long userId;
private String userName;
private String nickname;
private String avatarUrl;
private String backgroundUrl;
private Integer gender;
private LocalDate birthday;
private List<String> hobbies;
private String signature;
private LocalDateTime updatedAt;
}

View File

@@ -15,6 +15,20 @@ public interface ContactsService {
List<Map<String, Object>> getFriendsByUserId(Long userId); List<Map<String, Object>> getFriendsByUserId(Long userId);
/**
* 拉黑联系人
* @param userId 当前用户ID
* @param contactUserId 被拉黑联系人ID
* @return 操作是否成功
*/
boolean blacklistContact(Long userId, Long contactUserId);
/**
* 删除联系人(逻辑删除)
* @param userId 当前用户ID
* @param contactUserId 被删除联系人ID
* @return 操作是否成功
*/
boolean deleteContact(Long userId, Long contactUserId);
} }

View File

@@ -1,9 +1,7 @@
package com.bao.dating.service; package com.bao.dating.service;
import com.bao.dating.pojo.dto.UserInfoDTO; import com.bao.dating.pojo.dto.UserInfoDTO;
import com.bao.dating.pojo.dto.UserInfoUpdateDTO;
import com.bao.dating.pojo.dto.UserLoginDTO; import com.bao.dating.pojo.dto.UserLoginDTO;
import com.bao.dating.pojo.entity.User;
import com.bao.dating.pojo.vo.UserInfoVO; import com.bao.dating.pojo.vo.UserInfoVO;
import com.bao.dating.pojo.vo.UserLoginVO; import com.bao.dating.pojo.vo.UserLoginVO;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -79,7 +77,6 @@ public interface UserService {
* @return 用户 * @return 用户
*/ */
UserInfoDTO getUserInfoById(Long userId); UserInfoDTO getUserInfoById(Long userId);
UserInfoVO updateUserInfo(UserInfoUpdateDTO userInfoUpdateDTO);
void sendSmsCode(String phone); void sendSmsCode(String phone);

View File

@@ -5,6 +5,7 @@ import com.bao.dating.service.ContactsService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -19,4 +20,34 @@ public class ContactServiceImpl implements ContactsService {
// 直接调用Mapper查询无额外封装 // 直接调用Mapper查询无额外封装
return contactMapper.selectFriendsByUserId(userId); return contactMapper.selectFriendsByUserId(userId);
} }
/**
* 拉黑联系人
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean blacklistContact(Long userId, Long contactUserId) {
// 参数校验
if (userId == null || contactUserId == null || userId.equals(contactUserId)) {
return false;
}
// 执行拉黑操作
int affectRows = contactMapper.blacklistContact(userId, contactUserId);
return affectRows > 0;
}
/**
* 删除联系人
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteContact(Long userId, Long contactUserId) {
// 参数校验
if (userId == null || contactUserId == null || userId.equals(contactUserId)) {
return false;
}
// 执行删除操作
int affectRows = contactMapper.deleteContact(userId, contactUserId);
return affectRows > 0;
}
} }

View File

@@ -1,18 +1,14 @@
package com.bao.dating.service.impl; package com.bao.dating.service.impl;
import com.bao.dating.common.Result;
import com.bao.dating.common.ResultCode;
import com.bao.dating.common.aliyun.AliOssUtil; import com.bao.dating.common.aliyun.AliOssUtil;
import com.bao.dating.common.aliyun.GreenImageScan; import com.bao.dating.common.aliyun.GreenImageScan;
import com.bao.dating.common.aliyun.GreenTextScan; import com.bao.dating.common.aliyun.GreenTextScan;
import com.bao.dating.common.aliyun.SmsUtil; import com.bao.dating.common.aliyun.SmsUtil;
import com.bao.dating.common.result.AliOssResult; import com.bao.dating.common.result.AliOssResult;
import com.bao.dating.common.result.GreenAuditResult; import com.bao.dating.common.result.GreenAuditResult;
import com.bao.dating.config.RedisConfig;
import com.bao.dating.context.UserContext; import com.bao.dating.context.UserContext;
import com.bao.dating.mapper.UserMapper; import com.bao.dating.mapper.UserMapper;
import com.bao.dating.pojo.dto.UserInfoDTO; import com.bao.dating.pojo.dto.UserInfoDTO;
import com.bao.dating.pojo.dto.UserInfoUpdateDTO;
import com.bao.dating.pojo.dto.UserLoginDTO; import com.bao.dating.pojo.dto.UserLoginDTO;
import com.bao.dating.pojo.entity.User; import com.bao.dating.pojo.entity.User;
import com.bao.dating.pojo.vo.UserInfoVO; import com.bao.dating.pojo.vo.UserInfoVO;
@@ -28,6 +24,7 @@ import io.jsonwebtoken.Claims;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -243,100 +240,13 @@ public class UserServiceImpl implements UserService {
} }
/**
* 更新用户信息
* @param userInfoUpdateDTO
* @return
*/
@Override
public UserInfoVO updateUserInfo(UserInfoUpdateDTO userInfoUpdateDTO) {
Long userId = userInfoUpdateDTO.getUserId();
User user = userMapper.selectByUserId(userId);
if (user == null) {
throw new RuntimeException("用户不存在");
}
// 将需要审核的内容合并成一个文本,用于减少调用次数
StringBuilder textBuilder = new StringBuilder();
if (userInfoUpdateDTO.getNickname() != null && !userInfoUpdateDTO.getNickname().isEmpty()) {
textBuilder.append(userInfoUpdateDTO.getNickname()).append(" ");
}
if (userInfoUpdateDTO.getHobbies() != null && !userInfoUpdateDTO.getHobbies().isEmpty()) {
// 将爱好列表转换为字符串,用空格分隔
String hobbiesStr = String.join(" ", userInfoUpdateDTO.getHobbies());
textBuilder.append(hobbiesStr).append(" ");
}
if (userInfoUpdateDTO.getSignature() != null && !userInfoUpdateDTO.getSignature().isEmpty()) {
textBuilder.append(userInfoUpdateDTO.getSignature()).append(" ");
}
// 文本审核
if (textBuilder.length() > 0) {
Map textResult;
try {
textResult = greenTextScan.greeTextScan(textBuilder.toString());
} catch (Exception e) {
throw new RuntimeException("用户信息文本审核失败");
}
String suggestion = (String) textResult.get("suggestion");
if (GreenAuditResult.BLOCK.equals(suggestion)) {
throw new RuntimeException("用户信息包含违规内容,修改失败");
}
if (GreenAuditResult.REVIEW.equals(suggestion)) {
throw new RuntimeException("用户信息需要人工审核,暂无法修改");
}
}
// 图片审核
List<String> imageKeys = new ArrayList<>();
if (userInfoUpdateDTO.getAvatarUrl() != null && !userInfoUpdateDTO.getAvatarUrl().isEmpty()) {
imageKeys.add(userInfoUpdateDTO.getAvatarUrl());
}
if (userInfoUpdateDTO.getBackgroundUrl() != null && !userInfoUpdateDTO.getBackgroundUrl().isEmpty()) {
imageKeys.add(userInfoUpdateDTO.getBackgroundUrl());
}
if (!imageKeys.isEmpty()) {
Map imageResult;
try {
imageResult = greenImageScan.imageScan(imageKeys);
} catch (Exception e) {
throw new RuntimeException("用户图片审核失败");
}
String suggestion = (String) imageResult.get("suggestion");
if (GreenAuditResult.BLOCK.equals(suggestion)) {
throw new RuntimeException("头像或背景图不合规,修改失败");
}
if (GreenAuditResult.REVIEW.equals(suggestion)) {
throw new RuntimeException("头像或背景图需要人工审核,暂无法修改");
}
}
// 默认昵称兜底
if (userInfoUpdateDTO.getNickname() == null || userInfoUpdateDTO.getNickname().trim().isEmpty()) {
userInfoUpdateDTO.setNickname(user.getUserName());
}
userInfoUpdateDTO.setUpdatedAt(LocalDateTime.now());
// 更新数据库
userMapper.updateUserInfoByUserId(userInfoUpdateDTO);
// 封装返回结果
User updatedUser = userMapper.selectByUserId(userInfoUpdateDTO.getUserId());
UserInfoVO userInfoVO = new UserInfoVO();
BeanUtils.copyProperties(updatedUser, userInfoVO);
return userInfoVO;
}
/** /**
* 更新用户信息 * 更新用户信息
* *
* @param userInfoUpdateDTO 用户信息更新参数 * @param userInfoUpdateDTO 用户信息更新参数
*/ */
@Override @Override
public UserInfoVO updateUserInfo(UserInfoUpdateDTO userInfoUpdateDTO) { public UserInfoVO updateUserInfo(UserInfoDTO userInfoUpdateDTO) {
Long userId = userInfoUpdateDTO.getUserId(); Long userId = userInfoUpdateDTO.getUserId();
User user = userMapper.selectByUserId(userId); User user = userMapper.selectByUserId(userId);
if (user == null) { if (user == null) {
@@ -417,6 +327,7 @@ public class UserServiceImpl implements UserService {
return userInfoVO; return userInfoVO;
} }
/** /**
* 用户注册 * 用户注册
* @param userName 用户名称 * @param userName 用户名称
@@ -459,11 +370,13 @@ public class UserServiceImpl implements UserService {
@Override @Override
public UserLoginVO emailLogin(String email, String code) { public UserLoginVO emailLogin(String email, String code) {
User user = userMapper.selectByUserEmailUser(email); User user = userMapper.selectByUserEmailUser(email);
if (user == null) if (user == null) {
return null; return null;
}
boolean flag = verificationCodeService.verifyEmailCode(email, code); boolean flag = verificationCodeService.verifyEmailCode(email, code);
if (!flag) if (!flag) {
return null; return null;
}
// 生成token // 生成token
String token = JwtUtil.generateToken(String.valueOf(user.getUserId())); String token = JwtUtil.generateToken(String.valueOf(user.getUserId()));
UserLoginVO userLoginVO = new UserLoginVO(); UserLoginVO userLoginVO = new UserLoginVO();

View File

@@ -21,5 +21,29 @@
AND c.relation_type != 3 -- 排除黑名单 AND c.relation_type != 3 -- 排除黑名单
AND c.user_id != c.contact_user_id -- 排除自己 AND c.user_id != c.contact_user_id -- 排除自己
</select> </select>
<!-- 拉黑联系人更新relation_type为3黑名单、contact_status为3已拉黑 -->
<update id="blacklistContact">
UPDATE contacts
SET relation_type = 3,
contact_status = 3,
updated_at = CURRENT_TIMESTAMP
WHERE user_id = #{userId}
AND contact_user_id = #{contactUserId}
AND contact_status != 2
</update>
<!-- 删除联系人更新contact_status为2已删除 -->
<update id="deleteContact">
UPDATE contacts
SET contact_status = 2,
updated_at = CURRENT_TIMESTAMP
WHERE user_id = #{userId}
AND contact_user_id = #{contactUserId}
AND contact_status != 2
</update>
</mapper> </mapper>