|
|
@@ -0,0 +1,280 @@
|
|
|
+package com.fs.his.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.fs.common.utils.DateUtils;
|
|
|
+import com.fs.common.utils.StringUtils;
|
|
|
+import com.fs.company.domain.CompanyTag;
|
|
|
+import com.fs.company.domain.CompanyTagUser;
|
|
|
+import com.fs.company.mapper.CompanyTagMapper;
|
|
|
+import com.fs.company.mapper.CompanyTagUserMapper;
|
|
|
+import com.fs.company.service.ICompanyTagService;
|
|
|
+import com.fs.course.domain.FsUserCompanyUser;
|
|
|
+import com.fs.course.mapper.FsUserCompanyUserMapper;
|
|
|
+import com.fs.his.domain.FraudUsers;
|
|
|
+import com.fs.his.domain.FsUser;
|
|
|
+import com.fs.his.mapper.FraudUsersMapper;
|
|
|
+import com.fs.his.mapper.FsUserAddressMapper;
|
|
|
+import com.fs.his.mapper.FsUserMapper;
|
|
|
+import com.fs.his.service.IFraudUsersService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import static com.fs.his.utils.PhoneUtil.decryptPhone;
|
|
|
+import static com.fs.his.utils.PhoneUtil.encryptPhone;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class FraudUsersServiceImpl implements IFraudUsersService {
|
|
|
+
|
|
|
+ private static final Integer BLACK_STATUS = 2;
|
|
|
+ private static final String PROFESSIONAL_FRAUD_TAG = "职业打假人";
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private FraudUsersMapper fraudUsersMapper;
|
|
|
+ @Resource
|
|
|
+ private FsUserMapper fsUserMapper;
|
|
|
+ @Resource
|
|
|
+ private FsUserAddressMapper fsUserAddressMapper;
|
|
|
+ @Resource
|
|
|
+ private FsUserCompanyUserMapper fsUserCompanyUserMapper;
|
|
|
+ @Resource
|
|
|
+ private CompanyTagMapper companyTagMapper;
|
|
|
+ @Resource
|
|
|
+ private CompanyTagUserMapper companyTagUserMapper;
|
|
|
+ @Resource
|
|
|
+ private ICompanyTagService companyTagService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FraudUsers selectFraudUsersById(Long id) {
|
|
|
+ FraudUsers fraudUsers = fraudUsersMapper.selectFraudUsersById(id);
|
|
|
+ if (fraudUsers !=null){
|
|
|
+ if(StringUtils.isNotEmpty(fraudUsers.getPhone()) && fraudUsers.getPhone().length()>11 ){
|
|
|
+ fraudUsers.setPhone(decryptPhone(fraudUsers.getPhone()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fraudUsers;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<FraudUsers> selectFraudUsersList(FraudUsers fraudUsers) {
|
|
|
+ List<FraudUsers> usersList = fraudUsersMapper.selectFraudUsersList(fraudUsers);
|
|
|
+ //解密手机号
|
|
|
+ if(CollUtil.isNotEmpty(usersList)){
|
|
|
+ usersList.forEach(users -> {
|
|
|
+ if(StringUtils.isNotEmpty(users.getPhone()) && users.getPhone().length()>11){
|
|
|
+ users.setPhone(decryptPhone(users.getPhone()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return usersList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Map<String, Object> insertFraudUsers(FraudUsers fraudUsers) {
|
|
|
+ if (StringUtils.isNotEmpty(fraudUsers.getPhone())) {
|
|
|
+ fraudUsers.setPhone(normalizeFraudPhone(fraudUsers.getPhone()));
|
|
|
+ }
|
|
|
+ fraudUsersMapper.insertFraudUsers(fraudUsers);
|
|
|
+ return syncSingleFraudUsers(fraudUsersMapper.selectFraudUsersById(fraudUsers.getId()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Map<String, Object> updateFraudUsers(FraudUsers fraudUsers) {
|
|
|
+ if (StringUtils.isNotEmpty(fraudUsers.getPhone())) {
|
|
|
+ fraudUsers.setPhone(normalizeFraudPhone(fraudUsers.getPhone()));
|
|
|
+ }
|
|
|
+ fraudUsersMapper.updateFraudUsers(fraudUsers);
|
|
|
+ return syncSingleFraudUsers(fraudUsersMapper.selectFraudUsersById(fraudUsers.getId()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int deleteFraudUsersByIds(Long[] ids) {
|
|
|
+ return fraudUsersMapper.deleteFraudUsersByIds(ids);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int deleteFraudUsersById(Long id) {
|
|
|
+ return fraudUsersMapper.deleteFraudUsersById(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isFraudUser(String phone, String address) {
|
|
|
+ FraudUsers query = new FraudUsers();
|
|
|
+ if (StringUtils.isNotBlank(phone)) {
|
|
|
+ query.setPhone(normalizeFraudPhone(phone));
|
|
|
+ List<FraudUsers> fraudUsersByPhone = fraudUsersMapper.selectFraudUsersList(query);
|
|
|
+ if (fraudUsersByPhone != null && !fraudUsersByPhone.isEmpty()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(address)) {
|
|
|
+ FraudUsers addressQuery = new FraudUsers();
|
|
|
+ addressQuery.setAddress(address.trim());
|
|
|
+ List<FraudUsers> fraudUsersByAddress = fraudUsersMapper.selectFraudUsersList(addressQuery);
|
|
|
+ return fraudUsersByAddress != null && !fraudUsersByAddress.isEmpty();
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Map<String, Object> syncFraudUsers() {
|
|
|
+ List<FraudUsers> fraudUsersList = fraudUsersMapper.selectFraudUsersList(new FraudUsers());
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+ result.put("fraudUserCount", fraudUsersList.size());
|
|
|
+ if (fraudUsersList.isEmpty()) {
|
|
|
+ result.put("matchedUserCount", 0);
|
|
|
+ result.put("matchedRelationCount", 0);
|
|
|
+ result.put("blacklistedRelationCount", 0);
|
|
|
+ result.put("taggedRelationCount", 0);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<Long> matchedUserIds = new HashSet<>();
|
|
|
+ for (FraudUsers fraudUser : fraudUsersList) {
|
|
|
+ matchedUserIds.addAll(matchUserIds(fraudUser));
|
|
|
+ }
|
|
|
+ fillSyncResult(result, matchedUserIds);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> syncSingleFraudUsers(FraudUsers fraudUsers) {
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+ result.put("fraudUserId", fraudUsers != null ? fraudUsers.getId() : null);
|
|
|
+ result.put("fraudUserName", fraudUsers != null ? fraudUsers.getName() : null);
|
|
|
+ if (fraudUsers == null) {
|
|
|
+ result.put("matchedUserCount", 0);
|
|
|
+ result.put("matchedRelationCount", 0);
|
|
|
+ result.put("blacklistedRelationCount", 0);
|
|
|
+ result.put("taggedRelationCount", 0);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<Long> matchedUserIds = matchUserIds(fraudUsers);
|
|
|
+ fillSyncResult(result, matchedUserIds);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillSyncResult(Map<String, Object> result, Set<Long> matchedUserIds) {
|
|
|
+ result.put("matchedUserCount", matchedUserIds.size());
|
|
|
+ if (matchedUserIds.isEmpty()) {
|
|
|
+ result.put("matchedRelationCount", 0);
|
|
|
+ result.put("blacklistedRelationCount", 0);
|
|
|
+ result.put("taggedRelationCount", 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<FsUserCompanyUser> relations = fsUserCompanyUserMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<FsUserCompanyUser>().in(FsUserCompanyUser::getUserId, matchedUserIds)
|
|
|
+ );
|
|
|
+ result.put("matchedRelationCount", relations.size());
|
|
|
+ if (relations.isEmpty()) {
|
|
|
+ result.put("blacklistedRelationCount", 0);
|
|
|
+ result.put("taggedRelationCount", 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Long> relationIds = relations.stream()
|
|
|
+ .map(FsUserCompanyUser::getId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (!relationIds.isEmpty()) {
|
|
|
+ fsUserCompanyUserMapper.batchUpdateStatus(relationIds, BLACK_STATUS);
|
|
|
+ }
|
|
|
+ result.put("blacklistedRelationCount", relationIds.size());
|
|
|
+ result.put("taggedRelationCount", addProfessionalFraudTags(relations));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Set<Long> matchUserIds(FraudUsers fraudUser) {
|
|
|
+ Set<Long> userIds = new HashSet<>();
|
|
|
+ if (StringUtils.isNotBlank(fraudUser.getPhone())) {
|
|
|
+ String fraudPhone = normalizeFraudPhone(fraudUser.getPhone());
|
|
|
+ List<FsUser> users = fsUserMapper.selectFsUsersByPhoneLimitOne(fraudPhone);
|
|
|
+ if (users != null) {
|
|
|
+ userIds.addAll(users.stream().map(FsUser::getUserId).filter(Objects::nonNull).collect(Collectors.toSet()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.isNotBlank(fraudUser.getAddress())) {
|
|
|
+ List<Long> addressUserIds = fsUserAddressMapper.selectUserIdsByFullAddress(fraudUser.getAddress().trim());
|
|
|
+ if (addressUserIds != null) {
|
|
|
+ userIds.addAll(addressUserIds.stream().filter(Objects::nonNull).collect(Collectors.toSet()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return userIds;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int addProfessionalFraudTags(List<FsUserCompanyUser> relations) {
|
|
|
+ int count = 0;
|
|
|
+ for (FsUserCompanyUser relation : relations) {
|
|
|
+ if (relation.getUserId() == null || relation.getCompanyId() == null || relation.getCompanyUserId() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Long tagId = getOrCreateProfessionalFraudTagId(relation.getCompanyId());
|
|
|
+ if (tagId == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<CompanyTagUser> tagUsers = companyTagUserMapper.selectCompanyTagUserList(buildCompanyTagUserQuery(relation));
|
|
|
+ if (tagUsers == null || tagUsers.isEmpty()) {
|
|
|
+ CompanyTagUser companyTagUser = new CompanyTagUser();
|
|
|
+ companyTagUser.setUserId(relation.getUserId());
|
|
|
+ companyTagUser.setCompanyId(relation.getCompanyId());
|
|
|
+ companyTagUser.setCompanyUserId(relation.getCompanyUserId());
|
|
|
+ companyTagUser.setTagIds(String.valueOf(tagId));
|
|
|
+ companyTagUser.setCreateTime(DateUtils.getNowDate());
|
|
|
+ companyTagUserMapper.insertCompanyTagUser(companyTagUser);
|
|
|
+ count++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ CompanyTagUser companyTagUser = tagUsers.get(0);
|
|
|
+ Set<String> tagIdSet = Arrays.stream(Optional.ofNullable(companyTagUser.getTagIds()).orElse("").split(","))
|
|
|
+ .filter(StringUtils::isNotBlank)
|
|
|
+ .collect(Collectors.toCollection(LinkedHashSet::new));
|
|
|
+ if (tagIdSet.add(String.valueOf(tagId))) {
|
|
|
+ companyTagUser.setTagIds(String.join(",", tagIdSet));
|
|
|
+ companyTagUserMapper.updateCompanyTagUser(companyTagUser);
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ private CompanyTagUser buildCompanyTagUserQuery(FsUserCompanyUser relation) {
|
|
|
+ CompanyTagUser query = new CompanyTagUser();
|
|
|
+ query.setUserId(relation.getUserId());
|
|
|
+ query.setCompanyId(relation.getCompanyId());
|
|
|
+ query.setCompanyUserId(relation.getCompanyUserId());
|
|
|
+ return query;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String normalizeFraudPhone(String phone) {
|
|
|
+ String trimPhone = phone == null ? null : phone.trim();
|
|
|
+ if (StringUtils.isBlank(trimPhone)) {
|
|
|
+ return trimPhone;
|
|
|
+ }
|
|
|
+ return trimPhone.matches("^1\\d{10}$") ? encryptPhone(trimPhone) : trimPhone;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Long getOrCreateProfessionalFraudTagId(Long companyId) {
|
|
|
+ CompanyTag query = new CompanyTag();
|
|
|
+ query.setCompanyId(companyId);
|
|
|
+ query.setTag(PROFESSIONAL_FRAUD_TAG);
|
|
|
+ List<CompanyTag> tagList = companyTagMapper.selectCompanyTagList(query);
|
|
|
+ if (tagList != null && !tagList.isEmpty()) {
|
|
|
+ return tagList.get(0).getTagId();
|
|
|
+ }
|
|
|
+ CompanyTag companyTag = new CompanyTag();
|
|
|
+ companyTag.setCompanyId(companyId);
|
|
|
+ companyTag.setTag(PROFESSIONAL_FRAUD_TAG);
|
|
|
+ companyTagService.insertCompanyTag(companyTag);
|
|
|
+ return companyTag.getTagId();
|
|
|
+ }
|
|
|
+}
|