已经一个多月没有写博客了,最近一直在改版某产品的钱包功能。
这两天拿到一个新的需求,要提供一个银行卡列表给第三方使用。因为历史遗留因素,该产品的银行卡数据都在一张表里面,而且二类户及主绑卡的属性和卡号完全一致,只有type不同。用户自定义支付顺序是直接按照用户ID、卡类型、卡号进行修改的,且用户用同一张一类卡去签约多个银行的快捷支付就会产生多条卡号重复的记录,由一类卡开通的二类卡也可以签约多家银行,而提供给第三方的接口要求去重。即每张银行卡只在列表中出现一次,但是去重以后,获取对应的银行卡的其他信息就比较棘手。期初采用了第一种方案,先取出银行卡的卡号和类型然后遍历去重,如果没有匹配的就用null填充避免出现数组下标越界异常。因为代码较多且敏感,所以只截取数据处理部分的代码……
方案一:
Service层
/** --------------------------------- 以上忽略 ---------------------------------*/
最终返回的银行卡列表:
//第三方银行卡列表
ArrayList<UserAccountBankcard> cardList = getUserAllBankcards(userId);
ArrayList<BankCardVo> vos = new ArrayList<>();
for (UserAccountBankcard uab : cardList) {
//如果用户开通了A银行电子账户
if (StrUtil.isNotBlank(uab.getAccount())) {
//如果是A银行电子二类户签约的B银行快捷支付则不在列表中展示
if ("1".equals(uab.getType()) && uab.getBankCard().equals(uab.getAccount())) {
cardList.remove(uab);
}
}
}
//取所有快捷卡
for (UserAccountBankcard uab : cardList) {
vos.add(vo);
}
/** --------------------------------- 以下忽略 ---------------------------------*/
/** --------------------------------- 以上忽略 ---------------------------------*/
给对应的银行卡属性赋值:
@NotNull
//第三方专用银行卡列表
public ArrayList<UserAccountBankcard> getUserAllBankcards(String userId) {
List<UserAccountBankcard> allList = userAccountMapper.queryAllMyBankCardByUserId(userId, "");
ArrayList<Object> list = new ArrayList<>();
for (int i = 0; i < allList.size(); i++) {
UserAccountBankcard accountBankcard = allList.get(i);
UserAccountBankcard bankCard = new UserAccountBankcard();
bankCard.setBankCard(accountBankcard.getBankCard());
bankCard.setType(accountBankcard.getType());
list.add(i,bankCard);
}
//银行卡去重(同类型同卡号只取一个)
list = listCustomDeduplication(list);
//查询用户A银行电子账户
String accountNo = userAccountMapper.queryMyAccountNo(userId);
//组装银行卡列表
ArrayList<UserAccountBankcard> cardList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
UserAccountBankcard accountBankcard = allList.get(i);
if(ObjectUtil.isNotNull(list.get(i))) {
UserAccountBankcard bankCard = JSON.parseObject(String.valueOf(list.get(i)), UserAccountBankcard.class);
bankCard.setPriorityExternal(accountBankcard.getPriorityExternal());
bankCard.setAccount(accountNo);
bankCard.setPointSystem(accountBankcard.getPointSystem());
bankCard.setCardType(accountBankcard.getCardType()); // 卡属性
bankCard.setBankName(accountBankcard.getBankName()); // 银行名称
bankCard.setLogoUrl(accountBankcard.getLogoUrl()); // logo
bankCard.setBackColor(accountBankcard.getBackColor());// 银行卡背景色
cardList.add(bankCard);
}
}
return cardList;
}
/** --------------------------------- 以下忽略 ---------------------------------*/
/** --------------------------------- 以上忽略 ---------------------------------*/
银行卡列表去重:
/**
* list自定义去重
* @param list
*/
public static ArrayList listCustomDeduplication(ArrayList<Object> list) {
// 新集合
ArrayList<Object> newList = new ArrayList<>(list.size());
for (int i = 0; i < list.size(); i++) {
if (!newList.contains(list.get(i))) { // 如果新集合中不存在则插入
newList.add(i,list.get(i));
}else {
//填充null
newList.add(i,null);
}
}
return newList;
}
苦于方案一因为通过下标获取排序前的银行卡列表里面的对象可能出现偏差,所以改良出了方案二。直接通过stream流按照集合中的对象属性进行去重,然后再根据自定义支付顺序进行排序。
方案二:
Service层
/** --------------------------------- 以上忽略 ---------------------------------*/
最终返回的银行卡列表:
//第三方银行卡列表
ArrayList<UserAccountBankcard> cardList = getUserAllBankcards(userId);
ArrayList<BankCardVo> vos = new ArrayList<>();
//如果用户开通了A银行电子账户
ArrayList<UserAccountBankcard> list = new ArrayList<>();
if(StrUtil.isNotBlank(userAccountMapper.queryMyAccountNo(userId))){
//如果是A银行电子二类户签约的B银行快捷支付则不在列表中展示
List<UserAccountBankcard> collect = cardList.stream().filter(u ->
!("1".equals(u.getType()) && u.getBankCard().equals(u.getAccount())))
.collect(Collectors.toList());
list.addAll(collect);
}
for (UserAccountBankcard uab : cardList) {
vos.add(vo);
}
/** --------------------------------- 以下忽略 ---------------------------------*/
/** --------------------------------- 以上忽略 ---------------------------------*/
银行卡列表去重和排序:
@NotNull
//第三方专用银行卡列表
public ArrayList<UserAccountBankcard> getUserAllBankcards(String userId) {
List<UserAccountBankcard> allList = userAccountMapper.queryAllMyBankCardByUserId(userId, "");
//银行卡去重(同类型同卡号只取一个)
List<UserAccountBankcard> newList = allList.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
new TreeSet<>(Comparator.comparing(o ->o.getBankCard() + "#" + o.getType()))),
ArrayList::new));
//查询用户A银行电子账户
String accountNo = userAccountMapper.queryMyAccountNo(userId);
//组装银行卡列表
ArrayList<UserAccountBankcard> cardList = new ArrayList<>();
//用户是否设置了第三方排序
String flag = userAccountMapper.queryUserSetPriorityExternal(userId);
for (int i = 0; i < newList.size(); i++) {
if (ObjectUtil.isNotNull(newList.get(i))) {
UserAccountBankcard accountBankcard = newList.get(i);
if (StrUtil.isBlank(accountBankcard.getPriorityExternal())){
userAccountMapper.updatePriorityExternalToUser(accountBankcard.getUserId());
}else{
accountBankcard.setAccount(accountNo);
cardList.add(accountBankcard);
}
}
}
if ("YES".equals(flag)){
//重新按照第三方优先级排序
cardList.sort(Comparator.comparing(UserAccountBankcard::getPriorityExternal));
}
return cardList;
}