修复了不能显示首存金额的问题

This commit is contained in:
zayac 2024-06-17 17:06:33 +08:00
parent 0cd73df06a
commit 303db89f46
6 changed files with 213 additions and 157 deletions

View File

@ -1,3 +1,19 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zayac.admin.req; package com.zayac.admin.req;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
@ -26,6 +42,7 @@ public class ActiveListReq {
/** /**
* 是否重置 * 是否重置
*/ */
@Builder.Default
private Boolean isRest = false; private Boolean isRest = false;
/** /**

View File

@ -1,3 +1,19 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zayac.admin.resp; package com.zayac.admin.resp;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -5,7 +21,6 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**

View File

@ -121,7 +121,7 @@ public class CheckRegAndDep {
.processRegistration(minister, account, accountUsernameToUserMap, currentTeamInfo, prevTeamInfo, nowDate, asyncTaskExecutor); .processRegistration(minister, account, accountUsernameToUserMap, currentTeamInfo, prevTeamInfo, nowDate, asyncTaskExecutor);
CompletableFuture<Void> depositProcess = depositService CompletableFuture<Void> depositProcess = depositService
.processDeposits(minister, accountUsernameToUserMap, account, currentTeamInfo, prevTeamInfo, nowDate, asyncTaskExecutor); .processDeposits(minister, accountUsernameToUserMap, account, currentTeamInfo, prevTeamInfo, nowDate, nowDateTime, asyncTaskExecutor);
return CompletableFuture.allOf(registrationProcess, depositProcess).thenRunAsync(() -> { return CompletableFuture.allOf(registrationProcess, depositProcess).thenRunAsync(() -> {
teamService.updateTeamInfo(account, currentTeamInfo); teamService.updateTeamInfo(account, currentTeamInfo);

View File

@ -16,6 +16,7 @@
package com.zayac.admin.service; package com.zayac.admin.service;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.zayac.admin.common.enums.DisEnableStatusEnum; import com.zayac.admin.common.enums.DisEnableStatusEnum;
import com.zayac.admin.constant.ApiPathConstants; import com.zayac.admin.constant.ApiPathConstants;
@ -35,6 +36,7 @@ import org.springframework.stereotype.Service;
import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.cache.redisson.util.RedisUtils;
import top.continew.starter.core.exception.BusinessException; import top.continew.starter.core.exception.BusinessException;
import java.math.BigDecimal;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -49,7 +51,6 @@ import java.util.stream.Collectors;
import static com.zayac.admin.common.constant.CacheConstants.SUCCESSFULLY_PAYED_ACCOUNTNAME; import static com.zayac.admin.common.constant.CacheConstants.SUCCESSFULLY_PAYED_ACCOUNTNAME;
import static com.zayac.admin.utils.CommonUtils.findChangedTeamAccount; import static com.zayac.admin.utils.CommonUtils.findChangedTeamAccount;
import static com.zayac.admin.utils.CommonUtils.getLastNElements;
@Slf4j @Slf4j
@Service @Service
@ -61,19 +62,19 @@ public class DepositService {
private static final String BOT_TOKEN = "6013830443:AAHUOS4v6Ln19ziZkH-L28-HZQLJrGcvhto"; private static final String BOT_TOKEN = "6013830443:AAHUOS4v6Ln19ziZkH-L28-HZQLJrGcvhto";
private static final Long TELEGRAM_CHAT_ID = 6054562838L; private static final Long TELEGRAM_CHAT_ID = 6054562838L;
public CompletableFuture<Void> processDeposits(UserWithRolesAndAccountsResp ministerUser, public CompletableFuture<Void> processDeposits(UserWithRolesAndAccountsResp ministerUser,
Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap, Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap,
AccountResp account, AccountResp account,
Team currentTeam, Team currentTeam,
Team previousTeam, Team previousTeam,
LocalDate nowDate, LocalDate nowDate,
LocalDateTime nowDateTime,
Executor asyncTaskExecutor) { Executor asyncTaskExecutor) {
if (previousTeam == null || currentTeam.getFirstDepositNum() <= previousTeam.getFirstDepositNum()) { if (previousTeam == null || currentTeam.getFirstDepositNum() <= previousTeam.getFirstDepositNum()) {
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }
return processDepositRecords(ministerUser, accountUsernameToUserMap, account, currentTeam, previousTeam, nowDate, asyncTaskExecutor); return processDepositRecords(ministerUser, accountUsernameToUserMap, account, currentTeam, previousTeam, nowDate, nowDateTime, asyncTaskExecutor);
} }
private CompletableFuture<Void> processDepositRecords(UserWithRolesAndAccountsResp ministerUser, private CompletableFuture<Void> processDepositRecords(UserWithRolesAndAccountsResp ministerUser,
@ -82,14 +83,15 @@ public class DepositService {
Team currentTeam, Team currentTeam,
Team previousTeam, Team previousTeam,
LocalDate nowDate, LocalDate nowDate,
LocalDateTime nowDateTime,
Executor asyncTaskExecutor) { Executor asyncTaskExecutor) {
List<TeamAccountWithChange> hasNewDepositAccounts = findChangedTeamAccount(previousTeam, currentTeam).stream() List<TeamAccountWithChange> hasNewDepositAccounts = findChangedTeamAccount(previousTeam, currentTeam).stream()
.filter(teamAccountWithChange -> teamAccountWithChange.getNewDepositNum() > 0) .filter(teamAccountWithChange -> teamAccountWithChange.getNewDepositNum() > 0)
.toList(); .toList();
List<CompletableFuture<Void>> allTasks = hasNewDepositAccounts.stream() List<CompletableFuture<Void>> allTasks = hasNewDepositAccounts.stream()
.map(accountWithChange -> processAccountChanges(accountWithChange, ministerUser, accountUsernameToUserMap, account, nowDate, asyncTaskExecutor)) .map(accountWithChange -> processAccountChanges(accountWithChange, ministerUser, accountUsernameToUserMap, account, nowDate, nowDateTime, asyncTaskExecutor))
.toList(); .toList();
return CompletableFuture.allOf(allTasks.toArray(new CompletableFuture[0])); return CompletableFuture.allOf(allTasks.toArray(new CompletableFuture[0]));
} }
@ -99,100 +101,124 @@ public class DepositService {
Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap, Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap,
AccountResp account, AccountResp account,
LocalDate nowDate, LocalDate nowDate,
LocalDateTime nowDateTime,
Executor asyncTaskExecutor) { Executor asyncTaskExecutor) {
ActiveListReq req = ActiveListReq.builder() ActiveListReq req = ActiveListReq.builder()
.pageNum(1) .pageNum(1)
.activeType(3) .activeType(3)
.topAgentName(accountWithChange.getAgentName()) .topAgentName(accountWithChange.getAgentName())
.date(nowDate) .date(nowDate)
.isRest(false) .pageSize(9999)
.build(); .isRest(false)
.build();
return completableFutureWebClientService return completableFutureWebClientService
.fetchDataForAccount(account, ApiPathConstants.ACTIVE_LIST, req, new ParameterizedTypeReference<ApiResponse<Pagination<List<ActiveListResp>>>>() { .fetchDataForAccount(account, ApiPathConstants.ACTIVE_LIST, req, new ParameterizedTypeReference<ApiResponse<Pagination<List<ActiveListResp>>>>() {
}) })
.thenComposeAsync(page -> fetchAndProcessActiveList(account, req, page, accountWithChange, ministerUser, accountUsernameToUserMap, asyncTaskExecutor), asyncTaskExecutor) .thenApply(Pagination::getList)
.exceptionally(ex -> { .thenComposeAsync(activeListResps -> {
// 处理异常 // 过滤并排序
log.error("Error processing account changes for account: {}", account, ex); List<ActiveListResp> sortedList = activeListResps.stream()
return null; .filter(resp -> resp.getFirstPayTime() != null && resp.getFirstPayTime()
}); .isAfter(nowDateTime.minusMinutes(5)))
} .sorted(Comparator.comparing(ActiveListResp::getFirstPayTime))
.collect(Collectors.toList());
private CompletableFuture<Void> fetchAndProcessActiveList(AccountResp account, ActiveListReq req, Pagination<List<ActiveListResp>> page, // 截取后N个元素
TeamAccountWithChange accountWithChange, UserWithRolesAndAccountsResp ministerUser, List<ActiveListResp> activeListRespList = ListUtil.sub(sortedList, -accountWithChange
Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap, Executor asyncTaskExecutor) { .getNewDepositNum(), sortedList.size());
req.setPageNum(page.getPageNum());
return completableFutureWebClientService // 异步处理每个响应
.fetchDataForAccount(account, ApiPathConstants.ACTIVE_LIST, req, new ParameterizedTypeReference<ApiResponse<Pagination<List<ActiveListResp>>>>() { List<CompletableFuture<Void>> futures = activeListRespList.stream().map(resp -> {
}) if (resp.getDeposit().compareTo(BigDecimal.ZERO) == 0) {
.thenApply(Pagination::getList) LocalDate startDate = nowDateTime.minusHours(1).toLocalDate();
.thenAcceptAsync(activeListResps -> { PayRecordsListReq payRecordsListReq = PayRecordsListReq.builder()
List<ActiveListResp> sortedList = activeListResps.stream() .startDate(startDate)
.sorted(Comparator.comparing(ActiveListResp::getFirstPayTime)) .endDate(nowDate)
.collect(Collectors.toList()); .memberName(resp.getName())
List<ActiveListResp> activeListRespList = getLastNElements(sortedList, accountWithChange.getNewDepositNum()); .pageSize(10)
String depositResults = buildDepositResults(activeListRespList); .payState(2)
String notification = buildNotificationMessage(accountWithChange, depositResults); .agentName(accountWithChange.getAgentName())
sendNotifications(accountWithChange, ministerUser, accountUsernameToUserMap, notification); .build();
}, asyncTaskExecutor);
return completableFutureWebClientService
.fetchDataForAccount(account, ApiPathConstants.PAY_RECORDS_LIST_URL, payRecordsListReq, new ParameterizedTypeReference<ApiResponse<Pagination<List<PayRecord>>>>() {
})
.thenApply(Pagination::getList)
.thenAcceptAsync(payRecords -> {
if (payRecords != null && !payRecords.isEmpty()) {
resp.setDeposit(payRecords.get(0).getScoreAmount());
} else {
log.warn("No pay records found for member: {}", resp.getName());
}
}, asyncTaskExecutor);
}
return CompletableFuture.<Void>completedFuture(null);
}).toList();
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> activeListRespList);
}, asyncTaskExecutor)
.thenAcceptAsync(activeListRespList -> {
String depositResults = buildDepositResults(activeListRespList);
String notification = buildNotificationMessage(accountWithChange, depositResults);
sendNotifications(accountWithChange, ministerUser, accountUsernameToUserMap, notification);
}, asyncTaskExecutor)
.exceptionally(ex -> {
log.error("Error processing account changes for account: {}", account, ex);
return null;
});
} }
private String buildDepositResults(List<ActiveListResp> activeListRespList) { private String buildDepositResults(List<ActiveListResp> activeListRespList) {
StringBuilder depositResults = new StringBuilder(); StringBuilder depositResults = new StringBuilder();
activeListRespList.forEach(activeListResp -> activeListRespList.forEach(activeListResp -> depositResults.append(telegramMessageService
depositResults.append(telegramMessageService.buildDepositResultsMessage(activeListResp.getName(), activeListResp.getDeposit())) .buildDepositResultsMessage(activeListResp.getName(), activeListResp.getDeposit())));
);
return depositResults.toString(); return depositResults.toString();
} }
private String buildNotificationMessage(TeamAccountWithChange accountWithChange, String depositResults) { private String buildNotificationMessage(TeamAccountWithChange accountWithChange, String depositResults) {
return telegramMessageService.buildDepositMessage( return telegramMessageService.buildDepositMessage(accountWithChange.getAgentName(), accountWithChange
accountWithChange.getAgentName(), .getNewDepositNum(), depositResults, accountWithChange.getFirstDepositNum());
accountWithChange.getNewDepositNum(),
depositResults,
accountWithChange.getFirstDepositNum()
);
} }
private void sendNotifications(TeamAccountWithChange accountWithChange, UserWithRolesAndAccountsResp ministerUser, private void sendNotifications(TeamAccountWithChange accountWithChange,
Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap, String notification) { UserWithRolesAndAccountsResp ministerUser,
Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap,
String notification) {
var currUser = accountUsernameToUserMap.get(accountWithChange.getAgentName()); var currUser = accountUsernameToUserMap.get(accountWithChange.getAgentName());
if (currUser != null && DisEnableStatusEnum.ENABLE.equals(currUser.getNeedNotify())) { if (currUser != null && DisEnableStatusEnum.ENABLE.equals(currUser.getNeedNotify())) {
String botToken = StrUtil.isEmpty(currUser.getBotToken()) String botToken = StrUtil.isEmpty(currUser.getBotToken())
? ministerUser.getBotToken() ? ministerUser.getBotToken()
: currUser.getBotToken(); : currUser.getBotToken();
telegramMessageService.sendMessage(botToken, currUser.getRegAndDepIds(), notification); telegramMessageService.sendMessage(botToken, currUser.getRegAndDepIds(), notification);
} }
telegramMessageService.sendMessage(BOT_TOKEN, TELEGRAM_CHAT_ID, notification); telegramMessageService.sendMessage(BOT_TOKEN, TELEGRAM_CHAT_ID, notification);
} }
// // 凌晨的时候查询存款记录时往前减一天 防止凌晨的时候出现查询不到存款记录的问题
// // 凌晨的时候查询存款记录时往前减一天 防止凌晨的时候出现查询不到存款记录的问题 // LocalDate startDate = nowDateTime.minusHours(1).toLocalDate();
// LocalDate startDate = nowDateTime.minusHours(1).toLocalDate(); // PayRecordsListReq req = PayRecordsListReq.builder()
// PayRecordsListReq req = PayRecordsListReq.builder() // .startDate(startDate)
// .startDate(startDate) // .endDate(nowDate)
// .endDate(nowDate) // .pageSize(100)
// .pageSize(100) // .payState(2)
// .payState(2) // .agentName(accountWithChange.getAgentName())
// .agentName(accountWithChange.getAgentName()) // .build();
// .build(); //
// // StringBuilder depositResults = new StringBuilder();
// StringBuilder depositResults = new StringBuilder(); // AtomicInteger depositCounter = new AtomicInteger(0);
// AtomicInteger depositCounter = new AtomicInteger(0); //
// // return completableFutureWebClientService
// return completableFutureWebClientService // .fetchDataForAccount(account,ApiPathConstants.PAY_RECORDS_LIST_URL,req,new ParameterizedTypeReference<ApiResponse<Pagination<List<PayRecord>>>>(){}).thenApply(Pagination::getList)
// .fetchDataForAccount(account, ApiPathConstants.PAY_RECORDS_LIST_URL, req, new ParameterizedTypeReference<ApiResponse<Pagination<List<PayRecord>>>>() { // .thenComposeAsync(payRecords-> processPayRecords(payRecords, accountWithChange, account, nowDate, nowDateTime, depositResults, depositCounter, asyncTaskExecutor),asyncTaskExecutor)
// }) // .thenRunAsync(()->sendNotification(accountWithChange, ministerUser, accountUsernameToUserMap, depositResults),asyncTaskExecutor)
// .thenApply(Pagination::getList) // .exceptionally(ex->{
// .thenComposeAsync(payRecords -> processPayRecords(payRecords, accountWithChange, account, nowDate, nowDateTime, depositResults, depositCounter, asyncTaskExecutor), asyncTaskExecutor) // log.error("Error processing account changes for agent {}: {}", accountWithChange.getAgentName(), ex
// .thenRunAsync(() -> sendNotification(accountWithChange, ministerUser, accountUsernameToUserMap, depositResults), asyncTaskExecutor) // .getMessage());
// .exceptionally(ex -> { // return null;
// log.error("Error processing account changes for agent {}: {}", accountWithChange.getAgentName(), ex // });
// .getMessage()); //}
// return null;
// });
// }
private CompletableFuture<Void> processPayRecords(List<PayRecord> payRecords, private CompletableFuture<Void> processPayRecords(List<PayRecord> payRecords,
TeamAccountWithChange accountWithChange, TeamAccountWithChange accountWithChange,
@ -205,34 +231,34 @@ public class DepositService {
//根据用户名去重,保留时间最早的支付记录 //根据用户名去重,保留时间最早的支付记录
List<PayRecord> sortedPayRecords = payRecords.stream() List<PayRecord> sortedPayRecords = payRecords.stream()
.filter(record -> record.getCreatedAt().isAfter(nowDateTime.minusHours(1))) .filter(record -> record.getCreatedAt().isAfter(nowDateTime.minusHours(1)))
.collect(Collectors.collectingAndThen(Collectors.toMap(PayRecord::getName, record -> record, ( .collect(Collectors.collectingAndThen(Collectors.toMap(PayRecord::getName, record -> record, (
existingRecord, existingRecord,
newRecord) -> existingRecord newRecord) -> existingRecord
.getCreatedAt() .getCreatedAt()
.isBefore(newRecord .isBefore(newRecord
.getCreatedAt()) .getCreatedAt())
? existingRecord ? existingRecord
: newRecord, LinkedHashMap::new), map -> map : newRecord, LinkedHashMap::new), map -> map
.values() .values()
.stream() .stream()
.sorted(Comparator .sorted(Comparator
.comparing(PayRecord::getCreatedAt) .comparing(PayRecord::getCreatedAt)
.reversed()) .reversed())
.filter(payRecord -> !RedisUtils .filter(payRecord -> !RedisUtils
.hasKey(SUCCESSFULLY_PAYED_ACCOUNTNAME + payRecord .hasKey(SUCCESSFULLY_PAYED_ACCOUNTNAME + payRecord
.getBillNo())) .getBillNo()))
.collect(Collectors .collect(Collectors
.toList()))); .toList())));
List<CompletableFuture<Void>> fetchMemberFutures = sortedPayRecords.stream() List<CompletableFuture<Void>> fetchMemberFutures = sortedPayRecords.stream()
.map(payRecord -> fetchMemberDetails(account, payRecord.getName(), nowDate, asyncTaskExecutor) .map(payRecord -> fetchMemberDetails(account, payRecord.getName(), nowDate, asyncTaskExecutor)
.thenAcceptAsync(member -> processMemberDetails(member, payRecord, accountWithChange, depositResults, depositCounter), asyncTaskExecutor) .thenAcceptAsync(member -> processMemberDetails(member, payRecord, accountWithChange, depositResults, depositCounter), asyncTaskExecutor)
.exceptionally(ex -> { .exceptionally(ex -> {
log.error("Error fetching details for member {}: {}", payRecord.getName(), ex.getMessage()); log.error("Error fetching details for member {}: {}", payRecord.getName(), ex.getMessage());
return null; return null;
})) }))
.toList(); .toList();
return CompletableFuture.allOf(fetchMemberFutures.toArray(new CompletableFuture[0])); return CompletableFuture.allOf(fetchMemberFutures.toArray(new CompletableFuture[0]));
} }
@ -247,13 +273,13 @@ public class DepositService {
if (!RedisUtils.hasKey(SUCCESSFULLY_PAYED_ACCOUNTNAME + payRecord.getBillNo())) { if (!RedisUtils.hasKey(SUCCESSFULLY_PAYED_ACCOUNTNAME + payRecord.getBillNo())) {
//如果订单记录有存款成功但是会员的首存时间还为空,数据未同步,也是首存 //如果订单记录有存款成功但是会员的首存时间还为空,数据未同步,也是首存
if ((member.getFirstPayAt() == null || payRecord.getCreatedAt() if ((member.getFirstPayAt() == null || payRecord.getCreatedAt()
.equals(member.getFirstPayAt())) && depositCounter.getAndIncrement() < accountWithChange .equals(member.getFirstPayAt())) && depositCounter.getAndIncrement() < accountWithChange
.getNewDepositNum()) { .getNewDepositNum()) {
//把存款成功的用户保存起来,设置一个小时的缓存时间 防止重复用户 //把存款成功的用户保存起来,设置一个小时的缓存时间 防止重复用户
RedisUtils.set(SUCCESSFULLY_PAYED_ACCOUNTNAME + payRecord.getBillNo(), member.getName(), Duration RedisUtils.set(SUCCESSFULLY_PAYED_ACCOUNTNAME + payRecord.getBillNo(), member.getName(), Duration
.ofHours(1)); .ofHours(1));
depositResults.append(telegramMessageService.buildDepositResultsMessage(member.getName(), payRecord depositResults.append(telegramMessageService.buildDepositResultsMessage(member.getName(), payRecord
.getScoreAmount())); .getScoreAmount()));
} }
} }
} }
@ -264,50 +290,49 @@ public class DepositService {
Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap, Map<String, UserWithRolesAndAccountsResp> accountUsernameToUserMap,
StringBuilder depositResults) { StringBuilder depositResults) {
String notification = telegramMessageService.buildDepositMessage(accountWithChange String notification = telegramMessageService.buildDepositMessage(accountWithChange
.getAgentName(), accountWithChange.getNewDepositNum(), depositResults.toString(), accountWithChange .getAgentName(), accountWithChange.getNewDepositNum(), depositResults.toString(), accountWithChange
.getFirstDepositNum()); .getFirstDepositNum());
var currUser = accountUsernameToUserMap.get(accountWithChange.getAgentName()); var currUser = accountUsernameToUserMap.get(accountWithChange.getAgentName());
if (currUser != null && DisEnableStatusEnum.ENABLE.equals(currUser.getNeedNotify())) { if (currUser != null && DisEnableStatusEnum.ENABLE.equals(currUser.getNeedNotify())) {
String botToken = StrUtil.isEmpty(currUser.getBotToken()) String botToken = StrUtil.isEmpty(currUser.getBotToken())
? ministerUser.getBotToken() ? ministerUser.getBotToken()
: currUser.getBotToken(); : currUser.getBotToken();
telegramMessageService.sendMessage(botToken, currUser.getRegAndDepIds(), notification); telegramMessageService.sendMessage(botToken, currUser.getRegAndDepIds(), notification);
} }
telegramMessageService.sendMessage(BOT_TOKEN, TELEGRAM_CHAT_ID, notification); telegramMessageService.sendMessage(BOT_TOKEN, TELEGRAM_CHAT_ID, notification);
} }
private CompletableFuture<Member> fetchMemberDetails(AccountResp account, private CompletableFuture<Member> fetchMemberDetails(AccountResp account,
String name, String name,
LocalDate nowDate, LocalDate nowDate,
Executor asyncTaskExecutor) { Executor asyncTaskExecutor) {
TeamMemberListReq memberListReq = TeamMemberListReq.builder() TeamMemberListReq memberListReq = TeamMemberListReq.builder()
.name(name) .name(name)
.startDate(nowDate) .startDate(nowDate)
.endDate(nowDate) .endDate(nowDate)
.status(1) .status(1)
.build(); .build();
CompletableFuture<MemberPagination<List<Member>>> memberFuture = completableFutureWebClientService CompletableFuture<MemberPagination<List<Member>>> memberFuture = completableFutureWebClientService
.fetchDataForAccount(account, ApiPathConstants.MEMBER_TEAM_LIST_URL, memberListReq, new ParameterizedTypeReference<>() { .fetchDataForAccount(account, ApiPathConstants.MEMBER_TEAM_LIST_URL, memberListReq, new ParameterizedTypeReference<>() {
}); });
return memberFuture.thenApplyAsync(MemberPagination::getList, asyncTaskExecutor) return memberFuture.thenApplyAsync(MemberPagination::getList, asyncTaskExecutor)
.thenApplyAsync(list -> list.stream() .thenApplyAsync(list -> list.stream()
.findFirst() .findFirst()
.orElseThrow(() -> new BusinessException("没有找到匹配的成员信息")), asyncTaskExecutor) .orElseThrow(() -> new BusinessException("没有找到匹配的成员信息")), asyncTaskExecutor)
.thenComposeAsync(member -> fetchDetailedMemberInfo(account, member.getId(), nowDate), asyncTaskExecutor); .thenComposeAsync(member -> fetchDetailedMemberInfo(account, member.getId(), nowDate), asyncTaskExecutor);
} }
private CompletableFuture<Member> fetchDetailedMemberInfo(AccountResp account, Long memberId, LocalDate nowDate) { private CompletableFuture<Member> fetchDetailedMemberInfo(AccountResp account, Long memberId, LocalDate nowDate) {
MemberDetailsReq detailsReq = MemberDetailsReq.builder() MemberDetailsReq detailsReq = MemberDetailsReq.builder()
.id(memberId) .id(memberId)
.startDate(nowDate) .startDate(nowDate)
.endDate(nowDate) .endDate(nowDate)
.build(); .build();
return completableFutureWebClientService return completableFutureWebClientService
.fetchDataForAccount(account, ApiPathConstants.MEMBER_DETAIL_URL, detailsReq, new ParameterizedTypeReference<>() { .fetchDataForAccount(account, ApiPathConstants.MEMBER_DETAIL_URL, detailsReq, new ParameterizedTypeReference<>() {
}); });
} }
} }

View File

@ -61,7 +61,7 @@ public class TelegramMessageService {
public void sendMessage(String botToken, String targetIds, String message) { public void sendMessage(String botToken, String targetIds, String message) {
convertStringToList(targetIds).parallelStream() convertStringToList(targetIds).parallelStream()
.forEach(targetId -> this.sendMessage(botToken, targetId, message)); .forEach(targetId -> this.sendMessage(botToken, targetId, message));
} }
public static List<Long> convertStringToList(String str) { public static List<Long> convertStringToList(String str) {
@ -73,7 +73,7 @@ public class TelegramMessageService {
private static String escapeMarkdown(String text) { private static String escapeMarkdown(String text) {
List<Character> escapeChars = Arrays List<Character> escapeChars = Arrays
.asList('_', '[', ']', '(', ')', '~', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'); .asList('_', '[', ']', '(', ')', '~', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!');
for (Character charItem : escapeChars) { for (Character charItem : escapeChars) {
text = text.replace(charItem.toString(), "\\" + charItem); text = text.replace(charItem.toString(), "\\" + charItem);
} }
@ -92,19 +92,19 @@ public class TelegramMessageService {
String memberNames = accountMembers.stream().map(TeamMember::getName).collect(Collectors.joining(", ")); String memberNames = accountMembers.stream().map(TeamMember::getName).collect(Collectors.joining(", "));
if (currUser != null) { if (currUser != null) {
return String.format("👏 [%s] %s 注册: %d 会员: `%s` 总数:*%d*", currUser.getNickname(), teamAccount return String.format("👏 [%s] %s 注册: %d 会员: `%s` 总数:*%d*", currUser.getNickname(), teamAccount
.getAgentName(), accountMembers.size(), memberNames, teamAccount.getSubMemberNum()); .getAgentName(), accountMembers.size(), memberNames, teamAccount.getSubMemberNum());
} }
return String.format("👏 %s 注册: %d 会员: `%s` 总数:*%d*", teamAccount.getAgentName(), accountMembers return String.format("👏 %s 注册: %d 会员: `%s` 总数:*%d*", teamAccount.getAgentName(), accountMembers
.size(), memberNames, teamAccount.getSubMemberNum()); .size(), memberNames, teamAccount.getSubMemberNum());
} }
public String buildRegistrationMessage(List<TeamMember> accountMembers, TeamAccountWithChange teamAccount) { public String buildRegistrationMessage(List<TeamMember> accountMembers, TeamAccountWithChange teamAccount) {
String memberNames = accountMembers.stream() String memberNames = accountMembers.stream()
.map(member -> "`" + member.getName() + "`") .map(member -> "`" + member.getName() + "`")
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));
return String.format("👏 %s 注册: %d 会员: %s 总数:*%d*", teamAccount.getAgentName(), accountMembers return String.format("👏 %s 注册: %d 会员: %s 总数:*%d*", teamAccount.getAgentName(), accountMembers
.size(), memberNames, teamAccount.getSubMemberNum()); .size(), memberNames, teamAccount.getSubMemberNum());
} }
public String buildDepositMessage(String agentName, int newDepositNum, String depositResults, int firstDepositNum) { public String buildDepositMessage(String agentName, int newDepositNum, String depositResults, int firstDepositNum) {
@ -124,7 +124,7 @@ public class TelegramMessageService {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
statics.forEach(stat -> { statics.forEach(stat -> {
String formattedStat = String.format("%s\n注册: %s\n新增: %d\n日活: %d\n\n", stat.getAgentName(), stat String formattedStat = String.format("%s\n注册: %s\n新增: %d\n日活: %d\n\n", stat.getAgentName(), stat
.getIsNew(), stat.getFirstCount(), stat.getCountBets()); .getIsNew(), stat.getFirstCount(), stat.getCountBets());
message.append(formattedStat); message.append(formattedStat);
}); });
return message.toString(); return message.toString();
@ -134,7 +134,7 @@ public class TelegramMessageService {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
userFinancesList.forEach(financeDO -> { userFinancesList.forEach(financeDO -> {
String formattedFinance = String.format("%s: *%s*\n", financeDO.getAgentName(), financeDO.getNetProfit() String formattedFinance = String.format("%s: *%s*\n", financeDO.getAgentName(), financeDO.getNetProfit()
.toPlainString()); .toPlainString());
message.append(formattedFinance); message.append(formattedFinance);
}); });
return message.toString(); return message.toString();

View File

@ -30,28 +30,27 @@ import java.util.stream.Collectors;
public class CommonUtils { public class CommonUtils {
public static List<TeamAccountWithChange> findChangedTeamAccount(Team prevTeam, Team currTeam) { public static List<TeamAccountWithChange> findChangedTeamAccount(Team prevTeam, Team currTeam) {
Map<Long, TeamAccount> team2AccountMap = currTeam.getList() Map<Long, TeamAccount> team2AccountMap = currTeam.getList()
.stream() .stream()
.collect(Collectors.toMap(TeamAccount::getId, account -> account)); .collect(Collectors.toMap(TeamAccount::getId, account -> account));
return prevTeam.getList() return prevTeam.getList()
.stream() .stream()
.filter(account1 -> team2AccountMap.containsKey(account1.getId())) .filter(account1 -> team2AccountMap.containsKey(account1.getId()))
.map(account1 -> { .map(account1 -> {
TeamAccount account2 = team2AccountMap.get(account1.getId()); TeamAccount account2 = team2AccountMap.get(account1.getId());
TeamAccountWithChange changedAccount = new TeamAccountWithChange(); TeamAccountWithChange changedAccount = new TeamAccountWithChange();
BeanUtil.copyProperties(account2, changedAccount); BeanUtil.copyProperties(account2, changedAccount);
if (account1.getFirstDepositNum() != account2.getFirstDepositNum()) { if (account1.getFirstDepositNum() != account2.getFirstDepositNum()) {
changedAccount.setNewDepositNum(account2.getFirstDepositNum() - account1.getFirstDepositNum()); changedAccount.setNewDepositNum(account2.getFirstDepositNum() - account1.getFirstDepositNum());
} }
if (account1.getSubMemberNum() != account2.getSubMemberNum()) { if (account1.getSubMemberNum() != account2.getSubMemberNum()) {
changedAccount.setNewRegisterNum(account2.getSubMemberNum() - account1.getSubMemberNum()); changedAccount.setNewRegisterNum(account2.getSubMemberNum() - account1.getSubMemberNum());
} }
return changedAccount; return changedAccount;
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public static <T> List<T> getLastNElements(List<T> list, int n) { public static <T> List<T> getLastNElements(List<T> list, int n) {
if (list == null || list.isEmpty() || n <= 0) { if (list == null || list.isEmpty() || n <= 0) {
return Collections.emptyList(); return Collections.emptyList();