总览:
1、使用Redis存储投资信息
2、Redis常量类
在common模块constants包,创建一个Redis常量类(RedisKey):
package com.bjpowernode.common.constants;
public class RedisKey {
/*投资排行榜*/
public static final String KEY_INVEST_RANK = "INVEST:RANK";
/*注册时,短信验证码 SMS:REG:手机号*/
public static final String KEY_SMS_CODE_REG = "SMS:REG:";
/*登录时,短信验证码 SMS:LOGIN:手机号*/
public static final String KEY_SMS_CODE_LOGIN = "SMS:LOGIN:";
/*redis自增*/
public static final String KEY_RECHARGE_ORDERID = "RECHARGE:ORDERID:SEQ";
/*orderId*/
public static final String KEY_ORDERID_SET= "RECHARGE:ORDERID:SET";
}
3、显示存储投资排行榜的数据RankView
在web模块view包,创建一个显示投资排行榜的数据RankView类:
package com.bjpowernode.front.view.invest;
/**
* 存储投资排行榜的数据
*/
public class RankView {
private String phone;
private Double money;
public RankView(String phone, Double money) {
this.phone = phone;
this.money = money;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
4、controller处理
在web模块controller包,BaseController添加Redis模板对象(StringRedisTemplate):
package com.bjpowernode.front.controller;
import com.bjpowernode.api.service.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.redis.core.StringRedisTemplate;
import javax.annotation.Resource;
/**
* 公用controller类
*/
public class BaseController {
//声明公共的方法,属性的等
@Resource
protected StringRedisTemplate stringRedisTemplate;
//平台信息服务
@DubboReference(interfaceClass = PlatBaseInfoService.class,version = "1.0")
protected PlatBaseInfoService platBaseInfoService;
//产品服务
@DubboReference(interfaceClass = ProductService.class,version = "1.0")
protected ProductService productService;
//投资服务
@DubboReference(interfaceClass = InvestService.class,version = "1.0")
protected InvestService investService;
//用户服务
@DubboReference(interfaceClass = UserService.class,version = "1.0")
protected UserService userService;
//充值服务
@DubboReference(interfaceClass = RechargeService.class,version = "1.0")
protected RechargeService rechargeService;
}
在web模块controller包,创建投资控制InvestController 类:
投资排行榜(showInvestRank())
package com.bjpowernode.front.controller;
import com.bjpowernode.api.model.User;
import com.bjpowernode.common.constants.RedisKey;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.front.view.RespResult;
import com.bjpowernode.front.view.invest.RankView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 有关投资功能
*/
@Api(tags = "投资理财产品")
@RestController
public class InvestController extends BaseController {
/*投资排行榜*/
@ApiOperation(value = "投资排行榜", notes = "显式投资金额最高的3位用户信息")
@GetMapping("/v1/invest/rank")
public RespResult showInvestRank() {
//从redis查询数据
Set<ZSetOperations.TypedTuple<String>> sets = stringRedisTemplate
.boundZSetOps(RedisKey.KEY_INVEST_RANK).reverseRangeWithScores(0, 2);
List<RankView> rankList = new ArrayList<>();
//遍历set集合(lamdba表达式)
sets.forEach(tuple -> {
//tuple.getValue();//手机号
//tuple.getScore();//投资金额
rankList.add(new RankView(CommonUtil.tuoMinPhone(tuple.getValue()), tuple.getScore()));
});
RespResult result = RespResult.ok();
result.setList(rankList);
return result;
}
/*购买理财产品, 更新投资排行榜*/
@ApiOperation(value = "投资理财产品")
@PostMapping("/v1/invest/product")
public RespResult investProduct(
@RequestHeader("uid") Integer uid,
@RequestParam("productId") Integer productId,
@RequestParam("money") BigDecimal money){
RespResult result = RespResult.fail();
//1.检查基本参数
if( (uid != null && uid > 0) && (productId != null && productId > 0)
&&( money != null && money.intValue() % 100 == 0 && money.intValue() >= 100)){
int investResult = investService.investProduct(uid,productId,money);
switch (investResult){
case 0:
result.setMsg("投资数据不正确");
break;
case 1:
result = RespResult.ok();
modifyInvestRank(uid,money);
break;
case 2:
result.setMsg("资金账号不存在");
break;
case 3:
result.setMsg("资金不足");
break;
case 4:
result.setMsg("理财产品不存在");
break;
}
}
return result;
}
/*更新投资排行榜*/
private void modifyInvestRank(Integer uid,BigDecimal money){
User user = userService.queryById(uid);
if(user != null){
//更新redis中的投资排行榜
String key = RedisKey.KEY_INVEST_RANK;
stringRedisTemplate.boundZSetOps(key).incrementScore(
user.getPhone(),money.doubleValue());
}
}
}
手机号脱敏
在common模块util包,工具类CommonUtil添加手机号脱敏方法:(public static String tuoMinPhone(String phone))
1、参数(手机号)验证(存在且为11位数字)
2、拼接前几位和后几位,中间用’*'表示
package com.bjpowernode.common.util;
import java.math.BigDecimal;
import java.util.regex.Pattern;
public class CommonUtil {
/*处理pageNo*/
public static int defaultPageNo(Integer pageNo) {
int pNo = pageNo;
if (pageNo == null || pageNo < 1) {
pNo = 1;
}
return pNo;
}
/*处理pageSize*/
public static int defaultPageSize(Integer pageSize) {
int pSize = pageSize;
if (pageSize == null || pageSize < 1) {
pSize = 1;
}
return pSize;
}
/*手机号脱敏*/
public static String tuoMinPhone(String phone) {
String result = "***********";
if (phone != null && phone.trim().length() == 11) {
result = phone.substring(0,3) + "******" + phone.substring(9,11);
}
return result;
}
/*手机号格式 true:格式正确;false不正确*/
public static boolean checkPhone(String phone){
boolean flag = false;
if( phone != null && phone.length() == 11 ){
//^1[1-9]\\d{9}$
flag = Pattern.matches("^1[1-9]\\d{9}$",phone);
}
return flag;
}
/*比较BigDecimal n1 >=n2 :true ,false*/
public static boolean ge(BigDecimal n1, BigDecimal n2){
if( n1 == null || n2 == null){
throw new RuntimeException("参数BigDecimal是null");
}
return n1.compareTo(n2) >= 0;
}
}
全局跨域设置
在web模块settings包,创建一个全局跨域配置类WebMvcConfiguration
package com.bjpowernode.front.settings;
import com.bjpowernode.front.interceptor.TokenInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* 全局跨域
*/
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Value("${jwt.secret}")
private String jwtSecret;
/*token拦截器*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
TokenInterceptor tokenInterceptor = new TokenInterceptor(jwtSecret);
String [] addPath = {"/v1/user/realname"};
registry.addInterceptor(tokenInterceptor)
.addPathPatterns(addPath);
}
/*处理跨域*/
@Override
public void addCorsMappings(CorsRegistry registry) {
System.out.println("===========addCorsMappings===========");
//addMapping 处理的请求地址, 拦截这些地址,使用跨域处理逻辑
registry.addMapping("/**")
.allowedOriginPatterns("http://localhost:8080") //可跨域的域名,可以为 *
//支持跨域请求的,http方式
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
//支持跨域的请求头, 在请求头包含哪些数据时,可以支持跨域功能
.allowedHeaders("*");
}
}