diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java index 27a081dacc..db65ca6e0d 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisUtils.java @@ -9,16 +9,23 @@ package com.epmet.commons.tools.redis; import com.epmet.commons.tools.constant.NumConstant; +import com.epmet.commons.tools.exception.RenException; +import com.epmet.commons.tools.utils.ConvertUtils; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.*; import org.springframework.data.redis.support.atomic.RedisAtomicLong; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * Redis工具类 @@ -171,10 +178,40 @@ public class RedisUtils { } } - public Object lindex(String key,Long index){ - return redisTemplate.opsForList().index(key,index); + public Object lindex(String key,Long index){ return redisTemplate.opsForList().index(key,index); } + public List lrange(String key,long start,long end,Class clazz){ + List content = redisTemplate.opsForList().range(key,start,end); + if(CollectionUtils.isEmpty(content)) return null; + return content.stream().map( o -> { + try { + T target = clazz.newInstance(); + BeanUtils.copyProperties(o, target); + return target; + }catch (Exception e){throw new RenException("convert error");}finally{throw new RenException("convert error");} + }).collect(Collectors.toList()); + } + + /** + * @Description Redis lrem : + * 根据参数 count 的值,移除列表中与参数 value 相等的元素 + * COUNT 的值可以是以下几种 : + * count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count + * count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值 + * count = 0 : 移除表中所有与 value 相等的值 + * 返回值 : + * 被移除元素的数量 + * 列表不存在时返回 0 + * @param key + * @param count + * @param o 这里的Object需要重写equals(FIXME 注意序列化) + * @return long + * @author wangc + * @date 2020.11.05 10:22 + */ + public long lrem(String key,long count,Object o){ return redisTemplate.opsForList().remove(key,count,o);} + public Object rightPop(String key) { return redisTemplate.opsForList().rightPop(key); } diff --git a/epmet-user/epmet-user-client/src/main/java/com/epmet/dto/form/UserBadgeUnitFormDTO.java b/epmet-user/epmet-user-client/src/main/java/com/epmet/dto/form/UserBadgeUnitFormDTO.java new file mode 100644 index 0000000000..406f527bb9 --- /dev/null +++ b/epmet-user/epmet-user-client/src/main/java/com/epmet/dto/form/UserBadgeUnitFormDTO.java @@ -0,0 +1,48 @@ +package com.epmet.dto.form; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Objects; + +/** + * @Description 用户-徽章缓存单元 + * @ClassName UserBadgeUnitFormDTO + * @Auth wangc + * @Date 2020-11-05 10:00 + */ +@Data +public class UserBadgeUnitFormDTO implements Serializable { + private static final long serialVersionUID = -4497394865738168850L; + + /** + * 徽章Id + */ + private String badgeId; + + /** + * 徽章图标 url + */ + private String badgeIcon; + + /** + * 徽章名称 + */ + private String badgeName; + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UserBadgeUnitFormDTO that = (UserBadgeUnitFormDTO) o; + return badgeId.equals(that.badgeId) && + badgeIcon.equals(that.badgeIcon) && + badgeName.equals(that.badgeName); + } + + @Override + public int hashCode() { + return Objects.hash(badgeId, badgeIcon, badgeName); + } +} diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserRedisKeys.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserRedisKeys.java index f4fffb6975..599beea58f 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserRedisKeys.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/constant/UserRedisKeys.java @@ -23,4 +23,14 @@ public class UserRedisKeys { public static String getResiUserKey(String userId){ return rootPrefix.concat("resi:user:").concat(userId); } + + /** + * @Description 用户勋章缓存 epmet:badge:user:[customerId]:[userId] + * @param userId + * @return epmet:badge:user:[customerId]:[userId] + * @author wangc + * @date 2020.11.05 13:34 + */ + public static String getResiUserBadgeKey(String customerId,String userId){ + return rootPrefix.concat("badge:user:").concat(customerId).concat(userId);} } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/BadgeDao.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/BadgeDao.java index 965f753b6e..3b3fa6c596 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/BadgeDao.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/dao/BadgeDao.java @@ -20,6 +20,7 @@ package com.epmet.dao; import com.epmet.commons.mybatis.dao.BaseDao; import com.epmet.dto.result.BadgeDetailResultDTO; import com.epmet.dto.result.BadgeListResultDTO; +import com.epmet.dto.result.UserBadgeListResultDTO; import com.epmet.entity.BadgeEntity; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -105,4 +106,13 @@ public interface BadgeDao extends BaseDao { * @return void */ void deleteBadge(@Param("customerId") String customerId, @Param("badgeId") String badgeId); + + /** + * @Description 查询客户的徽章 + * @param customerId + * @return java.util.List + * @author wangc + * @date 2020.11.05 15:50 + */ + List selectCustomerBadgePool(@Param("customerId") String customerId); } \ No newline at end of file diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/redis/UserBadgeRedis.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/redis/UserBadgeRedis.java index c9eaee4367..0fc766cdf6 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/redis/UserBadgeRedis.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/redis/UserBadgeRedis.java @@ -1,13 +1,26 @@ package com.epmet.redis; + +import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; +import com.epmet.commons.tools.constant.NumConstant; import com.epmet.commons.tools.redis.RedisUtils; +import com.epmet.commons.tools.utils.ConvertUtils; import com.epmet.constant.BadgeConstant; +import com.epmet.constant.UserRedisKeys; +import com.epmet.dao.BadgeDao; +import com.epmet.dto.form.UserBadgeUnitFormDTO; +import com.epmet.dto.result.BadgeListResultDTO; import com.epmet.dto.result.UserBadgeListResultDTO; +import com.epmet.service.UserBadgeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Optional; import static com.epmet.commons.tools.redis.RedisUtils.MINUTE_THIRTY_EXPIRE; @@ -16,45 +29,50 @@ import static com.epmet.commons.tools.redis.RedisUtils.MINUTE_THIRTY_EXPIRE; * @DateTime 2020/11/3 2:21 下午 */ @Component +@Slf4j public class UserBadgeRedis { @Autowired private RedisUtils redisUtils; + @Autowired + private BadgeDao badgeDao; + @Autowired + private UserBadgeService badgeService; /** - * @Description 获取客户徽章信息 + * @Description 获取客户徽章信息 * @Param customerId * @author zxc * @date 2020/11/3 2:50 下午 */ - public Object getCustomerBadge(String customerId){ + public Object getCustomerBadge(String customerId) { Object userBadge = redisUtils.hGet(BadgeConstant.BADGE_KEY + customerId, BadgeConstant.BADGE); return userBadge; } /** - * @Description 存放客户徽章信息 + * @Description 存放客户徽章信息 * @Param userBadge * @Param customerId * @author zxc * @date 2020/11/3 2:51 下午 */ - public void setCustomerBadge(List userBadge, String customerId){ - redisUtils.hSet(BadgeConstant.BADGE_KEY+customerId,BadgeConstant.BADGE, JSON.toJSON(userBadge).toString(),-1); + public void setCustomerBadge(List userBadge, String customerId) { + redisUtils.hSet(BadgeConstant.BADGE_KEY + customerId, BadgeConstant.BADGE, JSON.toJSON(userBadge).toString(), -1); } /** - * @Description 删除客户徽章信息 + * @Description 删除客户徽章信息 * @Param customerId * @author zxc * @date 2020/11/5 3:06 下午 */ - public void delCustomerBadge(String customerId){ - redisUtils.hDel(BadgeConstant.BADGE_KEY+customerId,BadgeConstant.BADGE); + public void delCustomerBadge(String customerId) { + redisUtils.hDel(BadgeConstant.BADGE_KEY + customerId, BadgeConstant.BADGE); } /** - * @Description 存放徽章审核 手机验证码 + * @Description 存放徽章审核 手机验证码 * @Param mobile * @author zxc * @date 2020/11/5 10:30 上午 @@ -65,7 +83,7 @@ public class UserBadgeRedis { } /** - * @Description 获取徽章审核 手机验证码 + * @Description 获取徽章审核 手机验证码 * @Param mobile * @author zxc * @date 2020/11/5 10:30 上午 @@ -76,4 +94,56 @@ public class UserBadgeRedis { return smsCode; } -} + /** + * @param userId + * @return java.util.List + * @Description 获取用户的全部勋章信息(点亮的 、 排序从前到后) + * @author wangc + * @date 2020.11.05 13:26 + */ + public List obtainUserBadge2List(String userId) { + //TODO 补偿 + return redisUtils.lrange(UserRedisKeys.getResiUserKey(userId), NumConstant.ZERO, NumConstant.ONE_NEG, UserBadgeUnitFormDTO.class); + } + + /** + * 用户点亮或取消徽章 + * @param + * @return int + * @Description 入栈时使用lpush 出栈时使用lrem + * @author wangc + * @date 2020.11.05 13:37 + */ + public long pushOrRemoveUserBadge4List(String userId, String badgeId, String customerId) { + List orient = obtainUserBadge2List(userId); + UserBadgeUnitFormDTO unit = null; + + if (!CollectionUtils.isEmpty(orient)) { + Optional opt = orient.stream().filter(badge -> StringUtils.equals(badgeId, badge.getBadgeId())).findFirst(); + if (opt.isPresent()) { + unit = opt.get(); + return redisUtils.lrem(UserRedisKeys.getResiUserBadgeKey(customerId, userId), NumConstant.ONE, unit); + } + } + + //徽章池 + List badgePool = + Optional.ofNullable(JSON.parseArray(getCustomerBadge(customerId).toString(), UserBadgeListResultDTO.class)) + .orElse(badgeDao.selectCustomerBadgePool(customerId)); + if (CollectionUtils.isEmpty(badgePool)) { + log.error("com.epmet.redis.UserBadgeRedis.pushOrRemoveUserBadge4List,缓存中客户{}下的徽章池为空", customerId); + return NumConstant.ZERO; + } + + if (null == unit) { + Optional poolOpt = + badgePool.stream().filter(badge -> StringUtils.equals(badge.getBadgeId(), badgeId)).findFirst(); + if (poolOpt.isPresent()) unit = ConvertUtils.sourceToTarget(poolOpt.get(), UserBadgeUnitFormDTO.class); + else return NumConstant.ZERO; + } + redisUtils.leftPush(UserRedisKeys.getResiUserBadgeKey(customerId, userId), unit); + return NumConstant.ONE; + } + + } + diff --git a/epmet-user/epmet-user-server/src/main/resources/mapper/BadgeDao.xml b/epmet-user/epmet-user-server/src/main/resources/mapper/BadgeDao.xml index 322604bc70..d66bb7194a 100644 --- a/epmet-user/epmet-user-server/src/main/resources/mapper/BadgeDao.xml +++ b/epmet-user/epmet-user-server/src/main/resources/mapper/BadgeDao.xml @@ -112,5 +112,44 @@ select * from badge where DEL_FLAG = '0' AND CUSTOMER_ID = #{customerId} AND ID = #{badgeId} + + \ No newline at end of file