package com.ruoyi.web.task; import com.alibaba.fastjson2.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.quartz.domain.SysJob; import com.ruoyi.quartz.service.ISysJobService; import com.ruoyi.system.domain.Apply; import com.ruoyi.system.domain.Perform; import com.ruoyi.system.mapper.ApplyMapper; import com.ruoyi.system.mapper.PerformMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 定时任务调度测试 * * @author ruoyi */ @Component("ryTask") public class RyTask { @Autowired private ISysJobService jobService; @Autowired private PerformMapper performMapper; @Autowired private ApplyMapper applyMapper; private static final Logger log = LoggerFactory.getLogger(RyTask.class); /** * 获取wmd * * @return */ private String getWMD(String data) { try { // 密钥(secret key) String secret = "1b9cb6378d959b45714bec49971ade22e6e24e42"; // 要哈希的消息数据 // 创建HMAC算法实例,指定算法为HmacSHA1 Mac hmac = Mac.getInstance("HmacSHA1"); // 创建密钥对象 SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA1"); // 初始化HMAC算法实例 hmac.init(secretKey); // 计算消息的HMAC值,结果是一个字节数组 byte[] hmacBytes = hmac.doFinal(data.getBytes()); // 将字节数组转换为Base64编码的字符串 String base64Hmac = Base64.getEncoder().encodeToString(hmacBytes); // 输出生成的HMAC Base64编码值 // 指定使用的字符编码(如UTF-8) String charset = "UTF-8"; // 进行URL编码 return URLEncoder.encode(base64Hmac, charset); } catch (Exception e) { log.error(e.getMessage()); } return null; } /** * 获取参数 * * @param pid * @param jobId * @throws Exception */ public void get(Long pid, Long jobId) throws Exception { //执行完成停止任务 SysJob job = new SysJob(); job.setJobId(jobId); job.setStatus("1"); jobService.changeStatus(job); //演出 Perform perform = performMapper.selectPerformById(pid); if (perform == null) { throw new Exception("未找到演出"); } //人员 Apply apply = new Apply(); apply.setPerformId(pid); List applies = applyMapper.selectApplyListAllow(apply); if (applies == null || applies.isEmpty()) { throw new Exception("没有参与人员"); } Perform perform1 = new Perform(); String eValue = null; if (perform.getNum() == null || perform.getNum().isEmpty()) { long time = System.currentTimeMillis(); String data = "/notice/v1.0/notice-" + perform.getNotice() + "?fieldSet=noticeV1&appId=be4d79eb8fc7bd008ee82c8ec4ff6fd4&language=zh-cn&os=WEB&platform=WEB&wpf=pc"; String base = "https://global.apis.naver.com/weverse/wevweb"; String wmd = getWMD(data + time); if (wmd == null || wmd.isEmpty()) { throw new Exception("wmd解析失败"); } // 创建HttpClient实例 HttpClient httpClient = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); // 创建HttpRequest String url = base + data + "&wmsgpad=" + time + "&wmd=" + wmd; HttpRequest request = HttpRequest.newBuilder() .uri(new URI(url)) .GET() .header("Authorization", "Bearer " + applies.get(0).getToken()) .header("Origin", "https://weverse.io") .header("Referer", "https://weverse.io/") .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36") .build(); // 发送请求并获取响应 HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); // 检查响应状态码 if (response.statusCode() == 200) { // 打印响应体 String responseBody = response.body(); WeverseData weverseData = JSONObject.parseObject(responseBody, WeverseData.class); if (weverseData == null || weverseData.getButton() == null || weverseData.getButton().getWebLink() == null || weverseData.getButton().getWebLink().getUrl() == null || weverseData.getButton().getWebLink().getUrl().isEmpty()) { throw new Exception("button获取失败"); } URI uri = new URI(weverseData.getButton().getWebLink().getUrl()); String query = uri.getQuery(); String[] params = query.split("&"); Map paramMap = new HashMap<>(); for (String param : params) { String[] keyValue = param.split("="); String key = URLDecoder.decode(keyValue[0], "UTF-8"); String value = URLDecoder.decode(keyValue[1], "UTF-8"); paramMap.put(key, value); } // 获取参数e的值 eValue = paramMap.get("e"); } else { throw new Exception("button请求失败"); } if (eValue == null || eValue.isEmpty()) { throw new Exception("button为空"); } perform1.setNum(eValue); } else { eValue = perform.getNum(); } // 创建HttpClient实例 HttpClient httpClient = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); HttpRequest request = HttpRequest.newBuilder() .uri(new URI("https://faneventapi.weverse.io/api/v1/user/events/" + eValue)) .GET() .header("Authorization", "Bearer " + applies.get(0).getToken()) .header("Origin", "https://weverse.io") .header("Referer", "https://weverse.io/") .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36") .build(); // 发送请求并获取响应 HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { WeverseAgree weverseAgree = JSONObject.parseObject(response.body(), WeverseAgree.class); System.out.println(weverseAgree); if (weverseAgree == null || weverseAgree.getMetadata() == null || weverseAgree.getMetadata().getForm() == null || weverseAgree.getMetadata().getForm().getTerms() == null || weverseAgree.getMetadata().getForm().getTerms().isEmpty()) { throw new Exception("协议未找到"); } StringBuffer sb = new StringBuffer(); weverseAgree.getMetadata().getForm().getTerms().forEach(str -> { sb.append(str.getId()).append(","); }); sb.deleteCharAt(sb.length() - 1); String agree = sb.toString(); if (!agree.isEmpty()) { perform1.setAgree(agree); } log.info(agree); } perform1.setId(pid); performMapper.updatePerform(perform1); } /** * 抢票 * * @param pid */ public void rob(Long pid, Long jobId) throws Exception { log.info("pid:" + pid + " 任务开始了"); //status Perform pStatus1 = new Perform(); pStatus1.setStatus("2"); pStatus1.setId(pid); performMapper.updatePerform(pStatus1); //执行完成停止任务 SysJob job = new SysJob(); job.setJobId(jobId); job.setStatus("1"); jobService.changeStatus(job); //演出 Perform perform = performMapper.selectPerformById(pid); if (perform == null) { throw new Exception("未找到演出"); } //URL String url = String.format("https://faneventapi.weverse.io/api/v1/events/%s/register", perform.getNum()); //人员 Apply apply = new Apply(); apply.setPerformId(pid); List applies = applyMapper.selectApplyListAllow(apply); if (applies == null || applies.isEmpty()) { throw new Exception("没有参与人员"); } if (perform.getAgree() == null || "".equals(perform.getAgree())) { throw new Exception("协议为空"); } //协议 String[] agree = perform.getAgree().split(","); int[] agrees = Arrays.stream(agree).mapToInt(Integer::parseInt).toArray(); List req = new ArrayList<>(); ExecutorService executorService = Executors.newFixedThreadPool(100); HttpClient client = HttpClient.newHttpClient(); // 创建一个请求列表 List> futures = new ArrayList<>(); for (Apply a : applies) { // 准备JSON负载 Map eventData = new HashMap<>(); eventData.put("eventId", Integer.parseInt(perform.getNum())); eventData.put("language", "zh-cn"); Map data = new HashMap<>(); data.put("birthDate", a.getBirthday()); data.put("phoneNumber", a.getCountryCode() + " " + a.getPhoneNum()); data.put("agreedTermIds", agrees); eventData.put("data", data); ObjectMapper mapper = new ObjectMapper(); String jsonPayload = mapper.writeValueAsString(eventData); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .header("Content-Type", "application/json") .header("Authorization", "Bearer " + a.getToken()) .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36") .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) .build(); req.add(new MyReq(request, a.getWeverseEmail())); } Calendar calendar = Calendar.getInstance(); calendar.setTime(perform.getStartTime()); calendar.add(Calendar.HOUR_OF_DAY, -1); long start = calendar.getTimeInMillis(); long now = System.currentTimeMillis(); Thread.sleep(start - now - perform.getDelayTime()); log.info("抢票开始了"); for (MyReq r : req) { log.info("【用户】:" + r.getUser()); // 发起异步请求,但不等待结果 CompletableFuture future2 = client.sendAsync(r.getRequest(), HttpResponse.BodyHandlers.ofString()) .thenApplyAsync(HttpResponse::body, executorService); futures.add(future2); } // 等待所有请求完成 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); // 输出所有请求的响应(可选) for (CompletableFuture future : futures) { try { System.out.println(future.get()); } catch (Exception e) { log.error(e.getMessage()); } } // 关闭线程池 executorService.shutdown(); //status Perform pStatus2 = new Perform(); pStatus2.setStatus("3"); pStatus2.setId(pid); performMapper.updatePerform(pStatus2); for (Apply upApply : applies) { Apply apply1 = new Apply(); apply1.setId(upApply.getId()); apply1.setStatus("6"); applyMapper.updateApply(apply1); } } }