소스 검색

IM同步企微完课改备注返回给app前端

xw 1 주 전
부모
커밋
045b606ba3

+ 14 - 0
fs-service/src/main/java/com/fs/qw/param/ImFsUserRemarkTagsParam.java

@@ -0,0 +1,14 @@
+package com.fs.qw.param;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * IM 侧按 fs_user.user_id 批量查询企微备注、标签
+ */
+@Data
+public class ImFsUserRemarkTagsParam {
+    /** fs_user 表 user_id 集合 */
+    private List<String> userIds;
+}

+ 5 - 0
fs-service/src/main/java/com/fs/qw/service/IQwExternalContactService.java

@@ -101,6 +101,11 @@ public interface IQwExternalContactService extends IService<QwExternalContact> {
 
     List<QwExternalContactVOTime> selectQwExternalContactListVOByIds(List<Long> ids);
 
+    /**
+     * 按 fs_user_id 批量查询企微客户
+     */
+    List<QwExternalContact> selectExternalByFsUserIds(List<Long> userIds);
+
     R syncQwExternalContact(String corpId) throws IOException;
 
     R syncMyQwExternalContact(Long id) throws IOException;

+ 6 - 0
fs-service/src/main/java/com/fs/qw/service/IQwTagService.java

@@ -8,6 +8,7 @@ import com.fs.qw.param.newparam.ContactTagListParam;
 import com.fs.qw.vo.QwTagGroupListVO;
 import com.fs.qw.vo.QwTagVO;
 
+import java.util.Map;
 import java.util.List;
 
 /**
@@ -71,5 +72,10 @@ public interface IQwTagService
 
     public List<String> selectQwTagListByTagIds(QwTagSearchParam param);
 
+    /**
+     * 按标签ID批量查询标签名映射
+     */
+    Map<String, String> selectTagNameMapByTagIds(List<String> tagIds);
+
     List<QwTagVO> getTagListByUserId(ContactTagListParam param);
 }

+ 8 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java

@@ -867,6 +867,14 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
         return qwExternalContactMapper.selectQwExternalContactListVOByIds(ids);
     }
 
+    @Override
+    public List<QwExternalContact> selectExternalByFsUserIds(List<Long> userIds) {
+        if (userIds == null || userIds.isEmpty()) {
+            return new ArrayList<>();
+        }
+        return qwExternalContactMapper.selectExternalByFsUserIds(userIds);
+    }
+
     @Override
     public R syncQwExternalContact(String corpId) throws IOException {
 

+ 14 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwTagServiceImpl.java

@@ -200,6 +200,20 @@ public class QwTagServiceImpl implements IQwTagService
         return qwTagMapper.selectQwTagListNameByTagIds(param);
     }
 
