fengjiajia 1 week ago
parent
commit
2aa45acaf6

+ 5 - 1
pom.xml

@@ -126,7 +126,11 @@
             <artifactId>javase</artifactId>
             <artifactId>javase</artifactId>
             <version>3.5.1</version>
             <version>3.5.1</version>
         </dependency>
         </dependency>
-
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.0</version>
+        </dependency>
     </dependencies>
     </dependencies>
     <dependencyManagement>
     <dependencyManagement>
         <dependencies>
         <dependencies>

+ 25 - 0
src/main/java/com/zhentao/userRelationships/controller/UserRelationshipsController.java

@@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 
 
 @RestController
 @RestController
 @RequestMapping("/userRelationships")
 @RequestMapping("/userRelationships")
@@ -59,4 +60,28 @@ public class UserRelationshipsController {
     public Result handleFriendRequest(@RequestParam Long requestId, @RequestParam boolean isAccepted) {
     public Result handleFriendRequest(@RequestParam Long requestId, @RequestParam boolean isAccepted) {
         return userRelationshipsService.handleFriendRequest(requestId, isAccepted);
         return userRelationshipsService.handleFriendRequest(requestId, isAccepted);
     }
     }
+
+
+    //根据当前登录的用户获取所有好友并且按照首字母进行排序
+    @GetMapping("/getFriendsByUserIdAndSort")
+    @NullLogin
+    public Result getFriendsByUserIdAndSort(@RequestHeader("token") String token) {
+
+        try {
+            // 从Token中解析用户ID
+            String userIdFromToken = TokenUtils.getUserIdFromToken(token);
+            if (userIdFromToken == null || userIdFromToken.isEmpty()) {
+                return Result.error(null, "用户未登录");
+            }
+            Long userId = Long.parseLong(userIdFromToken);
+
+            // 调用服务层获取排序后的好友列表
+            List<Map<String, Object>> friends = userRelationshipsService.getFriendsByUserIdAndSort(userId);
+
+            return Result.OK(friends, "查询成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return Result.error(null, "查询失败:" + e.getMessage());
+        }
+    }
 }
 }

+ 12 - 0
src/main/java/com/zhentao/userRelationships/dto/FriendsTDto.java

@@ -0,0 +1,12 @@
+package com.zhentao.userRelationships.dto;
+
+import lombok.Data;
+
+@Data
+public class FriendsTDto {
+    private Long friendId;       // 好友ID
+    private String nickName;     // 好友昵称
+    private String avatar;       // 好友头像
+    private String firstLetter;  // 首字母(拼音缩写)
+
+}

+ 4 - 0
src/main/java/com/zhentao/userRelationships/service/UserRelationshipsService.java

