记得上下班打卡 | git大法好,push需谨慎

Commit 42da24b6 authored by wangyifan's avatar wangyifan

Merge branch 'dev-caomeihuizhang' into container-test

parents 9d2a232a ce4fe5ed
......@@ -22,6 +22,10 @@ public class AdamRedisConst {
public static final String INFO_ADDRESSES = PREFIX.concat("info:addresses:");
public static final String INFO_CAOMEI_BADGE_PUBLISHED = PREFIX.concat("info:caomei:badge:published");
public static final String INFO_CAOMEI_BADGE_USER = PREFIX.concat("info:caomei:badge:user:");
/**
* 身份证号已支付演出ID列表(短缓存,缓解 kylin_order_ticket_entities 无身份证索引时的热点查询压力)
*/
public static final String INFO_CAOMEI_PAID_PERFORMANCE_IDS_BY_IDCARD = PREFIX.concat("info:caomei:paid_performance_ids:idcard:");
/**
* {adam:info:biz:{uid},List<com.liquidnet.service.adam.dto.vo.AdamUserBizAcctVo>}
*/
......
......@@ -20,4 +20,9 @@ public interface IAdamCaomeiPassportUserService {
* 护照首页:个人信息、实名状态、已认领墙、按类型分组的全部上架徽章
*/
ResponseDto<AdamCaomeiPassportHomeVo> getPassportHome();
/**
* 校验当前登录用户是否已绑定护照
*/
ResponseDto<Boolean> checkPassportBound();
}
......@@ -3,6 +3,8 @@ package com.liquidnet.client.admin.zhengzai.adam.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamCaomeiPassportAdminService;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.AdamCaomeiPassportListDto;
import com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto;
import com.liquidnet.service.adam.dto.param.AdamCaomeiPassportSearchParam;
......@@ -44,6 +46,8 @@ public class AdamCaomeiPassportAdminServiceImpl implements IAdamCaomeiPassportAd
private AdamRealNameMapper adamRealNameMapper;
@Autowired
private AdamCaomeiBadgeMapper adamCaomeiBadgeMapper;
@Autowired
private RedisDataSourceUtil redisDataSourceUtil;
@Override
public PageInfo<AdamCaomeiPassportListVo> listPassports(AdamCaomeiPassportSearchParam param) {
......@@ -157,6 +161,8 @@ public class AdamCaomeiPassportAdminServiceImpl implements IAdamCaomeiPassportAd
if (StringUtils.isNotBlank(uid)) {
// 解绑后,清理该用户由“绑定护照”自动发放的护照纪念徽章
adamCaomeiBadgeMapper.deletePassportTypeBadgesByUid(uid);
// 清理用户草莓徽章缓存,避免前端短时间读到解绑前数据
redisDataSourceUtil.getRedisAdamUtil().del(AdamRedisConst.INFO_CAOMEI_BADGE_USER.concat(uid));
}
return true;
}
......
......@@ -41,4 +41,11 @@ public class AdamCaomeiPassportUserController {
public ResponseDto<AdamCaomeiPassportHomeVo> home() {
return adamCaomeiPassportUserService.getPassportHome();
}
@ApiOperationSupport(order = 3)
@ApiOperation("校验当前用户是否已绑定护照")
@GetMapping("/check")
public ResponseDto<Boolean> checkBound() {
return adamCaomeiPassportUserService.checkPassportBound();
}
}
......@@ -697,6 +697,54 @@ public class AdamRdmService {
return badges;
}
/**
* 用户认领徽章时追加一条(与收货地址 addAddressesVoByUid 相同:写回整列表到 Redis)
*/
public boolean addUserCaomeiBadgeDtoByUid(String uid,
List<AdamCaomeiPassportUserBadgeDto> vos,
AdamCaomeiPassportUserBadgeDto dto) {
if (vos == null) {
vos = new ArrayList<>();
}
vos.add(dto);
return setUserCaomeiBadgesByUid(uid, vos);
}
/**
* 用户认领徽章时批量追加(一次 set 回 Redis,避免循环多次写 Redis)
*/
public boolean addUserCaomeiBadgeDtosByUid(String uid,
List<AdamCaomeiPassportUserBadgeDto> vos,
List<AdamCaomeiPassportUserBadgeDto> appendVos) {
if (vos == null) {
vos = new ArrayList<>();
}
if (CollectionUtils.isEmpty(appendVos)) {
return setUserCaomeiBadgesByUid(uid, vos);
}
vos.addAll(appendVos);
return setUserCaomeiBadgesByUid(uid, vos);
}
/**
* 根据身份证获取已支付演出ID列表(60秒短缓存,缓解无索引热点查询)
*/
public List<String> getPaidPerformanceIdsByIdCard(String idCard) {
if (StringUtils.isEmpty(idCard)) {
return Collections.emptyList();
}
String rk = AdamRedisConst.INFO_CAOMEI_PAID_PERFORMANCE_IDS_BY_IDCARD.concat(idCard);
List<String> performanceIds = (List<String>) redisUtil.get(rk);
if (CollectionUtils.isEmpty(performanceIds)) {
performanceIds = adamCaomeiBadgeMapper.selectPaidPerformanceIdsByIdCard(idCard);
if (performanceIds == null) {
performanceIds = Collections.emptyList();
}
redisUtil.set(rk, performanceIds, 60);
}
return performanceIds;
}
/**
* 删除用户徽章redis
* @param uid
......
......@@ -2,6 +2,7 @@ package com.liquidnet.service.adam.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto;
import com.liquidnet.service.adam.dto.vo.*;
import com.liquidnet.service.adam.entity.AdamCaomeiBadge;
......@@ -12,20 +13,18 @@ import com.liquidnet.service.adam.mapper.AdamCaomeiBadgeMapper;
import com.liquidnet.service.adam.mapper.AdamCaomeiPassportMapper;
import com.liquidnet.service.adam.service.AdamRdmService;
import com.liquidnet.service.adam.service.IAdamCaomeiPassportUserService;
import com.liquidnet.service.adam.util.QueueUtils;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
......@@ -41,6 +40,8 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
private AdamCaomeiBadgeApplyRecordMapper badgeApplyRecordMapper;
@Autowired
private AdamRdmService adamRdmService;
@Autowired
private QueueUtils queueUtils;
@Override
@Transactional(rollbackFor = Exception.class)
......@@ -87,29 +88,68 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
if (publishedBadges == null) {
publishedBadges = new ArrayList<>();
}
// 所有护照类型徽章
List<AdamCaomeiBadge> passportTypeBadges = publishedBadges.stream()
.filter(b -> b.getType() != null && b.getType() == 1)
.collect(Collectors.toList());
if (passportTypeBadges.isEmpty()) {
log.info("[bindPassport] 暂无上架徽章");
return ResponseDto.success();
}
List<String> badgeIds = passportTypeBadges.stream()
.map(AdamCaomeiBadge::getBadgeId)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
Date grantAt = new Date();
if (!badgeIds.isEmpty()) {
adamCaomeiBadgeMapper.insertUserBadgesBatch(uid, badgeIds, 1, grantAt);
Date grantAt = DateUtil.now();
// 兼容 claimBadge 的写法:把本次发放的护照徽章同时写入用户徽章缓存列表
List<AdamCaomeiPassportUserBadgeDto> cacheBadgeVos = adamRdmService.getUserCaomeiBadgesByUid(uid);
if (cacheBadgeVos == null) {
cacheBadgeVos = new ArrayList<>();
} else {
cacheBadgeVos = new ArrayList<>(cacheBadgeVos);
}
Set<String> existedBadgeIds = cacheBadgeVos.stream()
.map(AdamCaomeiPassportUserBadgeDto::getBadgeId)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
List<AdamCaomeiPassportUserBadgeDto> appendVos = passportTypeBadges.stream()
.filter(b -> b != null && StringUtils.isNotBlank(b.getBadgeId()) && !existedBadgeIds.contains(b.getBadgeId()))
.map(b -> {
AdamCaomeiPassportUserBadgeDto dto = new AdamCaomeiPassportUserBadgeDto();
dto.setBadgeId(b.getBadgeId());
dto.setBadgeName(StringUtils.defaultString(b.getName()));
dto.setIcon(StringUtils.defaultString(b.getIcon()));
dto.setShareText(StringUtils.defaultString(b.getShareText()));
dto.setType(b.getType());
dto.setClaimedAt(grantAt);
dto.setSource(1);
return dto;
})
.collect(Collectors.toList());
adamRdmService.addUserCaomeiBadgeDtosByUid(uid, cacheBadgeVos, appendVos);
LinkedList<Object[]> paramsList = new LinkedList<>();
for (String badgeId : badgeIds) {
paramsList.add(new Object[]{uid, badgeId, 1, grantAt});
}
// 清理用户徽章缓存,下次读取首页时回源并重建
adamRdmService.delUserCaomeiBadgesByUid(uid);
queueUtils.sendMsgByRedis(
MQConst.AdamQueue.SQL_UCENTER.getKey(),
SqlMapping.get("adam_caomei_user_badge.add", paramsList)
);
// 5. 返回本次绑定场景下的护照类型徽章列表(用于前端弹窗)
List<AdamCaomeiPassportUserClaimedBadgeVo> grantedBadges = passportTypeBadges.stream().map(b -> {
List<AdamCaomeiPassportUserClaimedBadgeVo> grantedBadges = appendVos.stream().map(b -> {
AdamCaomeiPassportUserClaimedBadgeVo v = new AdamCaomeiPassportUserClaimedBadgeVo();
v.setBadgeId(b.getBadgeId());
v.setName(StringUtils.defaultString(b.getName()));
v.setName(StringUtils.defaultString(b.getBadgeName()));
v.setIcon(StringUtils.defaultString(b.getIcon()));
v.setShareText(StringUtils.defaultString(b.getShareText()));
v.setType(b.getType());
v.setClaimedAt(grantAt);
v.setClaimedAt(b.getClaimedAt());
v.setSource(1);
return v;
}).collect(Collectors.toList());
......@@ -153,7 +193,7 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
// 5. TODO 优化点
final List<String> paidPerformanceIds = StringUtils.isNotBlank(idCard)
? adamCaomeiBadgeMapper.selectPaidPerformanceIdsByIdCard(idCard)
? adamRdmService.getPaidPerformanceIdsByIdCard(idCard)
: new ArrayList<>();
log.info("[getPassportHome] 用户已支付的演出订单数量, uid: {}, 数量: {}", uid, paidPerformanceIds.size());
......@@ -192,6 +232,13 @@ public class AdamCaomeiPassportUserServiceImpl implements IAdamCaomeiPassportUse
return ResponseDto.success(home);
}
@Override
public ResponseDto<Boolean> checkPassportBound() {
String uid = CurrentUtil.getCurrentUid();
AdamCaomeiPassport bound = findBoundPassportForUser(uid);
return ResponseDto.success(bound != null);
}
private AdamCaomeiPassportUserCardVo buildUserCard(String uid, AdamCaomeiPassport bound) {
AdamCaomeiPassportUserCardVo card = new AdamCaomeiPassportUserCardVo();
card.setPassportBound(true);
......
......@@ -80,10 +80,13 @@ adam_user_mobile_locate.update_province=UPDATE adam_user_mobile_locate SET provi
adam_user_mobile_locate.close=UPDATE adam_user_mobile_locate SET `state`=2, updated_at=? WHERE uid=? AND `state`=1
# ----------------------------------------------------
# \u8349\u8393\u62A4\u7167-\u7528\u6237\u5FBD\u7AE0\u83B7\u5F97\u8BB0\u5F55 (adam_caomei_user_badge)
# \u7528\u6237\u7AEF claimBadge\uFF1A\u4E0E AdamCaomeiBadgeUserServiceImpl \u4E2D\u300C\u5148\u5199 Redis \u7528\u6237\u5FBD\u7AE0\u5217\u8868\u3001\u518D MQ \u5F02\u6B65\u843D\u5E93\u300D\u914D\u5957\uFF1B\u53C2\u6570\u987A\u5E8F user_id, badge_id, source\uFF1Bcreated_at \u7531\u5E93\u7AEF now() \u5199\u5165
adam_caomei_user_badge.add=INSERT INTO adam_caomei_user_badge (user_id, badge_id, source, created_at) VALUES (?,?,?,?)
# ----------------------------------------------------
# \u8349\u8393\u62A4\u7167-\u5FBD\u7AE0\u8865\u7B7E\u7533\u8BF7 (adam_caomei_badge_apply_record)
# \u7528\u6237\u7AEF applyBadge\uFF1A\u4E0E\u300C\u5148\u5199 Redis \u8865\u7B7E\u5217\u8868\u3001\u518D MQ \u5F02\u6B65\u843D\u5E93\u300D\u914D\u5957\uFF1B\u53C2\u6570\u987A\u5E8F apply_record_id, user_id, badge_id, performance_id, proof_image_url\uFF1Baudit_status=0\u3001reject_reason \u7A7A\u4E32\u3001\u65F6\u95F4\u7531 now() \u5199\u5165
adam_caomei_badge_apply_record.add=INSERT INTO adam_caomei_badge_apply_record (apply_record_id, user_id, badge_id, performance_id, proof_image_url, audit_status, reject_reason, created_at, updated_at) VALUES (?,?,?,?,?,0,'',now(),now())
# ----------------------------------------------------
candy_user_coupon.close=UPDATE candy_user_coupon SET state=2,updated_at=sysdate(),operator='close' WHERE uid=? AND state=1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment