package com.github.ouyangbob.wechat.service.impl;
import java.util.Calendar;
import java.util.Date;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.github.ouyangbob.util.UUIDGenerator;
import com.github.ouyangbob.wechat.mapper.AwardRecordMapper;
import com.github.ouyangbob.wechat.model.entity.AwardRecord;
import com.github.ouyangbob.wechat.service.IAwardService;
@Service
public class AwardServiceImpl implements IAwardService {
@Autowired
private AwardRecordMapper awardRecordMapper;
@Autowired
private RedisTemplate<String, Integer> redisTemplate;
/**
* 不中奖编号为0, 1、2、3等将一次为1、2、3
*/
private static int AWARD0_ID=0;
private static int AWARD1_ID=1;
private static int AWARD2_ID=2;
private static int AWARD3_ID=3;
private static int AWARD1_MAX=15;
private static int AWARD1_DAY_MAX=1;
private static int AWARD2_MAX=1000;
private static int AWARD2_DAY_MAX=34;
//private static int AWARD3_MAX=10000;
private static int AWARD1_PROBABILITY=5;
private static int AWARD2_PROBABILITY=1000;
private static int AWARD3_PROBABILITY=10000;
private static int PROBABILITY_MAX=(AWARD3_PROBABILITY+AWARD2_PROBABILITY+AWARD1_PROBABILITY);
public boolean saveGenerateAward(String code, String mobile) {
Integer cacheAwardNo = this.getCodeAwardNo(code);
if(cacheAwardNo!=null){
removeCodeAwardNo(code);
AwardRecord awardRecord=new AwardRecord();
awardRecord.setSecurityCode(code);
awardRecord.setAwardNo(cacheAwardNo.toString());
awardRecord.setId(UUIDGenerator.generate());
awardRecord.setMobile(mobile);
awardRecord.setAddDate(new Date());
awardRecordMapper.insert(awardRecord);
//设置编码使用次数
addCodeUseCount(code);
//添加奖品发放数量
addAwardSendingCount(cacheAwardNo);
//添加奖品当天发放数量
addAwardDaySendingCount(cacheAwardNo);
return true;
}
return false;
}
public int randomGenerateAward(String code) {
int codeCount=this.getCodeUseCount(code);
if(codeCount>0){
return AWARD0_ID;
}
Integer cacheAwardNo = this.getCodeAwardNo(code);
if(cacheAwardNo!=null){
return cacheAwardNo;
}
int resultAwardNo=AWARD3_ID;
int randomAwardNo=randomAwardNo();
if(randomAwardNo==AWARD1_ID){
/**
* 如果是1等奖则判断总数和每天获取的数量
*/
if(this.getAwardSendingCount(randomAwardNo)<AWARD1_MAX
&& this.getAwardDaySendingCount(randomAwardNo)<AWARD1_DAY_MAX ){
resultAwardNo=randomAwardNo;
}
}else if(randomAwardNo==AWARD1_ID){
/**
* 如果是2等奖则判断总数和每天获取的数量
*/
if(this.getAwardSendingCount(randomAwardNo)<AWARD2_MAX
&& this.getAwardDaySendingCount(randomAwardNo)<AWARD2_DAY_MAX ){
resultAwardNo=randomAwardNo;
}
}
/**
* TODO 移动到另外一个方法插入mysql
*/
/**
* 填充redis数据
*/
if(randomAwardNo==AWARD3_ID){
//设置编码使用次数
addCodeUseCount(code);
//添加奖品发放数量
addAwardSendingCount(randomAwardNo);
//添加奖品当天发放数量
addAwardDaySendingCount(randomAwardNo);
}else{
//设置编码中奖号码---防止未输入手机号的可以重新输入手机号
setCodeAwardNo(code, randomAwardNo);
}
return resultAwardNo;
}
/**
* 生成随机数
* @return
*/
private int randomAwardNo(){
int randomInt=RandomUtils.nextInt(0, PROBABILITY_MAX);
if(randomInt<=AWARD1_PROBABILITY){
return AWARD1_ID;
}else if(randomInt<=AWARD1_PROBABILITY+AWARD2_PROBABILITY){
return AWARD2_ID;
}else if(randomInt<=AWARD1_PROBABILITY+AWARD2_PROBABILITY+AWARD3_PROBABILITY){
return AWARD3_ID;
}else{
return AWARD0_ID;
}
}
/**
* 获取编码使用次数
* @param code
* @return
*/
private int getCodeUseCount(String code){
String key="code:".concat(code);
return redisTemplate.opsForValue().increment(key, 0).intValue();
}
/**
* 设置编码使用次数
* @param code
* @return
*/
private int addCodeUseCount(String code){
String key="code:".concat(code);
return redisTemplate.opsForValue().increment(key, 1).intValue();
}
/**
* 获取奖品发放数量
* @param code
* @return
*/
private int getAwardSendingCount(int awardNo){
String key="award:"+awardNo;
return redisTemplate.opsForValue().increment(key, 0).intValue();
}
/**
* 获取奖品当天发放数量
* @param code
* @return
*/
private int getAwardDaySendingCount(int awardNo){
final Calendar calendar = Calendar.getInstance();
int day=calendar.get(Calendar.DAY_OF_MONTH);
String key="award:"+day+":"+awardNo;
return redisTemplate.opsForValue().increment(key, 0).intValue();
}
/**
* 添加奖品发放数量
* @param code
* @return
*/
private int addAwardSendingCount(int awardNo){
String key="award:"+awardNo;
return redisTemplate.opsForValue().increment(key, 1).intValue();
}
/**
* 添加奖品当天发放数量
* @param code
* @return
*/
private int addAwardDaySendingCount(int awardNo){
final Calendar calendar = Calendar.getInstance();
int day=calendar.get(Calendar.DAY_OF_MONTH);
String key="award:"+day+":"+awardNo;
return redisTemplate.opsForValue().increment(key, 1).intValue();
}
/**
* 获取编码中奖编号
* @param code
* @return
*/
private Integer getCodeAwardNo(String code){
String key="code:award:".concat(code);
return redisTemplate.opsForValue().get(key);
}
/**
* 设置编码中奖号码
* @param code
* @return
*/
private void setCodeAwardNo(String code,int award){
String key="code:award:".concat(code);
redisTemplate.opsForValue().set(key,award);
}
/**
* 设置编码中奖号码
* @param code
* @return
*/
private void removeCodeAwardNo(String code){
String key="code:award:".concat(code);
redisTemplate.delete(key);
}
}