@@ -10,6 +10,7 @@ import com.zhentao.vo.Result;
 import org.apache.catalina.User;
 import org.apache.catalina.User;
 
 
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 
 
 /**
 /**
 * @author lenovo
 * @author lenovo
@@ -35,4 +36,7 @@ public interface UserRelationshipsService extends IService<UserRelationships> {
 
 
     // 处理申请添加好友成功
     // 处理申请添加好友成功
     Result handleFriendRequest(Long requestId, boolean isAccepted);
     Result handleFriendRequest(Long requestId, boolean isAccepted);
+
+    //根据当前登录的用户获取所有好友并且按照首字母进行排序
+    List<Map<String, Object>> getFriendsByUserIdAndSort(Long userId);
 }
 }

+ 81 - 12
src/main/java/com/zhentao/userRelationships/service/impl/UserRelationshipsServiceImpl.java

@@ -1,6 +1,6 @@
 package com.zhentao.userRelationships.service.impl;
 package com.zhentao.userRelationships.service.impl;
 
 
-import cn.hutool.core.lang.Snowflake;
+
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zhentao.user.domain.UserLogin;
 import com.zhentao.user.domain.UserLogin;
@@ -9,24 +9,24 @@ import com.zhentao.userRelationships.domain.UserRelationships;
 import com.zhentao.userRelationships.domain.UserRequest;
 import com.zhentao.userRelationships.domain.UserRequest;
 import com.zhentao.userRelationships.domain.UserShouye;
 import com.zhentao.userRelationships.domain.UserShouye;
 import com.zhentao.userRelationships.dto.FriendDto;
 import com.zhentao.userRelationships.dto.FriendDto;
-import com.zhentao.userRelationships.dto.UserRelationshipsDto;
+
+import com.zhentao.userRelationships.dto.FriendsTDto;
 import com.zhentao.userRelationships.mapper.UserRequestMapper;
 import com.zhentao.userRelationships.mapper.UserRequestMapper;
 import com.zhentao.userRelationships.mapper.UserShouyeMapper;
 import com.zhentao.userRelationships.mapper.UserShouyeMapper;
 import com.zhentao.userRelationships.service.UserRelationshipsService;
 import com.zhentao.userRelationships.service.UserRelationshipsService;
 import com.zhentao.userRelationships.mapper.UserRelationshipsMapper;
 import com.zhentao.userRelationships.mapper.UserRelationshipsMapper;
-import com.zhentao.userRelationships.util.AppJwtUtil;
+
+import com.zhentao.userRelationships.util.PinyinUtil;
 import com.zhentao.userRelationships.util.SnowflakeUtil;
 import com.zhentao.userRelationships.util.SnowflakeUtil;
-import com.zhentao.userRelationships.util.UserUtils;
+
 import com.zhentao.vo.Result;
 import com.zhentao.vo.Result;
-import io.jsonwebtoken.Claims;
-import org.apache.catalina.User;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
 
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 /**
 /**
 * @author lenovo
 * @author lenovo
@@ -196,9 +196,78 @@ public class UserRelationshipsServiceImpl extends ServiceImpl<UserRelationshipsM
             return Result.OK(null, "好友申请已拒绝");
             return Result.OK(null, "好友申请已拒绝");
         }
         }
     }
     }
+    //根据当前登录的用户获取所有好友并且按照首字母进行排序
+    @Override
+    public List<Map<String, Object>> getFriendsByUserIdAndSort(Long userId) {
+        // 创建一个查询条件对象,用于后续查询用户关系状态为1(例如:好友关系有效)且用户ID为指定值的记录
+        QueryWrapper<UserRelationships> queryWrapper=new QueryWrapper<>();
+        queryWrapper.eq("status",1)
+                .eq("user_id",userId);
+        // 执行查询,获取用户的关系记录列表
+        List<UserRelationships> relationships=this.list(queryWrapper);
+        // 如果没有找到任何关系记录,则返回一个空列表
+        if(relationships.isEmpty()){
+            return Collections.emptyList();
+        }
+        // 从关系记录中提取所有好友ID
+        List<Long> friendIds = relationships.stream()
+                .map(UserRelationships::getFriendId)
+                .collect(Collectors.toList());
+        // 根据提取的好友ID列表,查询所有对应的好友登录信息
+        List<UserLogin> friends = userLoginMapper.selectBatchIds(friendIds);
+        // 如果没有找到任何好友信息,则返回一个空列表
+        if (friends.isEmpty()) {
+            return Collections.emptyList();
+        }
+        // 3. 转换为FriendDto并处理首字母
+        // 使用Java Stream API对朋友列表进行处理,转换为FriendsTDto列表
+        List<FriendsTDto> FriendsTDtos = friends.stream().map(friend -> {
+            // 创建一个新的FriendsTDto对象
+            FriendsTDto friendsTDto=new FriendsTDto();
+            // 设置朋友的ID
+            friendsTDto.setFriendId(friend.getId());
+            // 设置朋友的昵称
+            friendsTDto.setNickName(friend.getNickName());
+            // 设置朋友的头像
+            friendsTDto.setAvatar(friend.getAvatar());
+            // 获取昵称首字母(拼音缩写)
+            String firstLetter = PinyinUtil.getFirstLetter(friend.getNickName());
+            // 设置昵称首字母
+            friendsTDto.setFirstLetter(firstLetter);
+            // 返回处理后的FriendsTDto对象
+            return friendsTDto;
+        }).collect(Collectors.toList());
+        // 4. 按首字母分组(使用TreeMap保证字母顺序)
+        Map<String, List<FriendsTDto>> groupByFirstLetter = FriendsTDtos.stream()
+                .collect(Collectors.groupingBy(
+                        FriendsTDto::getFirstLetter,
+                        TreeMap::new,
+                        Collectors.toList()
+                ));
+
+        // 5. 整理结果(先A-Z,再#)
+        List<Map<String, Object>> result = new ArrayList<>();
+        // 处理A-Z字母分组
+        for (char c = 'A'; c <= 'Z'; c++) {
+            String letter = String.valueOf(c);
+            if (groupByFirstLetter.containsKey(letter)) {
+                // 对每组好友按昵称拼音排序
+                groupByFirstLetter.get(letter).sort(
+                        Comparator.comparing(f -> PinyinUtil.getFullPinyin(f.getNickName()))
+                );
+                result.add(Collections.singletonMap(letter, groupByFirstLetter.get(letter)));
+            }
+        }
 
 
-
-
+        // 处理特殊字符分组(#)
+        if (groupByFirstLetter.containsKey("#")) {
+            groupByFirstLetter.get("#").sort(
+                    Comparator.comparing(f -> PinyinUtil.getFullPinyin(f.getNickName()))
+            );
+                result.add(Collections.singletonMap("#", groupByFirstLetter.get("#")));
+        }
+        return result;
+    }
 }
 }
 
 
 
 

+ 114 - 0
src/main/java/com/zhentao/userRelationships/util/PinyinUtil.java

@@ -0,0 +1,114 @@
+package com.zhentao.userRelationships.util;
+
+
+import net.sourceforge.pinyin4j.PinyinHelper;
+import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
+import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
+import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
+
+import java.util.regex.Pattern;
+
+/**
+ * 拼音处理工具类,用于获取汉字的拼音首字母和全拼
+ */
+public class PinyinUtil {
+
+    // 配置拼音输出格式
+    private static HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
+
+    static {
+        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);    // 大写
+        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); // 无音调
+        format.setVCharType(HanyuPinyinVCharType.WITH_V);     // 用v表示ü
+    }
+
+    /**
+     * 获取字符串的首字母拼音缩写
+     * @param str 输入字符串,支持中文、英文、数字、符号
+     * @return 首字母缩写(大写),非字母字符返回"#"
+     */
+    public static String getFirstLetter(String str) {
+        if (str == null || str.trim().isEmpty()) {
+            return "#";
+        }
+
+        char firstChar = str.trim().charAt(0);
+
+        // 处理中文
+        if (isChinese(firstChar)) {
+            try {
+                String pinyin = PinyinHelper.toHanyuPinyinStringArray(firstChar, format)[0];
+                return String.valueOf(pinyin.charAt(0));
+            } catch (BadHanyuPinyinOutputFormatCombination e) {
+                return "#";
+            }
+        }
+        // 处理英文字母
+        else if (Character.isLetter(firstChar)) {
+            return String.valueOf(Character.toUpperCase(firstChar));
+        }
+        // 处理数字、符号等
+        else {
+            return "#";
+        }
+    }
+
+    /**
+     * 获取字符串的完整拼音
+     * @param str 输入字符串
+     * @return 拼音字符串(首字母大写,其余小写,空格分隔)
+     */
+    public static String getFullPinyin(String str) {
+        if (str == null || str.trim().isEmpty()) {
+            return "";
+        }
+
+        StringBuilder pinyin = new StringBuilder();
+        for (char c : str.toCharArray()) {
+            if (isChinese(c)) {
+                try {
+                    String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
+                    if (pinyinArray != null && pinyinArray.length > 0) {
+                        pinyin.append(pinyinArray[0]);
+                    } else {
+                        pinyin.append(c);
+                    }
+                } catch (BadHanyuPinyinOutputFormatCombination e) {
+                    pinyin.append(c);
+                }
+            } else {
+                pinyin.append(c);
+            }
+            pinyin.append(" ");
+        }
+
+        // 首字母大写,其余小写
+        if (pinyin.length() > 0) {
+            String result = pinyin.toString().trim();
+            return result.substring(0, 1).toUpperCase() + result.substring(1).toLowerCase();
+        }
+
+        return "";
+    }
+
+    /**
+     * 判断字符是否为中文
+     */
+    private static boolean isChinese(char c) {
+        return c >= 0x4E00 && c <= 0x9FA5;
+    }
+
+    /**
+     * 判断字符串是否包含中文
+     */
+    public static boolean containsChinese(String str) {
+        if (str == null || str.trim().isEmpty()) {
+            return false;
+        }
+
+        Pattern pattern = Pattern.compile("[\\u4E00-\\u9FA5]");
+        return pattern.matcher(str).find();
+    }
+}