From 432d5464cbe9966bcbad5280bfad12c19186de08 Mon Sep 17 00:00:00 2001 From: Administrator Date: Wed, 30 Nov 2022 19:31:45 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=86=E9=A2=91055~(=E9=9B=AA=E8=8A=B1?= =?UTF-8?q?=E7=AE=97=E6=B3=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/client/BeaconCacheClient.java | 1 + .../api/filter/impl/FeeCheckFilter.java | 46 +++++++ beacon-common/pom.xml | 5 + .../common/constant/ApiConstant.java | 5 + .../common/enums/ExceptionEnums.java | 3 +- .../common/model/StandardSubmit.java | 2 +- .../mashibing/common/util/SnowFlakeUtil.java | 113 ++++++++++++++++++ .../test/mapper/ClientBalanceMapper.java | 5 +- .../test/mapper/ClientBalanceMapperTest.java | 14 ++- 9 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 beacon-common/src/main/java/com/mashibing/common/util/SnowFlakeUtil.java diff --git a/beacon-api/src/main/java/com/mashibing/api/client/BeaconCacheClient.java b/beacon-api/src/main/java/com/mashibing/api/client/BeaconCacheClient.java index 1d97dce..46db4ce 100644 --- a/beacon-api/src/main/java/com/mashibing/api/client/BeaconCacheClient.java +++ b/beacon-api/src/main/java/com/mashibing/api/client/BeaconCacheClient.java @@ -25,4 +25,5 @@ public interface BeaconCacheClient { @GetMapping("/cache/smember/{key}") Set smember(@PathVariable(value = "key")String key); + } diff --git a/beacon-api/src/main/java/com/mashibing/api/filter/impl/FeeCheckFilter.java b/beacon-api/src/main/java/com/mashibing/api/filter/impl/FeeCheckFilter.java index 7c4483c..2b7263e 100644 --- a/beacon-api/src/main/java/com/mashibing/api/filter/impl/FeeCheckFilter.java +++ b/beacon-api/src/main/java/com/mashibing/api/filter/impl/FeeCheckFilter.java @@ -1,8 +1,14 @@ package com.mashibing.api.filter.impl; +import com.mashibing.api.client.BeaconCacheClient; import com.mashibing.api.filter.CheckFilter; +import com.mashibing.common.constant.ApiConstant; +import com.mashibing.common.constant.CacheConstant; +import com.mashibing.common.enums.ExceptionEnums; +import com.mashibing.common.exception.ApiException; import com.mashibing.common.model.StandardSubmit; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** @@ -13,9 +19,49 @@ import org.springframework.stereotype.Service; @Slf4j public class FeeCheckFilter implements CheckFilter { + @Autowired + private BeaconCacheClient cacheClient; + + /** + * 只要短信内容的文字长度小于等于70个字,按照一条计算 + */ + private final int MAX_LENGTH = 70; + + /** + * 如果短信内容的文字长度超过70,67字/条计算 + */ + private final int LOOP_LENGTH = 67; + + private final String BALANCE = "balance"; + @Override public void check(StandardSubmit submit) { log.info("【接口模块-校验客户余额】 校验ing…………"); + //1、从submit中获取到短信内容 + int length = submit.getText().length(); + + //2、判断短信内容的长度,如果小于等于70,算作一条,如果大于70字,按照67字/条,算出来当前短信的费用 + if(length <= MAX_LENGTH){ + // 当前短信内容是一条 + submit.setFee(ApiConstant.SINGLE_FEE); + }else{ + int strip = length % LOOP_LENGTH == 0 ? length / LOOP_LENGTH : length / LOOP_LENGTH + 1; + submit.setFee(ApiConstant.SINGLE_FEE * strip); + } + + //3、从Redis中查询出客户剩余的金额 + Long balance = ((Integer) cacheClient.hget(CacheConstant.CLIENT_BALANCE + submit.getClientId(), BALANCE)).longValue(); + + //4、判断金额是否满足当前短信费用\ + if(balance >= submit.getFee()){ + log.info("【接口模块-校验客户余额】 用户金额充足!!"); + return; + } + + //5、不满足就抛出异常 + log.info("【接口模块-校验客户余额】 客户余额不足"); + throw new ApiException(ExceptionEnums.BALANCE_NOT_ENOUGH); } + } diff --git a/beacon-common/pom.xml b/beacon-common/pom.xml index 72bc9cd..1838d8e 100644 --- a/beacon-common/pom.xml +++ b/beacon-common/pom.xml @@ -16,6 +16,11 @@ org.projectlombok lombok + + org.springframework + spring-context + 5.3.12 + \ No newline at end of file diff --git a/beacon-common/src/main/java/com/mashibing/common/constant/ApiConstant.java b/beacon-common/src/main/java/com/mashibing/common/constant/ApiConstant.java index 9e21145..8bab719 100644 --- a/beacon-common/src/main/java/com/mashibing/common/constant/ApiConstant.java +++ b/beacon-common/src/main/java/com/mashibing/common/constant/ApiConstant.java @@ -15,4 +15,9 @@ public interface ApiConstant { */ String SIGN_SUFFIX = "】"; + /** + * 单条短信,默认每条50(厘) + */ + Long SINGLE_FEE = 50L; + } diff --git a/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java b/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java index ea6739f..769a06b 100644 --- a/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java +++ b/beacon-common/src/main/java/com/mashibing/common/enums/ExceptionEnums.java @@ -14,8 +14,9 @@ public enum ExceptionEnums { ERROR_SIGN(-3,"无可用签名"), ERROR_TEMPLATE(-4,"无可用模板"), ERROR_MOBILE(-5,"手机号格式不正确"), - BALANCE_NOT_ENOUGH(-6,"手客户余额不足"), + BALANCE_NOT_ENOUGH(-6,"客户余额不足"), PARAMETER_ERROR(-10,"参数不合法!"), + SNOWFLAKE_OUT_OF_RANGE(-11,"雪花算法的机器id或服务id超出最大范围!") ; private Integer code; diff --git a/beacon-common/src/main/java/com/mashibing/common/model/StandardSubmit.java b/beacon-common/src/main/java/com/mashibing/common/model/StandardSubmit.java index 9a539f4..34240e7 100644 --- a/beacon-common/src/main/java/com/mashibing/common/model/StandardSubmit.java +++ b/beacon-common/src/main/java/com/mashibing/common/model/StandardSubmit.java @@ -58,7 +58,7 @@ public class StandardSubmit { private LocalDateTime sendTime; /** - * 当前短信的费用,计算短信内容的文字,70个字一条,超过部分,67个字一条 + * 当前短信的费用,计算短信内容的文字,70个字一条,超过部分,67个字一条,单位(厘) */ private Long fee; diff --git a/beacon-common/src/main/java/com/mashibing/common/util/SnowFlakeUtil.java b/beacon-common/src/main/java/com/mashibing/common/util/SnowFlakeUtil.java new file mode 100644 index 0000000..c56178d --- /dev/null +++ b/beacon-common/src/main/java/com/mashibing/common/util/SnowFlakeUtil.java @@ -0,0 +1,113 @@ +package com.mashibing.common.util; + +import com.mashibing.common.enums.ExceptionEnums; +import com.mashibing.common.exception.ApiException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; + +/** + * 雪花算法生成全局唯一ID + * 64个bit为的long类型的值 + * 第一位:占1个bit位,就是0. + * 第二位:占41个bit位,代表时间戳 + * 第三位:占5个bit位,代表机器id + * 第四位:占5个bit位,服务id + * 第五位:占12个bit位,序列,自增的数值 + * @author zjw + * @description + */ +@Component +@Slf4j +public class SnowFlakeUtil { + + /** + * 41个bit位存储时间戳,从0开始计算,最多可以存储69.7年。 + * 那么如果默认使用,从1970年到现在,最多可以用到2039年左右。 + * 按照从2022-11-11号开始计算,存储41个bit为,这样最多可以使用到2092年不到~~ + */ + private long timeStart = 1668096000000L; + + /** + * 机器id + */ + @Value("${snowflake.machineId:0}") + private long machineId; + + /** + * 服务id + */ + @Value("${snowflake.serviceId:0}") + private long serviceId; + + /** + * 序列 + */ + private long sequence; + + + /** + * 机器id占用的bit位数 + */ + private long machineIdBits = 5L; + + /** + * 服务id占用的bit位数 + */ + private long serviceIdBits = 5L; + + /** + * 序列占用的bit位数 + */ + private long sequenceBits = 12L; + + /** + * 计算出机器id的最大值 + */ + private long maxMachineId = -1 ^ (-1 << machineIdBits); + + /** + * 计算出服务id的最大值 + */ + private long maxServiceId = -1 ^ (-1 << serviceIdBits); + + @PostConstruct + public void init(){ + if(machineId > maxMachineId || serviceId > maxServiceId){ + System.out.println("机器ID或服务ID超过最大范围值!!"); + throw new ApiException(ExceptionEnums.SNOWFLAKE_OUT_OF_RANGE); + } + } + + /** + * 服务id需要位移的位数 + */ + private long serviceIdShift = sequenceBits; + + /** + * 机器id需要位移的位数 + */ + private long machineIdShift = sequenceBits + serviceIdBits; + + /** + * 时间戳需要位移的位数 + */ + private long timestampShift = sequenceBits + serviceIdBits + maxMachineId; + + + + + + + + + + + +} diff --git a/beacon-test/src/main/java/com/mashibing/test/mapper/ClientBalanceMapper.java b/beacon-test/src/main/java/com/mashibing/test/mapper/ClientBalanceMapper.java index d5ba74c..835bdfd 100644 --- a/beacon-test/src/main/java/com/mashibing/test/mapper/ClientBalanceMapper.java +++ b/beacon-test/src/main/java/com/mashibing/test/mapper/ClientBalanceMapper.java @@ -1,5 +1,6 @@ package com.mashibing.test.mapper; +import com.mashibing.test.entity.ClientBalance; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @@ -9,7 +10,7 @@ import org.apache.ibatis.annotations.Select; */ public interface ClientBalanceMapper { - @Select("select balance from client_balance where client_id = #{clientId}") - Long findByClientId(@Param("clientId")Long clientId); + @Select("select * from client_balance where client_id = #{clientId}") + ClientBalance findByClientId(@Param("clientId")Long clientId); } diff --git a/beacon-test/src/test/java/com/mashibing/test/mapper/ClientBalanceMapperTest.java b/beacon-test/src/test/java/com/mashibing/test/mapper/ClientBalanceMapperTest.java index 6cf7ebd..93ad311 100644 --- a/beacon-test/src/test/java/com/mashibing/test/mapper/ClientBalanceMapperTest.java +++ b/beacon-test/src/test/java/com/mashibing/test/mapper/ClientBalanceMapperTest.java @@ -1,13 +1,16 @@ package com.mashibing.test.mapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.mashibing.test.client.CacheClient; +import com.mashibing.test.entity.ClientBalance; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import static org.junit.Assert.*; +import java.util.Map; @SpringBootTest @RunWith(SpringRunner.class) @@ -20,10 +23,11 @@ public class ClientBalanceMapperTest { private CacheClient cacheClient; @Test - public void findByClientId() { - Long balance = mapper.findByClientId(1L); - System.out.println(balance); + public void findByClientId() throws JsonProcessingException { + ClientBalance clientBalance = mapper.findByClientId(1L); + ObjectMapper objectMapper = new ObjectMapper(); + Map map = objectMapper.readValue(objectMapper.writeValueAsString(clientBalance), Map.class); - cacheClient.set("client_balance:1",balance); + cacheClient.hmset("client_balance:1",map); } } \ No newline at end of file