|  | @@ -17,12 +17,10 @@ import com.fs.course.domain.*;
 | 
	
		
			
				|  |  |  import com.fs.course.mapper.*;
 | 
	
		
			
				|  |  |  import com.fs.course.param.FsCourseLinkCreateParam;
 | 
	
		
			
				|  |  |  import com.fs.course.service.IFsCourseLinkService;
 | 
	
		
			
				|  |  | -import com.fs.qw.domain.QwExternalContact;
 | 
	
		
			
				|  |  | -import com.fs.qw.domain.QwGroupChat;
 | 
	
		
			
				|  |  | -import com.fs.qw.domain.QwGroupChatUser;
 | 
	
		
			
				|  |  | -import com.fs.qw.domain.QwUser;
 | 
	
		
			
				|  |  | +import com.fs.qw.domain.*;
 | 
	
		
			
				|  |  |  import com.fs.qw.mapper.QwExternalContactMapper;
 | 
	
		
			
				|  |  |  import com.fs.qw.mapper.QwUserMapper;
 | 
	
		
			
				|  |  | +import com.fs.qw.service.IQwCompanyService;
 | 
	
		
			
				|  |  |  import com.fs.qw.service.IQwGroupChatService;
 | 
	
		
			
				|  |  |  import com.fs.qw.service.IQwGroupChatUserService;
 | 
	
		
			
				|  |  |  import com.fs.qw.service.impl.QwExternalContactServiceImpl;
 | 
	
	
		
			
				|  | @@ -163,6 +161,9 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private ICompanyUserService companyUserService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private IQwCompanyService iQwCompanyService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @PostConstruct
 | 
	
		
			
				|  |  |      public void init() {
 | 
	
	
		
			
				|  | @@ -301,45 +302,48 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |              groupChatMap = PubFun.listToMapByGroupObject(qwGroupChatList, QwGroupChat::getChatId);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -//        Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
 | 
	
		
			
				|  |  | -//                .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
 | 
	
		
			
				|  |  | -        // 查询销售二级域名
 | 
	
		
			
				|  |  | -        Set<Long> ids = sopUserLogsVos.stream().map(s -> {
 | 
	
		
			
				|  |  | -            String[] userKey = s.getUserId().split("\\|");
 | 
	
		
			
				|  |  | -            if (userKey.length < 3) {
 | 
	
		
			
				|  |  | -                return null;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return Long.parseLong(userKey[1]);
 | 
	
		
			
				|  |  | -        }).filter(Objects::nonNull).collect(Collectors.toSet());
 | 
	
		
			
				|  |  | -        List<CompanyUser> companyUserList;
 | 
	
		
			
				|  |  | -        if (ids.isEmpty()) {
 | 
	
		
			
				|  |  | -            companyUserList = new ArrayList<>();
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -            companyUserList = companyUserService.selectCompanyUserByIds(ids);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
 | 
	
		
			
				|  |  | -                .peek(s -> {
 | 
	
		
			
				|  |  | -                    String[] userKey = s.getUserId().split("\\|");
 | 
	
		
			
				|  |  | -                    if (userKey.length < 3) {
 | 
	
		
			
				|  |  | -                        return;
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                    // 销售ID
 | 
	
		
			
				|  |  | -                    Long companyUserId = Long.parseLong(userKey[1]);
 | 
	
		
			
				|  |  | -                    CompanyUser companyUser = companyUserList.stream().filter(cu -> Objects.equals(cu.getUserId(), companyUserId)).findFirst().orElse(null);
 | 
	
		
			
				|  |  | -                    if (Objects.nonNull(companyUser)) {
 | 
	
		
			
				|  |  | -                        if (StringUtils.isNotBlank(companyUser.getDomain())) {
 | 
	
		
			
				|  |  | -                            s.setDomain(companyUser.getDomain().trim());
 | 
	
		
			
				|  |  | -                        } else {
 | 
	
		
			
				|  |  | -                            s.setDomain(config.getRealLinkDomainName().trim());
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                    } else {
 | 
	
		
			
				|  |  | -                        s.setDomain(config.getRealLinkDomainName().trim());
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                })
 | 
	
		
			
				|  |  |                  .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 查询销售二级域名
 | 
	
		
			
				|  |  | +//        Set<Long> ids = sopUserLogsVos.stream().map(s -> {
 | 
	
		
			
				|  |  | +//            String[] userKey = s.getUserId().split("\\|");
 | 
	
		
			
				|  |  | +//            if (userKey.length < 3) {
 | 
	
		
			
				|  |  | +//                return null;
 | 
	
		
			
				|  |  | +//            }
 | 
	
		
			
				|  |  | +//            return Long.parseLong(userKey[1]);
 | 
	
		
			
				|  |  | +//        }).filter(Objects::nonNull).collect(Collectors.toSet());
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//        List<CompanyUser> companyUserList;
 | 
	
		
			
				|  |  | +//        if (ids.isEmpty()) {
 | 
	
		
			
				|  |  | +//            companyUserList = new ArrayList<>();
 | 
	
		
			
				|  |  | +//        } else {
 | 
	
		
			
				|  |  | +//            companyUserList = companyUserService.selectCompanyUserByIds(ids);
 | 
	
		
			
				|  |  | +//        }
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//        Map<String, List<SopUserLogsVo>> sopLogsGroupedById = sopUserLogsVos.stream()
 | 
	
		
			
				|  |  | +//                .peek(s -> {
 | 
	
		
			
				|  |  | +//                    String[] userKey = s.getUserId().split("\\|");
 | 
	
		
			
				|  |  | +//                    if (userKey.length < 3) {
 | 
	
		
			
				|  |  | +//                        return;
 | 
	
		
			
				|  |  | +//                    }
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//                    // 销售ID
 | 
	
		
			
				|  |  | +//                    Long companyUserId = Long.parseLong(userKey[1]);
 | 
	
		
			
				|  |  | +//                    CompanyUser companyUser = companyUserList.stream().filter(cu -> Objects.equals(cu.getUserId(), companyUserId)).findFirst().orElse(null);
 | 
	
		
			
				|  |  | +//                    if (Objects.nonNull(companyUser)) {
 | 
	
		
			
				|  |  | +//                        if (!StringUtil.strIsNullOrEmpty(companyUser.getDomain())) {
 | 
	
		
			
				|  |  | +//                            s.setDomain(companyUser.getDomain().trim());
 | 
	
		
			
				|  |  | +//                        } else {
 | 
	
		
			
				|  |  | +//                            s.setDomain(config.getRealLinkDomainName().trim());
 | 
	
		
			
				|  |  | +//                        }
 | 
	
		
			
				|  |  | +//                    } else {
 | 
	
		
			
				|  |  | +//                        s.setDomain(config.getRealLinkDomainName().trim());
 | 
	
		
			
				|  |  | +//                    }
 | 
	
		
			
				|  |  | +//                })
 | 
	
		
			
				|  |  | +//                .collect(Collectors.groupingBy(SopUserLogsVo::getSopId));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          log.info("共分组 {} 个 SOP ID 进行处理。", sopLogsGroupedById.size());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          CountDownLatch sopGroupLatch = new CountDownLatch(sopLogsGroupedById.size());
 | 
	
	
		
			
				|  | @@ -347,7 +351,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |          for (Map.Entry<String, List<SopUserLogsVo>> entry : sopLogsGroupedById.entrySet()) {
 | 
	
		
			
				|  |  |              String sopId = entry.getKey();
 | 
	
		
			
				|  |  |              List<SopUserLogsVo> userLogsVos = entry.getValue();
 | 
	
		
			
				|  |  | -            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime, groupChatMap);
 | 
	
		
			
				|  |  | +            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime, groupChatMap,config);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 等待所有 SOP 分组处理完成
 | 
	
	
		
			
				|  | @@ -367,9 +371,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |              maxAttempts = 3,
 | 
	
		
			
				|  |  |              backoff = @Backoff(delay = 2000)
 | 
	
		
			
				|  |  |      )
 | 
	
		
			
				|  |  | -    public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch ,LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
 | 
	
		
			
				|  |  | +    public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch ,LocalDateTime currentTime,
 | 
	
		
			
				|  |  | +                                     Map<String, QwGroupChat> groupChatMap,CourseConfig config) {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  | -            processSopGroup(sopId, userLogsVos,currentTime, groupChatMap);
 | 
	
		
			
				|  |  | +            processSopGroup(sopId, userLogsVos,currentTime, groupChatMap, config);
 | 
	
		
			
				|  |  |          } catch (Exception e) {
 | 
	
		
			
				|  |  |              log.error("处理 SOP ID {} 时发生异常: {}", sopId, e.getMessage(), e);
 | 
	
		
			
				|  |  |          } finally {
 | 
	
	
		
			
				|  | @@ -378,7 +383,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos,LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) throws Exception {
 | 
	
		
			
				|  |  | +    private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos,LocalDateTime currentTime, Map<String,
 | 
	
		
			
				|  |  | +            QwGroupChat> groupChatMap,CourseConfig config) throws Exception {
 | 
	
		
			
				|  |  |          QwSopRuleTimeVO ruleTimeVO = sopMapper.selectQwSopByClickHouseId(sopId);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (ruleTimeVO == null) {
 | 
	
	
		
			
				|  | @@ -392,6 +398,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |              log.error("SOP ID {} 模板不存在,相关日志已清除。", sopId);
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          ruleTimeVO.setTempStatus(qwSopTemp.getStatus());
 | 
	
		
			
				|  |  |          ruleTimeVO.setTempGap(qwSopTemp.getGap());
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -410,9 +417,16 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        QwCompany qwCompany = iQwCompanyService.getQwCompanyByRedis(ruleTimeVO.getCorpId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (qwCompany == null ) {
 | 
	
		
			
				|  |  | +            log.error("SOP ID {} 的 公司信息为空 为空,跳过处理。", sopId);
 | 
	
		
			
				|  |  | +            return ;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          CountDownLatch userLogsLatch = new CountDownLatch(userLogsVos.size());
 | 
	
		
			
				|  |  |          for (SopUserLogsVo logVo : userLogsVos) {
 | 
	
		
			
				|  |  | -            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime, groupChatMap);
 | 
	
		
			
				|  |  | +            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime, groupChatMap,qwCompany.getMiniAppId(), config);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 等待所有用户日志处理完成
 | 
	
	
		
			
				|  | @@ -431,9 +445,11 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |              maxAttempts = 3,
 | 
	
		
			
				|  |  |              backoff = @Backoff(delay = 2000)
 | 
	
		
			
				|  |  |      )
 | 
	
		
			
				|  |  | -    public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, CountDownLatch latch, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
 | 
	
		
			
				|  |  | +    public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
 | 
	
		
			
				|  |  | +                                    CountDownLatch latch, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,
 | 
	
		
			
				|  |  | +                                    String miniAppId,CourseConfig config) {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  | -            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime, groupChatMap);
 | 
	
		
			
				|  |  | +            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime, groupChatMap, miniAppId, config);
 | 
	
		
			
				|  |  |          } catch (Exception e) {
 | 
	
		
			
				|  |  |              log.error("处理用户日志 {} 时发生异常: {}", logVo.getId(), e.getMessage(), e);
 | 
	
		
			
				|  |  |          } finally {
 | 
	
	
		
			
				|  | @@ -442,8 +458,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap) {
 | 
	
		
			
				|  |  | +    private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
 | 
	
		
			
				|  |  | +                                LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,String miniAppId,CourseConfig config) {
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              LocalDate startDate = LocalDate.parse(logVo.getStartTime(), DATE_FORMATTER);
 | 
	
		
			
				|  |  |              LocalDate currentDate = currentTime.toLocalDate();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -472,14 +490,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                  return;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            String[] userKey = logVo.getUserId().split("\\|");
 | 
	
		
			
				|  |  | -            if (userKey.length < 3) {
 | 
	
		
			
				|  |  | -                log.error("用户 ID {} 格式不正确,跳过处理。", logVo.getUserId());
 | 
	
		
			
				|  |  | -                return;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            String qwUserId = userKey[0].trim();
 | 
	
		
			
				|  |  | -            String companyUserId = userKey[1].trim();
 | 
	
		
			
				|  |  | -            String companyId = userKey[2].trim();
 | 
	
		
			
				|  |  | +//            String[] userKey = logVo.getUserId().split("\\|");
 | 
	
		
			
				|  |  | +//            if (userKey.length < 3) {
 | 
	
		
			
				|  |  | +//                log.error("用户 ID {} 格式不正确,跳过处理。", logVo.getUserId());
 | 
	
		
			
				|  |  | +//                return;
 | 
	
		
			
				|  |  | +//            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//            String qwUserId = userKey[0].trim();
 | 
	
		
			
				|  |  | +//            String companyUserId = userKey[1].trim();
 | 
	
		
			
				|  |  | +//            String companyId = userKey[2].trim();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //获取企业微信员工的称呼//从redis里或者从库里取
 | 
	
	
		
			
				|  | @@ -489,6 +508,26 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                  return;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            String qwUserId = String.valueOf(qwUserByRedis.getId()).trim();
 | 
	
		
			
				|  |  | +            String companyUserId = String.valueOf(qwUserByRedis.getCompanyUserId()).trim();
 | 
	
		
			
				|  |  | +            String companyId = String.valueOf(qwUserByRedis.getCompanyId()).trim();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (StringUtil.strIsNullOrEmpty(companyUserId) || StringUtil.strIsNullOrEmpty(companyId) || "null".equals(companyUserId)) {
 | 
	
		
			
				|  |  | +                log.error("员工未绑定销售账号或公司,跳过处理:"+qwUserId);
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            CompanyUser companyUser = companyUserService.selectCompanyUserByIdForRedis(Long.valueOf(companyUserId));
 | 
	
		
			
				|  |  | +            if (Objects.nonNull(companyUser)) {
 | 
	
		
			
				|  |  | +                if (!StringUtil.strIsNullOrEmpty(companyUser.getDomain())) {
 | 
	
		
			
				|  |  | +                    logVo.setDomain(companyUser.getDomain().trim());
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    logVo.setDomain(config.getRealLinkDomainName().trim());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                logVo.setDomain(config.getRealLinkDomainName().trim());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              //寻找时间
 | 
	
		
			
				|  |  |  //            LocalDateTime currentTime = LocalDateTime.of(2024, 12, 25,23 , 40);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -582,20 +621,22 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                              }
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                        // 获取fsUserId
 | 
	
		
			
				|  |  | -                        Set<Long> externalIds = sopUserLogsInfos.stream().map(SopUserLogsInfo::getExternalId).collect(Collectors.toSet());
 | 
	
		
			
				|  |  | -                        if (!externalIds.isEmpty()) {
 | 
	
		
			
				|  |  | -                            List<QwExternalContact> externalContactList = qwExternalContactService.list(Wrappers.<QwExternalContact>lambdaQuery().in(QwExternalContact::getId, externalIds));
 | 
	
		
			
				|  |  | -                            sopUserLogsInfos.forEach(s -> {
 | 
	
		
			
				|  |  | -                                QwExternalContact qwExternalContact = externalContactList.stream().filter(e -> Objects.equals(s.getExternalId(), e.getId())).findFirst().orElse(null);
 | 
	
		
			
				|  |  | -                                if (Objects.nonNull(qwExternalContact)) {
 | 
	
		
			
				|  |  | -                                    s.setFsUserId(qwExternalContact.getFsUserId());
 | 
	
		
			
				|  |  | -                                }
 | 
	
		
			
				|  |  | -                            });
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | +                        // 获取fsUserId TODO
 | 
	
		
			
				|  |  | +//                        Set<Long> externalIds = sopUserLogsInfos.stream().map(SopUserLogsInfo::getExternalId).collect(Collectors.toSet());
 | 
	
		
			
				|  |  | +//                        if (!externalIds.isEmpty()) {
 | 
	
		
			
				|  |  | +//                            List<QwExternalContact> externalContactList = qwExternalContactService.list(Wrappers.<QwExternalContact>lambdaQuery().in(QwExternalContact::getId, externalIds));
 | 
	
		
			
				|  |  | +//                            sopUserLogsInfos.forEach(s -> {
 | 
	
		
			
				|  |  | +//                                QwExternalContact qwExternalContact = externalContactList.stream().filter(e -> Objects.equals(s.getExternalId(), e.getId())).findFirst().orElse(null);
 | 
	
		
			
				|  |  | +//                                if (Objects.nonNull(qwExternalContact)) {
 | 
	
		
			
				|  |  | +//                                    s.setFsUserId(qwExternalContact.getFsUserId());
 | 
	
		
			
				|  |  | +//                                }
 | 
	
		
			
				|  |  | +//                            });
 | 
	
		
			
				|  |  | +//                        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId, companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(), groupChatMap);
 | 
	
		
			
				|  |  | +                        insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId,
 | 
	
		
			
				|  |  | +                                companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(),
 | 
	
		
			
				|  |  | +                                groupChatMap, miniAppId);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  } catch (Exception e) {
 | 
	
	
		
			
				|  | @@ -637,7 +678,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |      //消息处理
 | 
	
		
			
				|  |  |      private void insertSopUserLogs(List<SopUserLogsInfo> sopUserLogsInfos, SopUserLogsVo logVo, Date sendTime,
 | 
	
		
			
				|  |  |                                     QwSopRuleTimeVO ruleTimeVO, QwSopTempSetting.Content content,
 | 
	
		
			
				|  |  | -                                   String qwUserId,String companyUserId,String companyId,String welcomeText,String qwUserName, Map<String, QwGroupChat> groupChatMap) {
 | 
	
		
			
				|  |  | +                                   String qwUserId,String companyUserId,String companyId,String welcomeText,String qwUserName,
 | 
	
		
			
				|  |  | +                                   Map<String, QwGroupChat> groupChatMap,String miniAppId) {
 | 
	
		
			
				|  |  |          String formattedSendTime = sendTime.toInstant()
 | 
	
		
			
				|  |  |                  .atZone(ZoneId.systemDefault())
 | 
	
		
			
				|  |  |                  .format(DATE_TIME_FORMATTER);
 | 
	
	
		
			
				|  | @@ -674,7 +716,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                      log.error("群聊创建看课记录失败!", e);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
 | 
	
		
			
				|  |  | -                        type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName, null, true);
 | 
	
		
			
				|  |  | +                        type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName, null, true, miniAppId);
 | 
	
		
			
				|  |  |              } else {
 | 
	
		
			
				|  |  |                  if(groupChat.getChatUserList() != null && !groupChat.getChatUserList().isEmpty()){
 | 
	
		
			
				|  |  |                      groupChat.getChatUserList().forEach(user -> {
 | 
	
	
		
			
				|  | @@ -682,7 +724,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                          ruleTimeVO.setRemark("客户群催课");
 | 
	
		
			
				|  |  |                          QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, user.getUserId(), user.getName(), null, isOfficial, null);
 | 
	
		
			
				|  |  |                          handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
 | 
	
		
			
				|  |  | -                                type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName, null, false);
 | 
	
		
			
				|  |  | +                                type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName, null, false, miniAppId);
 | 
	
		
			
				|  |  |                      });
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -695,7 +737,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                      Long fsUserId = contactId.getFsUserId();
 | 
	
		
			
				|  |  |                      QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId, isOfficial, contactId.getExternalId());
 | 
	
		
			
				|  |  |                      handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
 | 
	
		
			
				|  |  | -                            type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false);
 | 
	
		
			
				|  |  | +                            type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false, miniAppId);
 | 
	
		
			
				|  |  |                  } catch (Exception e) {
 | 
	
		
			
				|  |  |                      log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
 | 
	
		
			
				|  |  |                  }
 | 
	
	
		
			
				|  | @@ -745,7 +787,23 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |          sopLogs.setCorpId(logVo.getCorpId());
 | 
	
		
			
				|  |  |          sopLogs.setLogType(ruleTimeVO.getType());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        sopLogs.setSendType(isOfficial == 1 ? 1 : ruleTimeVO.getSendType());
 | 
	
		
			
				|  |  | +        if (isOfficial == 1) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
 | 
	
		
			
				|  |  | +                sopLogs.setSendType(2);
 | 
	
		
			
				|  |  | +                sopLogs.setRemark("未绑定小程序用户,单链补发");
 | 
	
		
			
				|  |  | +                //时间设置成固定7点
 | 
	
		
			
				|  |  | +                LocalDateTime dateTime = LocalDateTime.parse(formattedSendTime, DATE_TIME_FORMATTER);
 | 
	
		
			
				|  |  | +                sopLogs.setSendTime(OUTPUT_FORMATTER.format(dateTime));
 | 
	
		
			
				|  |  | +            }else {
 | 
	
		
			
				|  |  | +                sopLogs.setSendType(1);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        }else if (isOfficial==0){
 | 
	
		
			
				|  |  | +            sopLogs.setSendType(ruleTimeVO.getSendType() == 1 ? 2 : ruleTimeVO.getSendType());
 | 
	
		
			
				|  |  | +        }else{
 | 
	
		
			
				|  |  | +            sopLogs.setSendType(ruleTimeVO.getSendType());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          sopLogs.setSendStatus(3L);
 | 
	
	
		
			
				|  | @@ -754,11 +812,12 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |          String[] userKey = logVo.getUserId().split("\\|");
 | 
	
		
			
				|  |  |          sopLogs.setCompanyId(Long.valueOf(userKey[2].trim()));
 | 
	
		
			
				|  |  |          sopLogs.setSopId(logVo.getSopId());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        sopLogs.setSort(Integer.valueOf(logVo.getStartTime().replaceAll("-","")));
 | 
	
		
			
				|  |  |          sopLogs.setExternalUserId(externalContactId);
 | 
	
		
			
				|  |  |          sopLogs.setExternalId(externalId);
 | 
	
		
			
				|  |  |          sopLogs.setExternalUserName(externalUserName);
 | 
	
		
			
				|  |  |          sopLogs.setFsUserId(fsUserId);
 | 
	
		
			
				|  |  | +        sopLogs.setUserLogsId(logVo.getId());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          return sopLogs;
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -766,14 +825,15 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |      private void handleLogBasedOnType(QwSopLogs sopLogs, QwSopTempSetting.Content content,
 | 
	
		
			
				|  |  |                                        SopUserLogsVo logVo, Date sendTime, Long courseId,
 | 
	
		
			
				|  |  |                                        Long videoId, int type, String qwUserId,
 | 
	
		
			
				|  |  | -                                      String companyUserId, String companyId, String externalId,String welcomeText,String qwUserName, Long fsUserId, boolean isGroupChat) {
 | 
	
		
			
				|  |  | +                                      String companyUserId, String companyId, String externalId,String welcomeText,
 | 
	
		
			
				|  |  | +                                      String qwUserName, Long fsUserId, boolean isGroupChat,String miniAppId) {
 | 
	
		
			
				|  |  |          switch (type) {
 | 
	
		
			
				|  |  |              case 1:
 | 
	
		
			
				|  |  |                  handleNormalMessage(sopLogs, content,companyUserId);
 | 
	
		
			
				|  |  |                  break;
 | 
	
		
			
				|  |  |              case 2:
 | 
	
		
			
				|  |  |                  handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
 | 
	
		
			
				|  |  | -                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId, isGroupChat);
 | 
	
		
			
				|  |  | +                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId, isGroupChat, miniAppId);
 | 
	
		
			
				|  |  |                  break;
 | 
	
		
			
				|  |  |              case 3:
 | 
	
		
			
				|  |  |                  handleOrderMessage(sopLogs, content);
 | 
	
	
		
			
				|  | @@ -805,7 +865,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |      private void handleCourseMessage(QwSopLogs sopLogs, QwSopTempSetting.Content content,
 | 
	
		
			
				|  |  |                                       SopUserLogsVo logVo, Date sendTime, Long courseId,
 | 
	
		
			
				|  |  |                                       Long videoId, String qwUserId, String companyUserId,
 | 
	
		
			
				|  |  | -                                     String companyId, String externalId,String welcomeText,String qwUserName, Long fsUserId, boolean isGroupChat) {
 | 
	
		
			
				|  |  | +                                     String companyId, String externalId,String welcomeText,String qwUserName,
 | 
	
		
			
				|  |  | +                                     Long fsUserId, boolean isGroupChat,String miniAppId) {
 | 
	
		
			
				|  |  |          // 深拷贝 Content 对象,避免使用 JSON
 | 
	
		
			
				|  |  |          QwSopTempSetting.Content clonedContent = deepCopyContent(content);
 | 
	
		
			
				|  |  |          if (clonedContent == null) {
 | 
	
	
		
			
				|  | @@ -816,6 +877,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |  //
 | 
	
		
			
				|  |  |  //        Integer courseType = clonedContent.getCourseType();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        String isOfficial = clonedContent.getIsOfficial();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          List<QwSopTempSetting.Content.Setting> settings = clonedContent.getSetting();
 | 
	
		
			
				|  |  |          if (settings == null || settings.isEmpty()) {
 | 
	
		
			
				|  |  |              log.error("Cloned content settings are empty, skipping.");
 | 
	
	
		
			
				|  | @@ -848,7 +911,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                          } else {
 | 
	
		
			
				|  |  |                              addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId, logVo);
 | 
	
		
			
				|  |  |                              link = generateShortLink(setting, logVo, sendTime, courseId, videoId,
 | 
	
		
			
				|  |  | -                                    qwUserId, companyUserId, companyId, externalId, fsUserId);
 | 
	
		
			
				|  |  | +                                    qwUserId, companyUserId, companyId, externalId,isOfficial,sopLogs.getFsUserId());
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                          if (StringUtils.isNotEmpty(link)) {
 | 
	
	
		
			
				|  | @@ -859,7 +922,6 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                                  if (currentValue == null) {
 | 
	
		
			
				|  |  |                                      setting.setValue(link);
 | 
	
		
			
				|  |  |                                  } else {
 | 
	
		
			
				|  |  | -//                                    setting.setValue(currentValue + "\n" + sortLink);
 | 
	
		
			
				|  |  |                                      setting.setValue(currentValue
 | 
	
		
			
				|  |  |                                              .replaceAll("#销售称呼#", StringUtil.strIsNullOrEmpty(welcomeText) ? "" : welcomeText)
 | 
	
		
			
				|  |  |                                              + "\n" + link);
 | 
	
	
		
			
				|  | @@ -882,12 +944,18 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |                      addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      String sortLink = createLinkByMiniApp(setting, logVo, sendTime, courseId, videoId,
 | 
	
		
			
				|  |  | -                            qwUserId, companyUserId, companyId, externalId);
 | 
	
		
			
				|  |  | +                            qwUserId, companyUserId, companyId, externalId,isOfficial,sopLogs.getFsUserId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    if (!StringUtil.strIsNullOrEmpty(miniAppId)) {
 | 
	
		
			
				|  |  | +                        setting.setMiniprogramAppid(miniAppId);
 | 
	
		
			
				|  |  | +                    }else {
 | 
	
		
			
				|  |  | +                        log.error("公司的小程序id为空:采用了前端传的固定值"+sopLogs.getSopId());
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      setting.setMiniprogramPage(sortLink.replaceAll("^[\\s\\u2005]+", ""));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      try {
 | 
	
		
			
				|  |  | -                        setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl()) ? "https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png" : setting.getMiniprogramPicUrl());
 | 
	
		
			
				|  |  | +                        setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl())?"https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png":setting.getMiniprogramPicUrl());
 | 
	
		
			
				|  |  |                      } catch (Exception e) {
 | 
	
		
			
				|  |  |                          log.error("赋值-小程序封面地址失败-" + e);
 | 
	
		
			
				|  |  |                      }
 | 
	
	
		
			
				|  | @@ -933,7 +1001,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private String generateShortLink(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
 | 
	
		
			
				|  |  |                                       Long courseId, Long videoId, String qwUserId,
 | 
	
		
			
				|  |  | -                                     String companyUserId, String companyId, String externalId, Long fsUserId) {
 | 
	
		
			
				|  |  | +                                     String companyUserId, String companyId, String externalId,String isOfficial, Long fsUserId) {
 | 
	
		
			
				|  |  |          // 获取缓存的配置
 | 
	
		
			
				|  |  |          CourseConfig config;
 | 
	
		
			
				|  |  |          synchronized(configLock) {
 | 
	
	
		
			
				|  | @@ -954,7 +1022,22 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |          link.setCorpId(logVo.getCorpId());
 | 
	
		
			
				|  |  |          link.setCourseId(courseId.longValue());
 | 
	
		
			
				|  |  |          link.setQwExternalId(Long.parseLong(externalId));
 | 
	
		
			
				|  |  | -        link.setLinkType(0); //正常链接
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (StringUtil.strIsNullOrEmpty(isOfficial)){
 | 
	
		
			
				|  |  | +            link.setLinkType(0);
 | 
	
		
			
				|  |  | +        }else {
 | 
	
		
			
				|  |  | +            if (isOfficial.equals("1")) {
 | 
	
		
			
				|  |  | +                if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
 | 
	
		
			
				|  |  | +                    link.setLinkType(0);
 | 
	
		
			
				|  |  | +                }else {
 | 
	
		
			
				|  |  | +                    link.setLinkType(5);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }else if (isOfficial.equals("0")){
 | 
	
		
			
				|  |  | +                link.setLinkType(0);
 | 
	
		
			
				|  |  | +            }else{
 | 
	
		
			
				|  |  | +                link.setLinkType(0);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          FsCourseRealLink courseMap = new FsCourseRealLink();
 | 
	
		
			
				|  |  |          courseMap.setCompanyId(link.getCompanyId());
 | 
	
	
		
			
				|  | @@ -964,9 +1047,25 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |          courseMap.setCorpId(link.getCorpId());
 | 
	
		
			
				|  |  |          courseMap.setCourseId(link.getCourseId());
 | 
	
		
			
				|  |  |          courseMap.setQwExternalId(link.getQwExternalId());
 | 
	
		
			
				|  |  | -        courseMap.setLinkType(0);
 | 
	
		
			
				|  |  |          courseMap.setFsUserId(fsUserId);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        if (StringUtil.strIsNullOrEmpty(isOfficial)){
 | 
	
		
			
				|  |  | +            courseMap.setLinkType(0);
 | 
	
		
			
				|  |  | +        }else {
 | 
	
		
			
				|  |  | +            if (isOfficial.equals("1")) {
 | 
	
		
			
				|  |  | +                if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
 | 
	
		
			
				|  |  | +                    courseMap.setLinkType(0);
 | 
	
		
			
				|  |  | +                }else {
 | 
	
		
			
				|  |  | +                    courseMap.setLinkType(5);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }else if (isOfficial.equals("0")){
 | 
	
		
			
				|  |  | +                courseMap.setLinkType(0);
 | 
	
		
			
				|  |  | +            }else{
 | 
	
		
			
				|  |  | +                courseMap.setLinkType(0);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          String courseJson = JSON.toJSONString(courseMap);
 | 
	
		
			
				|  |  |          String realLinkFull = REAL_LINK_PREFIX + courseJson;
 | 
	
		
			
				|  |  |          link.setRealLink(realLinkFull);
 | 
	
	
		
			
				|  | @@ -1112,7 +1211,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private String createLinkByMiniApp(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
 | 
	
		
			
				|  |  |                                       Long courseId, Long videoId, String qwUserId,
 | 
	
		
			
				|  |  | -                                     String companyUserId, String companyId, String externalId) {
 | 
	
		
			
				|  |  | +                                     String companyUserId, String companyId, String externalId,String isOfficial,Long fsUserId) {
 | 
	
		
			
				|  |  |          // 获取缓存的配置
 | 
	
		
			
				|  |  |          CourseConfig config;
 | 
	
		
			
				|  |  |          synchronized(configLock) {
 | 
	
	
		
			
				|  | @@ -1137,7 +1236,22 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |          link.setCorpId(logVo.getCorpId());
 | 
	
		
			
				|  |  |          link.setCourseId(courseId.longValue());
 | 
	
		
			
				|  |  |          link.setQwExternalId(Long.parseLong(externalId));
 | 
	
		
			
				|  |  | -        link.setLinkType(3); //正常链接
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (StringUtil.strIsNullOrEmpty(isOfficial)){
 | 
	
		
			
				|  |  | +            link.setLinkType(3);
 | 
	
		
			
				|  |  | +        }else {
 | 
	
		
			
				|  |  | +            if (isOfficial.equals("1")) {
 | 
	
		
			
				|  |  | +                if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
 | 
	
		
			
				|  |  | +                    link.setLinkType(3);
 | 
	
		
			
				|  |  | +                }else {
 | 
	
		
			
				|  |  | +                    link.setLinkType(5);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }else if (isOfficial.equals("0")){
 | 
	
		
			
				|  |  | +                link.setLinkType(3);
 | 
	
		
			
				|  |  | +            }else{
 | 
	
		
			
				|  |  | +                link.setLinkType(3);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          String randomString = generateRandomStringWithLock();
 | 
	
		
			
				|  |  |          if (StringUtil.strIsNullOrEmpty(randomString)){
 | 
	
	
		
			
				|  | @@ -1153,7 +1267,6 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          String courseJson = JSON.toJSONString(courseMap);
 | 
	
		
			
				|  |  |          String realLinkFull = miniappRealLink + courseJson;
 | 
	
		
			
				|  |  | -//        String realLinkFull = config.getMiniprogramPage() + courseJson;
 | 
	
		
			
				|  |  |          link.setRealLink(realLinkFull);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |