Commit ec4e4399 authored by 蔡隽贤's avatar 蔡隽贤

抽奖代码

parents
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.southsmart</groupId>
<artifactId>luck-draw</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>luck-draw</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.southsmart.luckdraw;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class LuckDrawApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(LuckDrawApplication.class, args);
}
}
package com.southsmart.luckdraw.entity;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 参与者
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ExcelTarget("Participant")
public class Participant {
//参与者姓名
@Excel(name = "姓名")
String name;
//积分
Integer score = 0;
//这轮的hash值
String hash = "";
//失利补偿
Integer incentive = 0;
}
package com.southsmart.luckdraw.service;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.southsmart.luckdraw.entity.Participant;
import com.southsmart.luckdraw.util.HttpUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.text.Collator;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@RestController
@RequestMapping("luckDraw")
public class LuckDrawService {
@Autowired
RestTemplate restTemplate;
private final int roundNum = 3;
//hash数组
private String[] hashArrays;
//参加人数
private Integer memberNum = 0;
//参加人名单
private List<Participant> participants = new ArrayList<>();
//三轮获奖名单
private List<Participant>[] results = new List[3];
//json字符串中匹配hash
private Pattern pattern = Pattern.compile("\"hash\":\"\\w{64}\"");
@CrossOrigin
@PostMapping("importParticipant")
public boolean joinIn(MultipartFile file, HttpServletResponse response) throws Exception {
try {
ImportParams params = new ImportParams();
params.setTitleRows(0);
params.setHeadRows(1);
participants = ExcelImportUtil.importExcel(file.getInputStream(), Participant.class, params);
memberNum = participants.size();
hashArrays = new String[memberNum];
//获取比特币hash
getHash();
return true;
}catch (Exception e){
return false;
}
}
@CrossOrigin
@GetMapping("getLuck")
public Map<String,Object> luckDraw(int prizeNum,HttpServletResponse response){
//封装结果的实体
Map<String,Object> result = new HashMap<>();
result.put("prizeNum",prizeNum);
//人数不足则返回null
if(prizeNum >= memberNum){
result.put("results",results);
return result;
}
//hash取够了开始抽奖
getLuck();
//剔除本轮中奖人并重置金币数
quitLuckDraw(prizeNum);
System.out.println("获奖名单:");
for(int i = 0 ; i < prizeNum;i++){
System.out.println(results[2].get(i).getName());
}
//保存名单
result.put("results",results);
return result;
}
/**
* 获取比特币hash
*/
public void getHash(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//获取昨日日期,当天交易量不足
Date today = new Date();
Calendar c = Calendar.getInstance();
c.setTime(today);
c.add(Calendar.DAY_OF_MONTH, -1);
today = c.getTime();
String todayDate = sdf.format(today);
//调用接口
HttpEntity httpEntity = HttpUtil.getHttpEntity();
String url = "https://chain.api.btc.com/v3/block/date/" + todayDate;
ResponseEntity<String> map = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
String body = map.getBody();
Matcher matcher = pattern.matcher(body);
//保存匹配到的hash
int hashNum = 0;
while(matcher.find()) {
if(hashNum >= hashArrays.length){
break;
}
String realHash = matcher.group();
hashArrays[hashNum] = realHash;
hashNum++;
}
}
public void getLuck(){
//记录轮数
int round = 0;
while(round < roundNum) {
//随机取Hash
Random rand = new Random();
//取过的hash记录 被取了的为1,没取的为0
int[] mark = new int[memberNum];
//参与者历遍
for (Participant participant : participants) {
int key = rand.nextInt(memberNum);
//判断该hash是否已经被获取
while (mark[key] != 0) {
key = rand.nextInt(memberNum);
}
//保存hash
participant.setHash(hashArrays[key]);
mark[key] = 1;
}
Collections.sort(participants, new Comparator<Participant>() {
@Override
public int compare(Participant o1, Participant o2) {
Collator collator = Collator.getInstance(Locale.ENGLISH);
String hash1 = o1.getHash()!=null? o1.getHash():"";
String hash2 = o2.getHash()!=null? o2.getHash():"";
return collator.compare(hash1, hash2);
}
});
//计算分数
for (int rank = 1; rank <= participants.size(); rank++) {
Participant participant = participants.get(rank - 1);
//本轮倒数前10的获得激励
if(rank <= 10){
participant.setIncentive(participant.getIncentive() + 1);
}
int score = participant.getScore() + rank;
if(round > 0){
score = score + 1 << participant.getIncentive();
}
participant.setScore(score);
}
//创建临时名单保存结果
List<Participant> participantsTemp = new ArrayList<>();
for(Participant participant :participants){
Participant participantTemp = new Participant();
BeanUtils.copyProperties(participant,participantTemp);
participantsTemp.add(participantTemp);
}
//根据分数排序
Collections.sort(participantsTemp, new Comparator<Participant>() {
@Override
public int compare(Participant o1, Participant o2) {
return o2.getScore() - o1.getScore();
}
});
//保存本轮结果
results[round] = participantsTemp;
//本轮结束
++round;
}
System.out.println("三轮抽奖完成");
}
//剔除本轮中奖人并重置金币数
public void quitLuckDraw(int prizeNum){
//剔除本轮中奖人并重置金币数
List<Participant> newParticipant = new ArrayList<>();
for(Participant participant:participants){
int i = 0;
for(;i < prizeNum ; i++){
if(participant.getName().equals(results[roundNum-1].get(i).getName())){
break;
}
}
if(i < prizeNum){
//说明在获奖名单中
continue;
}else {
//不在则添加到新的抽奖名单
participant.setScore(0);
participant.setHash(null);
newParticipant.add(participant);
}
}
participants = newParticipant;
memberNum = participants.size();
}
}
package com.southsmart.luckdraw.util;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import java.util.Arrays;
/**
* Http工具类
*/
public class HttpUtil {
/**
* 模拟浏览器调用api
* @return
*/
public static HttpEntity getHttpEntity(){
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
return entity;
}
}
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