+    @Override
+    public Map<String, String> selectTagNameMapByTagIds(List<String> tagIds) {
+        if (tagIds == null || tagIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        List<QwTag> tags = qwTagMapper.selectQwTagListByTagIdsNew(tagIds);
+        if (tags == null || tags.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        return tags.stream()
+                .filter(t -> t.getTagId() != null)
+                .collect(Collectors.toMap(QwTag::getTagId, QwTag::getName, (a, b) -> a));
+    }
+
     @Override
     public List<QwTagVO> getTagListByUserId(ContactTagListParam param) {
         String[] keywords = new String[0];

+ 18 - 0
fs-service/src/main/java/com/fs/qw/vo/ImFsUserRemarkTagsVO.java

@@ -0,0 +1,18 @@
+package com.fs.qw.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * IM 侧企微外部联系人备注与标签(与列表接口解析规则一致)
+ */
+@Data
+public class ImFsUserRemarkTagsVO {
+    /** fs_user.user_id */
+    private Long userId;
+    /** 企微客户备注 */
+    private String remark;
+    /** 标签名称列表 */
+    private List<String> tagNames;
+}

+ 191 - 0
fs-user-app/src/main/java/com/fs/app/controller/ImQwExternalContactController.java

@@ -0,0 +1,191 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.common.core.domain.R;
+import com.fs.qw.domain.QwExternalContact;
+import com.fs.qw.param.ImFsUserRemarkTagsParam;
+import com.fs.qw.service.IQwExternalContactService;
+import com.fs.qw.service.IQwTagService;
+import com.fs.qw.vo.ImFsUserRemarkTagsVO;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * IM:按 fs_user 批量查企微外部联系人备注、标签(
+ */
+@Api("IM-企微客户")
+@Slf4j
+@RestController
+@RequestMapping("/app/im/qwExternalContact")
+public class ImQwExternalContactController extends AppBaseController {
+    private static final Gson GSON = new Gson();
+    private static final Pattern ID_PATTERN = Pattern.compile("^[Uu]?(\\d+)$");
+
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
+    @Autowired
+    private IQwTagService iQwTagService;
+    @ApiOperation("批量查询企微备注与标签")
+    @Login
+    @PostMapping("/remarkTagsByFsUserIds")
+    public R remarkTagsByFsUserIds(@RequestBody ImFsUserRemarkTagsParam param) {
+        if (param == null || CollectionUtils.isEmpty(param.getUserIds())) {
+            return R.ok().put("data", Collections.emptyList());
+        }
+        List<Long> requested = normalizeFsUserIds(param.getUserIds());
+        if (CollectionUtils.isEmpty(requested)) {
+            return R.ok().put("data", Collections.emptyList());
+        }
+
+        List<QwExternalContact> contacts = qwExternalContactService.selectExternalByFsUserIds(requested);
+        Map<Long, QwExternalContact> bestByFsUser = pickBestExternalContactByFsUser(contacts);
+        Map<String, List<String>> parsedTagIdCache = new HashMap<>();
+        Map<String, String> tagNameMap = buildTagNameMap(bestByFsUser.values(), parsedTagIdCache);
+
+        List<ImFsUserRemarkTagsVO> rows = new ArrayList<>(requested.size());
+        for (Long uid : requested) {
+            ImFsUserRemarkTagsVO row = new ImFsUserRemarkTagsVO();
+            row.setUserId(uid);
+            QwExternalContact c = bestByFsUser.get(uid);
+            if (c != null) {
+                row.setRemark(c.getRemark());
+                row.setTagNames(resolveTagNamesLikeList(c.getTagIds(), parsedTagIdCache, tagNameMap));
+            } else {
+                row.setTagNames(Collections.emptyList());
+            }
+            rows.add(row);
+        }
+        return R.ok().put("data", rows);
+    }
+
+    private static Map<Long, QwExternalContact> pickBestExternalContactByFsUser(List<QwExternalContact> contacts) {
+        Map<Long, QwExternalContact> out = new HashMap<>();
+        if (CollectionUtils.isEmpty(contacts)) {
+            return out;
+        }
+        for (QwExternalContact current : contacts) {
+            if (current == null || current.getFsUserId() == null) {
+                continue;
+            }
+            QwExternalContact best = out.get(current.getFsUserId());
+            if (best == null || isBetter(current, best)) {
+                out.put(current.getFsUserId(), current);
+            }
+        }
+        return out;
+    }
+
+    private static boolean isBetter(QwExternalContact current, QwExternalContact best) {
+        boolean currentActive = Integer.valueOf(0).equals(current.getStatus());
+        boolean bestActive = Integer.valueOf(0).equals(best.getStatus());
+        if (currentActive != bestActive) {
+            return currentActive;
+        }
+        Long currentId = current.getId();
+        Long bestId = best.getId();
+        if (currentId == null) {
+            return false;
+        }
+        if (bestId == null) {
+            return true;
+        }
+        return currentId > bestId;
+    }
+
+    private Map<String, String> buildTagNameMap(Iterable<QwExternalContact> contacts, Map<String, List<String>> parsedTagIdCache) {
+        LinkedHashSet<String> allTagIds = new LinkedHashSet<>();
+        for (QwExternalContact contact : contacts) {
+            allTagIds.addAll(parseTagIds(contact.getTagIds(), parsedTagIdCache));
+        }
+        if (allTagIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        return iQwTagService.selectTagNameMapByTagIds(new ArrayList<>(allTagIds));
+    }
+
+    private List<String> resolveTagNamesLikeList(String tagIds, Map<String, List<String>> parsedTagIdCache, Map<String, String> tagNameMap) {
+        List<String> ids = parseTagIds(tagIds, parsedTagIdCache);
+        if (CollectionUtils.isEmpty(ids)) {
+            return Collections.emptyList();
+        }
+        List<String> names = new ArrayList<>();
+        for (String id : ids) {
+            String name = tagNameMap.get(id);
+            if (name != null) {
+                names.add(name);
+            }
+        }
+        return names;
+    }
+
+    private List<String> parseTagIds(String tagIds, Map<String, List<String>> parsedTagIdCache) {
+        if (tagIds == null || Objects.equals(tagIds, "[]")) {
+            return Collections.emptyList();
+        }
+        if (parsedTagIdCache.containsKey(tagIds)) {
+            return parsedTagIdCache.get(tagIds);
+        }
+        List<String> ids;
+        try {
+            ids = GSON.fromJson(
+                    tagIds,
+                    new TypeToken<List<String>>() {
+                    }.getType());
+        } catch (Exception ex) {
+            log.warn("IM标签解析失败, tagIds={}", tagIds, ex);
+            parsedTagIdCache.put(tagIds, Collections.emptyList());
+            return Collections.emptyList();
+        }
+        if (CollectionUtils.isEmpty(ids)) {
+            parsedTagIdCache.put(tagIds, Collections.emptyList());
+            return Collections.emptyList();
+        }
+        parsedTagIdCache.put(tagIds, ids);
+        return ids;
+    }
+
+    private List<Long> normalizeFsUserIds(List<String> rawUserIds) {
+        List<Long> normalized = new ArrayList<>();
+        for (String raw : rawUserIds) {
+            if (raw == null) {
+                continue;
+            }
+            String trimmed = raw.trim();
+            if (trimmed.isEmpty()) {
+                continue;
+            }
+            Matcher matcher = ID_PATTERN.matcher(trimmed);
+            if (!matcher.matches()) {
+                log.warn("IM userId格式不支持, userId={}", raw);
+                continue;
+            }
+            try {
+                normalized.add(Long.parseLong(matcher.group(1)));
+            } catch (NumberFormatException ex) {
+                log.warn("IM userId转换失败, userId={}", raw, ex);
+            }
+        }
+        return normalized.stream().distinct().collect(Collectors.toList());
+    }
+}