mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-05-17 16:28:41 +08:00
update
This commit is contained in:
@@ -21,6 +21,7 @@ import com.jsowell.common.constant.Constants;
|
|||||||
import com.jsowell.common.constant.RabbitConstants;
|
import com.jsowell.common.constant.RabbitConstants;
|
||||||
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
|
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
|
||||||
import com.jsowell.common.core.redis.RedisCache;
|
import com.jsowell.common.core.redis.RedisCache;
|
||||||
|
import com.jsowell.common.enums.MemberWalletEnum;
|
||||||
import com.jsowell.common.enums.adapay.AdapayStatusEnum;
|
import com.jsowell.common.enums.adapay.AdapayStatusEnum;
|
||||||
import com.jsowell.common.enums.adapay.MerchantDelayModeEnum;
|
import com.jsowell.common.enums.adapay.MerchantDelayModeEnum;
|
||||||
import com.jsowell.common.enums.ykc.*;
|
import com.jsowell.common.enums.ykc.*;
|
||||||
@@ -65,6 +66,10 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
public class TempService {
|
public class TempService {
|
||||||
|
|
||||||
|
private static final String JSOWELL_MEMBER_MERCHANT_ID = "1";
|
||||||
|
|
||||||
|
private static final String NANTONG_CHENMING_WALLET_MERCHANT_ID = "575";
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -1557,22 +1562,105 @@ public class TempService {
|
|||||||
/**
|
/**
|
||||||
* 从文件中导入会员余额
|
* 从文件中导入会员余额
|
||||||
*/
|
*/
|
||||||
public void batchImportMemberBalance(List<ImportMemberBalanceDTO> list) {
|
public BatchImportMemberBalanceResultDTO batchImportMemberBalance(List<ImportMemberBalanceDTO> list) {
|
||||||
|
BatchImportMemberBalanceResultDTO result = new BatchImportMemberBalanceResultDTO();
|
||||||
if (CollectionUtils.isEmpty(list)) {
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
return;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.setTotalCount(list.size());
|
||||||
|
List<ImportMemberBalanceItemResultDTO> itemResults = list.parallelStream()
|
||||||
|
.map(this::importMemberBalanceSafely)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
long successCount = itemResults.stream().filter(ImportMemberBalanceItemResultDTO::isSuccess).count();
|
||||||
|
List<ImportMemberBalanceItemResultDTO> failedList = itemResults.stream()
|
||||||
|
.filter(item -> !item.isSuccess())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
result.setSuccessCount((int) successCount);
|
||||||
|
result.setFailCount(failedList.size());
|
||||||
|
result.setFailedList(failedList);
|
||||||
|
|
||||||
|
logger.info("批量导入会员余额完成, totalCount:{}, successCount:{}, failCount:{}",
|
||||||
|
result.getTotalCount(), result.getSuccessCount(), result.getFailCount());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImportMemberBalanceItemResultDTO importMemberBalanceSafely(ImportMemberBalanceDTO memberBalanceDTO) {
|
||||||
|
String phone = memberBalanceDTO != null ? memberBalanceDTO.getPhone() : null;
|
||||||
|
try {
|
||||||
|
importMemberBalance(memberBalanceDTO);
|
||||||
|
return ImportMemberBalanceItemResultDTO.success(phone);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("导入会员余额失败, phone:{}, param:{}", phone, JSON.toJSONString(memberBalanceDTO), e);
|
||||||
|
return ImportMemberBalanceItemResultDTO.fail(phone, e.getMessage());
|
||||||
}
|
}
|
||||||
list.parallelStream().forEach(this::importMemberBalance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importMemberBalance(ImportMemberBalanceDTO memberBalanceDTO) {
|
private void importMemberBalance(ImportMemberBalanceDTO memberBalanceDTO) {
|
||||||
// 1. 根据手机号查询万车充会员信息
|
if (memberBalanceDTO == null) {
|
||||||
MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMobileNumber(memberBalanceDTO.getPhone(), "1");
|
throw new BusinessException("", "导入会员余额失败,参数不能为空");
|
||||||
// 2. 如果没有万车充会员信息,则自动注册万车充会员,并创建“南通晨鸣中锦置业有限责任公司”运营商钱包
|
}
|
||||||
if (memberBasicInfo == null) {
|
String phone = memberBalanceDTO.getPhone();
|
||||||
|
BigDecimal balance = memberBalanceDTO.getBalance();
|
||||||
|
if (StringUtils.isBlank(phone)) {
|
||||||
|
throw new BusinessException("", "导入会员余额失败,手机号不能为空");
|
||||||
|
}
|
||||||
|
if (balance == null || balance.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
throw new BusinessException("", "导入会员余额失败,余额必须大于0");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 根据balance添加余额
|
// 1. 根据手机号查询万车充会员信息;不存在则静默注册一个属于万车充体系的会员。
|
||||||
}
|
MemberBasicInfo memberBasicInfo = findOrCreateJsowellMember(phone);
|
||||||
}
|
|
||||||
|
|
||||||
|
// 2. 给“南通晨鸣中锦置业有限责任公司”运营商钱包增加本金余额。
|
||||||
|
increaseMemberWalletBalance(memberBasicInfo.getMemberId(), balance);
|
||||||
|
|
||||||
|
logger.info("导入会员余额成功, phone:{}, memberId:{}, merchantId:{}, balance:{}",
|
||||||
|
phone, memberBasicInfo.getMemberId(), NANTONG_CHENMING_WALLET_MERCHANT_ID, balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据手机号查询万车充会员;若不存在,则自动注册后重新查询。
|
||||||
|
*/
|
||||||
|
private MemberBasicInfo findOrCreateJsowellMember(String phone) {
|
||||||
|
MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMobileNumber(phone, JSOWELL_MEMBER_MERCHANT_ID);
|
||||||
|
if (memberBasicInfo != null) {
|
||||||
|
return memberBasicInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("导入会员余额时未查询到万车充会员,开始自动注册, phone:{}, merchantId:{}",
|
||||||
|
phone, JSOWELL_MEMBER_MERCHANT_ID);
|
||||||
|
MemberRegisterAndLoginDTO loginDTO = MemberRegisterAndLoginDTO.builder()
|
||||||
|
.mobileNumber(phone)
|
||||||
|
.firstLevelMerchantId(JSOWELL_MEMBER_MERCHANT_ID)
|
||||||
|
.build();
|
||||||
|
memberService.memberRegisterAndLoginV2(loginDTO);
|
||||||
|
|
||||||
|
memberBasicInfo = memberBasicInfoService.selectInfoByMobileNumber(phone, JSOWELL_MEMBER_MERCHANT_ID);
|
||||||
|
if (memberBasicInfo == null) {
|
||||||
|
logger.error("导入会员余额时自动注册后仍未查询到会员, phone:{}, merchantId:{}",
|
||||||
|
phone, JSOWELL_MEMBER_MERCHANT_ID);
|
||||||
|
throw new BusinessException(ReturnCodeEnum.CODE_MEMBER_REGISTER_AND_LOGIN_ERROR);
|
||||||
|
}
|
||||||
|
return memberBasicInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给指定会员在目标运营商钱包中增加本金余额。
|
||||||
|
*
|
||||||
|
* <p>如果该运营商钱包不存在,现有余额逻辑会自动创建钱包并记录流水。</p>
|
||||||
|
*/
|
||||||
|
private void increaseMemberWalletBalance(String memberId, BigDecimal balance) {
|
||||||
|
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
|
||||||
|
.memberId(memberId)
|
||||||
|
.type(MemberWalletEnum.TYPE_IN.getValue())
|
||||||
|
.subType(MemberWalletEnum.SUBTYPE_TOP_UP.getValue())
|
||||||
|
.updatePrincipalBalance(balance)
|
||||||
|
.targetMerchantId(NANTONG_CHENMING_WALLET_MERCHANT_ID)
|
||||||
|
.build();
|
||||||
|
memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package com.jsowell.service;
|
||||||
|
|
||||||
|
import com.jsowell.pile.dto.BatchImportMemberBalanceResultDTO;
|
||||||
|
import com.jsowell.common.enums.MemberWalletEnum;
|
||||||
|
import com.jsowell.pile.domain.MemberBasicInfo;
|
||||||
|
import com.jsowell.pile.dto.ImportMemberBalanceDTO;
|
||||||
|
import com.jsowell.pile.dto.ImportMemberBalanceItemResultDTO;
|
||||||
|
import com.jsowell.pile.dto.MemberRegisterAndLoginDTO;
|
||||||
|
import com.jsowell.pile.service.MemberBasicInfoService;
|
||||||
|
import com.jsowell.pile.vo.web.UpdateMemberBalanceDTO;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
class TempServiceImportMemberBalanceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void importMemberBalance_shouldIncreaseWalletBalance_whenMemberAlreadyExists() throws Exception {
|
||||||
|
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||||
|
MemberService memberService = mock(MemberService.class);
|
||||||
|
|
||||||
|
MemberBasicInfo memberBasicInfo = MemberBasicInfo.builder()
|
||||||
|
.memberId("M1001")
|
||||||
|
.mobileNumber("13800000001")
|
||||||
|
.merchantId(1L)
|
||||||
|
.build();
|
||||||
|
when(memberBasicInfoService.selectInfoByMobileNumber("13800000001", "1")).thenReturn(memberBasicInfo);
|
||||||
|
|
||||||
|
TempService tempService = newTempService(memberBasicInfoService, memberService);
|
||||||
|
ImportMemberBalanceDTO dto = new ImportMemberBalanceDTO();
|
||||||
|
dto.setPhone("13800000001");
|
||||||
|
dto.setBalance(new BigDecimal("88.50"));
|
||||||
|
|
||||||
|
invokeImportMemberBalance(tempService, dto);
|
||||||
|
|
||||||
|
verify(memberService, never()).memberRegisterAndLoginV2(any(MemberRegisterAndLoginDTO.class));
|
||||||
|
|
||||||
|
ArgumentCaptor<UpdateMemberBalanceDTO> captor = ArgumentCaptor.forClass(UpdateMemberBalanceDTO.class);
|
||||||
|
verify(memberBasicInfoService).updateMemberBalance(captor.capture());
|
||||||
|
UpdateMemberBalanceDTO updateDto = captor.getValue();
|
||||||
|
assertEquals("M1001", updateDto.getMemberId());
|
||||||
|
assertEquals(MemberWalletEnum.TYPE_IN.getValue(), updateDto.getType());
|
||||||
|
assertEquals(MemberWalletEnum.SUBTYPE_TOP_UP.getValue(), updateDto.getSubType());
|
||||||
|
assertEquals(new BigDecimal("88.50"), updateDto.getUpdatePrincipalBalance());
|
||||||
|
assertEquals("575", updateDto.getTargetMerchantId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void importMemberBalance_shouldRegisterMemberBeforeIncreaseBalance_whenMemberDoesNotExist() throws Exception {
|
||||||
|
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||||
|
MemberService memberService = mock(MemberService.class);
|
||||||
|
|
||||||
|
MemberBasicInfo memberBasicInfo = MemberBasicInfo.builder()
|
||||||
|
.memberId("M2002")
|
||||||
|
.mobileNumber("13800000002")
|
||||||
|
.merchantId(1L)
|
||||||
|
.build();
|
||||||
|
when(memberBasicInfoService.selectInfoByMobileNumber("13800000002", "1")).thenReturn(null, memberBasicInfo);
|
||||||
|
|
||||||
|
TempService tempService = newTempService(memberBasicInfoService, memberService);
|
||||||
|
ImportMemberBalanceDTO dto = new ImportMemberBalanceDTO();
|
||||||
|
dto.setPhone("13800000002");
|
||||||
|
dto.setBalance(new BigDecimal("100"));
|
||||||
|
|
||||||
|
invokeImportMemberBalance(tempService, dto);
|
||||||
|
|
||||||
|
ArgumentCaptor<MemberRegisterAndLoginDTO> loginCaptor = ArgumentCaptor.forClass(MemberRegisterAndLoginDTO.class);
|
||||||
|
verify(memberService).memberRegisterAndLoginV2(loginCaptor.capture());
|
||||||
|
MemberRegisterAndLoginDTO loginDTO = loginCaptor.getValue();
|
||||||
|
assertEquals("13800000002", loginDTO.getMobileNumber());
|
||||||
|
assertEquals("1", loginDTO.getFirstLevelMerchantId());
|
||||||
|
|
||||||
|
ArgumentCaptor<UpdateMemberBalanceDTO> balanceCaptor = ArgumentCaptor.forClass(UpdateMemberBalanceDTO.class);
|
||||||
|
verify(memberBasicInfoService).updateMemberBalance(balanceCaptor.capture());
|
||||||
|
assertEquals("M2002", balanceCaptor.getValue().getMemberId());
|
||||||
|
assertEquals("575", balanceCaptor.getValue().getTargetMerchantId());
|
||||||
|
assertEquals(new BigDecimal("100"), balanceCaptor.getValue().getUpdatePrincipalBalance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void batchImportMemberBalance_shouldReturnSummary_whenMixedRecords() {
|
||||||
|
MemberBasicInfoService memberBasicInfoService = mock(MemberBasicInfoService.class);
|
||||||
|
MemberService memberService = mock(MemberService.class);
|
||||||
|
|
||||||
|
MemberBasicInfo memberBasicInfo = MemberBasicInfo.builder()
|
||||||
|
.memberId("M3003")
|
||||||
|
.mobileNumber("13800000003")
|
||||||
|
.merchantId(1L)
|
||||||
|
.build();
|
||||||
|
when(memberBasicInfoService.selectInfoByMobileNumber("13800000003", "1")).thenReturn(memberBasicInfo);
|
||||||
|
|
||||||
|
TempService tempService = newTempService(memberBasicInfoService, memberService);
|
||||||
|
|
||||||
|
ImportMemberBalanceDTO successDto = new ImportMemberBalanceDTO();
|
||||||
|
successDto.setPhone("13800000003");
|
||||||
|
successDto.setBalance(new BigDecimal("50"));
|
||||||
|
|
||||||
|
ImportMemberBalanceDTO failDto = new ImportMemberBalanceDTO();
|
||||||
|
failDto.setPhone("");
|
||||||
|
failDto.setBalance(new BigDecimal("20"));
|
||||||
|
|
||||||
|
BatchImportMemberBalanceResultDTO result = tempService.batchImportMemberBalance(Arrays.asList(successDto, failDto));
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(2, result.getTotalCount());
|
||||||
|
assertEquals(1, result.getSuccessCount());
|
||||||
|
assertEquals(1, result.getFailCount());
|
||||||
|
assertEquals(1, result.getFailedList().size());
|
||||||
|
ImportMemberBalanceItemResultDTO failedItem = result.getFailedList().get(0);
|
||||||
|
assertEquals("", failedItem.getPhone());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TempService newTempService(MemberBasicInfoService memberBasicInfoService, MemberService memberService) {
|
||||||
|
TempService tempService = new TempService();
|
||||||
|
setField(tempService, "memberBasicInfoService", memberBasicInfoService);
|
||||||
|
setField(tempService, "memberService", memberService);
|
||||||
|
return tempService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void invokeImportMemberBalance(TempService tempService, ImportMemberBalanceDTO dto) throws Exception {
|
||||||
|
Method method = TempService.class.getDeclaredMethod("importMemberBalance", ImportMemberBalanceDTO.class);
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(tempService, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setField(Object target, String fieldName, Object value) {
|
||||||
|
try {
|
||||||
|
Field field = target.getClass().getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(target, value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.jsowell.pile.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class BatchImportMemberBalanceResultDTO {
|
||||||
|
private int totalCount;
|
||||||
|
private int successCount;
|
||||||
|
private int failCount;
|
||||||
|
private List<ImportMemberBalanceItemResultDTO> failedList = new ArrayList<>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.jsowell.pile.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ImportMemberBalanceItemResultDTO {
|
||||||
|
private boolean success;
|
||||||
|
private String phone;
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
public static ImportMemberBalanceItemResultDTO success(String phone) {
|
||||||
|
ImportMemberBalanceItemResultDTO result = new ImportMemberBalanceItemResultDTO();
|
||||||
|
result.setSuccess(true);
|
||||||
|
result.setPhone(phone);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImportMemberBalanceItemResultDTO fail(String phone, String errorMessage) {
|
||||||
|
ImportMemberBalanceItemResultDTO result = new ImportMemberBalanceItemResultDTO();
|
||||||
|
result.setSuccess(false);
|
||||||
|
result.setPhone(phone);
|
||||||
|
result.setErrorMessage(errorMessage);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user