4 Commits

Author SHA1 Message Date
Xiang
03f98fbe1e fix:返回值 2026-02-11 15:41:59 +08:00
Xiang
67e67a911e Merge remote-tracking branch 'origin/master'
# Conflicts:
#	script/src/main/java/com/xiang/xservice/application/script/xb/schedule/xb/FundCountJob.java
#	script/src/main/java/com/xiang/xservice/application/script/xb/schedule/xb/FundInfoQueryJob.java
#	script/src/main/java/com/xiang/xservice/application/script/xb/schedule/xb/FundMsgReportJob.java
2026-02-11 09:00:57 +08:00
Xiang
d62d788e81 fix:清理代码 2026-02-11 09:00:12 +08:00
xiang
c506a850c3 feat:基金定时任务 2026-02-07 20:12:45 +08:00
12 changed files with 24 additions and 478 deletions

View File

@@ -124,7 +124,7 @@
<dependency> <dependency>
<groupId>com.xiang.starter</groupId> <groupId>com.xiang.starter</groupId>
<artifactId>xmc-common</artifactId> <artifactId>xmc-common</artifactId>
<version>1.0</version> <version>1.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.xiang.starter</groupId> <groupId>com.xiang.starter</groupId>
@@ -134,7 +134,7 @@
<dependency> <dependency>
<groupId>com.xiang.starter</groupId> <groupId>com.xiang.starter</groupId>
<artifactId>xmc-http-starter</artifactId> <artifactId>xmc-http-starter</artifactId>
<version>2.0-SNAPSHOT</version> <version>2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.xiang.starter</groupId> <groupId>com.xiang.starter</groupId>

View File

@@ -31,13 +31,13 @@ public class IndexController {
@GetMapping("/index") @GetMapping("/index")
public Result<String> index() { public Result<String> index() {
String msg = "已激活环境:" + env + "web端口启用" + port + "使用datasource:" + url; String msg = "已激活环境:" + env + "web端口启用" + port + "使用datasource:" + url;
return Result.success(msg); return Result.data(msg);
} }
@GetMapping("/redisTest") @GetMapping("/redisTest")
private Result<String> redisTest() { private Result<String> redisTest() {
redisTemplate.opsForValue().set("2222", "231"); redisTemplate.opsForValue().set("2222", "231");
return Result.success("redis获取到key为test的值为" + redisTemplate.opsForValue().get("2222")); return Result.data("redis获取到key为test的值为" + redisTemplate.opsForValue().get("2222"));
} }
} }

View File

@@ -8,6 +8,8 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/** /**
* 模板管理控制器 * 模板管理控制器
* *
@@ -21,8 +23,8 @@ public class TemplateController {
private final TemplateService templateService; private final TemplateService templateService;
@PostMapping("/all") @PostMapping("/all")
public Result<TemplateList> getAllTemplates() throws Exception { public Result<List<TemplateList>> getAllTemplates() throws Exception {
return Result.success(templateService.getAllTemplates()); return Result.data(templateService.getAllTemplates());
} }
} }

View File

@@ -50,7 +50,7 @@ public class CodeGenServiceImpl implements CodeGenService {
// 3. generate the code by freemarker templates with parameters . // 3. generate the code by freemarker templates with parameters .
// Freemarker根据参数和模板生成代码 // Freemarker根据参数和模板生成代码
Map<String, String> result = getResultByParams(paramInfo.getOptions()); Map<String, String> result = getResultByParams(paramInfo.getOptions());
return Result.success(result); return Result.data(result);
} catch (Exception e) { } catch (Exception e) {
log.error("代码生成失败", e); log.error("代码生成失败", e);
return Result.error("代码生成失败: " + e.getMessage()); return Result.error("代码生成失败: " + e.getMessage());

View File

@@ -37,7 +37,7 @@ public class DynamicDomainController {
log.error("获取公网IP失败 time:{}", LocalDateTime.now(), e); log.error("获取公网IP失败 time:{}", LocalDateTime.now(), e);
return Result.error("获取公网IP失败"); return Result.error("获取公网IP失败");
} }
return Result.success("获取公网IP成功", publicIp); return Result.data(publicIp);
} }
@PostMapping("/ddns") @PostMapping("/ddns")
@@ -46,7 +46,7 @@ public class DynamicDomainController {
String publicIp = IpUtils.getPublicIp(); String publicIp = IpUtils.getPublicIp();
log.info("获取公网IP成功time:{}, ip:{}", LocalDateTime.now(), publicIp); log.info("获取公网IP成功time:{}, ip:{}", LocalDateTime.now(), publicIp);
IDomainService.dynamicDomainAnalysis(publicIp); IDomainService.dynamicDomainAnalysis(publicIp);
return Result.success("获取公网IP成功"); return Result.data("获取公网IP成功");
} catch (Exception e) { } catch (Exception e) {
log.error("获取公网IP失败 time:{}", LocalDateTime.now(), e); log.error("获取公网IP失败 time:{}", LocalDateTime.now(), e);
return Result.error("获取公网IP失败"); return Result.error("获取公网IP失败");

View File

@@ -102,6 +102,6 @@ public class FwdDataController {
} }
} }
} }
return Result.success("success"); return Result.data("success");
} }
} }

View File

@@ -36,37 +36,37 @@ public class FwdOuterController {
@GetMapping("/getShowProjects") @GetMapping("/getShowProjects")
public Result<ProjectsResp> getShowProjects() { public Result<ProjectsResp> getShowProjects() {
ProjectsResp showProjectsFromHttp = performServiceHttp.getShowProjectsFromHttp(new BaseRequest()); ProjectsResp showProjectsFromHttp = performServiceHttp.getShowProjectsFromHttp(new BaseRequest());
return Result.success("查询成功!", showProjectsFromHttp); return Result.data(showProjectsFromHttp);
} }
@GetMapping("/getProjectInfo/{id}") @GetMapping("/getProjectInfo/{id}")
public Result<Perform> getProjectInfo(@PathVariable("id") Long id) { public Result<Perform> getProjectInfo(@PathVariable("id") Long id) {
String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken(); String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken();
Perform performsByProjectIdFromHttp = performServiceHttp.getPerformsByProjectIdFromHttp(id, token); Perform performsByProjectIdFromHttp = performServiceHttp.getPerformsByProjectIdFromHttp(id, token);
return Result.success("查询成功!", performsByProjectIdFromHttp); return Result.data(performsByProjectIdFromHttp);
} }
@GetMapping("/getPerformsByProjectIdFromHttp/{id}") @GetMapping("/getPerformsByProjectIdFromHttp/{id}")
public Result<Perform> getPerformsByProjectIdFromHttp(@PathVariable("id") Long id) { public Result<Perform> getPerformsByProjectIdFromHttp(@PathVariable("id") Long id) {
String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken(); String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken();
Perform performsByProjectIdFromHttp = performServiceHttp.getPerformsByProjectIdFromHttp(id, token); Perform performsByProjectIdFromHttp = performServiceHttp.getPerformsByProjectIdFromHttp(id, token);
return Result.success("查询成功!", performsByProjectIdFromHttp); return Result.data(performsByProjectIdFromHttp);
} }
@PostMapping("/createOrder") @PostMapping("/createOrder")
public Result<String> createOrder(Long projectId) throws Exception { public Result<String> createOrder(Long projectId) throws Exception {
String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken(); String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken();
if (performService.createProjectOrder(projectId, FREQUENT_IDS, token)) { if (performService.createProjectOrder(projectId, FREQUENT_IDS, token)) {
return Result.success("下单成功!"); return Result.data("下单成功!");
} }
return Result.error("下单失败!"); return Result.error("下单失败!");
} }
@GetMapping("/getSeatPlanStatus") @GetMapping("/getSeatPlanStatus")
public Result<SeatPlanStatus> getSeatPlanStatu (@RequestParam List<Long> ids) { public Result<List<SeatPlanStatus>> getSeatPlanStatu (@RequestParam List<Long> ids) {
String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken(); String token = fwdUserConfigMapper.getAvailableUser().get(0).getToken();
List<SeatPlanStatus> seatPlanStatusFromHttp = performServiceHttp.getSeatPlanStatusFromHttp(ids, token); List<SeatPlanStatus> seatPlanStatusFromHttp = performServiceHttp.getSeatPlanStatusFromHttp(ids, token);
return Result.success("查询成功!", seatPlanStatusFromHttp); return Result.data(seatPlanStatusFromHttp);
} }
} }

View File

@@ -1,7 +1,5 @@
package com.xiang.xservice.application.script.xb.controller; package com.xiang.xservice.application.script.xb.controller;
import com.google.common.collect.Lists;
import com.xiang.xservice.basic.common.resp.Result;
import com.xiang.xservice.application.script.xb.entity.pojo.xb.XbFundList; import com.xiang.xservice.application.script.xb.entity.pojo.xb.XbFundList;
import com.xiang.xservice.application.script.xb.entity.request.xb.fund.QueryFundInfoReq; import com.xiang.xservice.application.script.xb.entity.request.xb.fund.QueryFundInfoReq;
import com.xiang.xservice.application.script.xb.entity.request.xb.fund.QueryFundListReq; import com.xiang.xservice.application.script.xb.entity.request.xb.fund.QueryFundListReq;
@@ -9,6 +7,7 @@ import com.xiang.xservice.application.script.xb.entity.request.xb.fund.QueryXbFu
import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundInfo; import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundInfo;
import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundList; import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundList;
import com.xiang.xservice.application.script.xb.service.FundService; import com.xiang.xservice.application.script.xb.service.FundService;
import com.xiang.xservice.basic.common.resp.Result;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@@ -31,28 +30,28 @@ public class XBController {
private final FundService fundService; private final FundService fundService;
@PostMapping("/queryFundList") @PostMapping("/queryFundList")
public Result<XbFundList> queryFundList(@RequestBody QueryXbFundListReq req) { public Result<List<XbFundList>> queryFundList(@RequestBody QueryXbFundListReq req) {
List<XbFundList> result = fundService.queryFundList(req.getType()); List<XbFundList> result = fundService.queryFundList(req.getType());
if (CollectionUtils.isEmpty(result)) { if (CollectionUtils.isEmpty(result)) {
return Result.error("基金列表信息为空!"); return Result.error("基金列表信息为空!");
} }
return Result.success("success", result); return Result.data(result);
} }
@PostMapping("/queryList") @PostMapping("/queryList")
public Result<FundList> queryList(@RequestBody QueryFundListReq req) { public Result<List<FundList>> queryList(@RequestBody QueryFundListReq req) {
List<FundList> result = fundService.queryTodayList(req.getDate(), req.getDataResources(), req.getDataSourceSwitch(), req.getCodeArr()); List<FundList> result = fundService.queryTodayList(req.getDate(), req.getDataResources(), req.getDataSourceSwitch(), req.getCodeArr());
if (CollectionUtils.isEmpty(result)) { if (CollectionUtils.isEmpty(result)) {
return Result.error("基金列表信息为空!"); return Result.error("基金列表信息为空!");
} }
return Result.success("success", result); return Result.data(result);
} }
@PostMapping("/queryFundInfo") @PostMapping("/queryFundInfo")
public Result<FundInfo> queryFundInfo(@RequestBody QueryFundInfoReq req) { public Result<FundInfo> queryFundInfo(@RequestBody QueryFundInfoReq req) {
FundInfo fundInfo = fundService.queryFundInfo(req.getCode()); FundInfo fundInfo = fundService.queryFundInfo(req.getCode());
if (Objects.nonNull(fundInfo)) { if (Objects.nonNull(fundInfo)) {
return Result.success("success", Lists.newArrayList(fundInfo)); return Result.data(fundInfo);
} }
return Result.error("查询基金信息为空!"); return Result.error("查询基金信息为空!");
} }

View File

@@ -1,105 +0,0 @@
package com.xiang.xservice.application.script.xb.schedule.xb;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.xiang.xservice.application.script.xb.entity.pojo.xb.XbFundCount;
import com.xiang.xservice.application.script.xb.entity.pojo.xb.XbFundList;
import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundList;
import com.xiang.xservice.application.script.xb.service.FundService;
import com.xiang.xservice.basic.utils.DateUtils;
import com.xiang.xservice.common.service.dingTalk.StockDingTalkFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @Author: xiang
* @Date: 2025-05-21 13:59
*/
@Component
@RequiredArgsConstructor
@Slf4j
@RestController
public class FundCountJob {
private final FundService fundService;
private final StockDingTalkFactory dingTalkService;
@Scheduled(cron = "0 0 22 * * ?")
public void countFundJob() {
// 周六周日过滤
if (Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SATURDAY) ||
Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SUNDAY)) {
return;
}
log.info("==========================[基金统计] 基金统计定时任务启动!==========================");
List<XbFundList> lists = fundService.queryFundList();
if (CollectionUtils.isEmpty(lists)) {
return;
}
List<XbFundCount> counts = Lists.newCopyOnWriteArrayList();
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
lists.parallelStream().forEach(xbFundList -> {
List<FundList> fund = fundService.queryTodayList(date, "2", Boolean.TRUE, Collections.singletonList(xbFundList.getCode()));
if (CollectionUtils.isNotEmpty(fund)) {
XbFundCount xbFundCount = new XbFundCount();
xbFundCount.setLId(xbFundList.getId());
xbFundCount.setCode(xbFundList.getCode());
xbFundCount.setName(xbFundList.getName());
xbFundCount.setChange(fund.get(0).getChange().multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP));
xbFundCount.setUpdateTime(LocalDateTime.now());
counts.add(xbFundCount);
}
});
if (CollectionUtils.isNotEmpty(counts)) {
log.info("[基金统计] 基金统计记录,需要插入的数据:{}", JSONObject.toJSONString(counts));
fundService.addCounts(counts);
}
log.info("==========================[基金统计] 基金统计定时任务结束!==========================");
}
@Scheduled(cron = "0 40 14 * * ? ")
public void countFundInWeek() throws Exception {
if (DateUtils.validWeekTime()) return;
log.info("==========================[基金统计] 基金本周涨跌幅消息发送定时任务启动!==========================");
List<XbFundCount> xbFundCounts = fundService.queryFundCountInWeek();
if (CollectionUtils.isEmpty(xbFundCounts)) {
return;
}
StringBuilder sb = new StringBuilder();
Map<String, List<XbFundCount>> map = xbFundCounts.stream().collect(Collectors.groupingBy(XbFundCount::getCode));
map.forEach((k, v) -> {
List<XbFundCount> fundCounts = map.get(k);
if (CollectionUtils.isEmpty(fundCounts)) {
return;
}
List<BigDecimal> decimals = fundCounts.stream().map(XbFundCount::getChange).collect(Collectors.toList());
BigDecimal sum = BigDecimal.ZERO;
for (BigDecimal decimal : decimals) {
sum = sum.add(decimal);
}
BigDecimal avg = sum.divide(BigDecimal.valueOf(decimals.size()), 2, RoundingMode.HALF_UP);
sb.append("").append(fundCounts.get(0).getName()).append("】本周平均涨跌幅为:").append(avg).append("\n");
});
if (StringUtils.isNotBlank(sb)) {
dingTalkService.sendMsg(sb.toString());
}
log.info("==========================[基金统计] 基金本周涨跌幅消息发送定时任务结束!==========================");
}
}

View File

@@ -1,134 +0,0 @@
package com.xiang.xservice.application.script.xb.schedule.xb;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.xiang.xservice.application.script.xb.entity.pojo.xb.FundMessage;
import com.xiang.xservice.application.script.xb.entity.pojo.xb.XbFundList;
import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundInfo;
import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundList;
import com.xiang.xservice.application.script.xb.repository.XBFundMapper;
import com.xiang.xservice.application.script.xb.service.FundService;
import com.xiang.xservice.basic.config.MyThreadFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @Author: xiang
* @Date: 2025-05-14 17:15
*/
@Component
@RequiredArgsConstructor
@Slf4j
public class FundInfoQueryJob {
private final FundService fundService;
private final XBFundMapper xbFundMapper;
private final ExecutorService es =
new ThreadPoolExecutor(
10,
20,
1000,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(),
new MyThreadFactory("xb-query-thread", Boolean.TRUE),
new ThreadPoolExecutor.AbortPolicy());
@Value("${xiaobei.codeArr}")
private String codeArr;
/**
* 基金每分钟涨幅记录
*/
@Scheduled(cron = "0 0/1 9,10,11,13,14 * * ?")
public void queryFundInfoInMinJob() {
// 周六周日过滤
if (Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SATURDAY) ||
Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SUNDAY)) {
return;
}
List<FundMessage> fundMessageList = queryFund(null);
if (CollectionUtils.isEmpty(fundMessageList)) {
return;
}
List<CompletableFuture> futures = Lists.newArrayList();
List<com.xiang.xservice.application.script.xb.entity.pojo.xb.FundInfo> fundInfoList = Lists.newCopyOnWriteArrayList();
fundMessageList.parallelStream().forEach(fundMessage -> {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
FundInfo fundInfo = fundService.queryFundInfo(fundMessage.getCode());
com.xiang.xservice.application.script.xb.entity.pojo.xb.FundInfo info = com.xiang.xservice.application.script.xb.entity.pojo.xb.FundInfo.builder()
.code(fundMessage.getCode())
.name(fundInfo.getName())
.change(fundMessage.getChange().multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toString())
.updateTime(getTimeFromStr(fundMessage.getDate(), fundMessage.getUpdate()))
.build();
fundInfoList.add(info);
}, es);
futures.add(future);
});
CompletableFuture[] futureArr = futures
.toArray(futures.toArray(new CompletableFuture[0]));
CompletableFuture.allOf(futureArr).join();
if (CollectionUtils.isNotEmpty(fundInfoList)) {
log.info("[基金查询] 每分钟基金涨跌幅查询记录,需要插入的数据:{}", JSONObject.toJSONString(fundInfoList));
xbFundMapper.batchSave(fundInfoList);
}
}
private List<FundMessage> queryFund(Integer type) {
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
List<String> code = Lists.newArrayList();
List<XbFundList> lists = xbFundMapper.queryFundList(type);
if (CollectionUtils.isEmpty(lists)) {
if (Objects.equals(type, 1)) {
code = Arrays.stream(codeArr.split(", ")).collect(Collectors.toList());
}
return Lists.newArrayList();
} else {
code = lists.stream().map(XbFundList::getCode).collect(Collectors.toList());
}
List<FundList> fundLists = fundService.queryTodayList(date, "2", Boolean.TRUE, code);
if (CollectionUtils.isEmpty(fundLists)) {
return Lists.newArrayList();
}
List<FundMessage> result = Lists.newCopyOnWriteArrayList();
fundLists.parallelStream().forEach(fundList -> {
FundInfo fundInfo = fundService.queryFundInfo(fundList.getCode());
if (Objects.nonNull(fundInfo)) {
FundMessage fund = FundMessage.builder().name(fundInfo.getName()).date(fundList.getDate())
.code(fundList.getCode()).change(fundList.getChange()).update(fundList.getUpdate()).build();
result.add(fund);
}
});
return result;
}
private LocalDateTime getTimeFromStr(String date, String time) {
String dateTimeStr = date + " " + time;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.parse(dateTimeStr, formatter);
}
}

View File

@@ -1,144 +0,0 @@
package com.xiang.xservice.application.script.xb.schedule.xb;
import com.alibaba.fastjson.JSON;
import com.xiang.xservice.application.script.xb.entity.pojo.xb.XbFundList;
import com.xiang.xservice.application.script.xb.entity.response.xbyj.fund.FundList;
import com.xiang.xservice.application.script.xb.service.FundService;
import com.xiang.xservice.common.service.dingTalk.StockDingTalkFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Author: xiang
* @Date: 2025-07-31 18:10
*/
@Component
@Slf4j
@RestController
@RequiredArgsConstructor
public class FundMsgReportJob {
private final FundService fundService;
private final StockDingTalkFactory dingTalkService;
private static final Integer TYPE_A = 1;
private static final Integer TYPE_M = 3;
private static final Integer TYPE_G = 2;
@Scheduled(cron = "0 1,31 9,10,11,13,14 * * ?")
@PostMapping("/asdasda")
public void fundReport4A() {
log.info("===========A股基金变化通知===========");
// 周六周日过滤
if (Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SATURDAY) ||
Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SUNDAY)) {
log.info("当前时间为:{}", LocalDateTime.now());
return;
}
List<XbFundList> fundLists = fundService.queryFundList(TYPE_A);
if (CollectionUtils.isEmpty(fundLists)) {
log.info("查询配置的A股信息为空");
return;
}
Map<String, XbFundList> fundMap = fundLists.stream().collect(Collectors.toMap(XbFundList::getCode, Function.identity(), (a, b) -> a));
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
List<FundList> funds = fundService.queryTodayList(date, "2", Boolean.TRUE, new ArrayList<>(fundMap.keySet()));
if (CollectionUtils.isEmpty(funds)) {
log.info("http请求查询基金信息为空");
return;
}
log.info("http查询基金信息:{}", JSON.toJSONString(funds));
StringBuilder msg = new StringBuilder(date).append("===》A股基金变化通知:\n");
buildMsg(funds, fundMap, msg);
dingTalkService.sendMsg(msg.toString());
}
@Scheduled(cron = "0 1,31 9,10,11,13,14,15 * * ?")
public void fundReport4G() {
log.info("===========港股基金变化通知!===========");
// 周六周日过滤
if (Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SATURDAY) ||
Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SUNDAY)) {
log.info("当前时间为:{}", LocalDateTime.now());
return;
}
List<XbFundList> fundLists = fundService.queryFundList(TYPE_G);
if (CollectionUtils.isEmpty(fundLists)) {
log.info("查询配置的港股信息为空");
return;
}
Map<String, XbFundList> fundMap = fundLists.stream().collect(Collectors.toMap(XbFundList::getCode, Function.identity(), (a, b) -> a));
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
List<FundList> funds = fundService.queryTodayList(date, "2", Boolean.TRUE, new ArrayList<>(fundMap.keySet()));
if (CollectionUtils.isEmpty(funds)) {
log.info("http请求查询基金信息为空");
return;
}
log.info("http查询港股基金信息:{}", JSON.toJSONString(funds));
StringBuilder msg = new StringBuilder(date).append("===》港股基金变化通知:\n");
buildMsg(funds, fundMap, msg);
dingTalkService.sendMsg(msg.toString());
}
@Scheduled(cron = "0 0 9 * * ?")
public void fundReport4M() {
log.info("===========美股基金变化通知!===========");
// 周六周日过滤
if (Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SATURDAY) ||
Objects.equals(LocalDateTime.now().getDayOfWeek(), DayOfWeek.SUNDAY)) {
log.info("当前时间为:{}", LocalDateTime.now());
return;
}
List<XbFundList> fundLists = fundService.queryFundList(TYPE_M);
if (CollectionUtils.isEmpty(fundLists)) {
log.info("查询配置的美股信息为空");
return;
}
Map<String, XbFundList> fundMap = fundLists.stream().collect(Collectors.toMap(XbFundList::getCode, Function.identity(), (a, b) -> a));
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
List<FundList> funds = fundService.queryTodayList(date, "2", Boolean.TRUE, new ArrayList<>(fundMap.keySet()));
if (CollectionUtils.isEmpty(funds)) {
log.info("http请求查询基金信息为空");
return;
}
log.info("http查询美股基金信息:{}", JSON.toJSONString(funds));
StringBuilder msg = new StringBuilder(date).append("===》美股基金变化通知:\n");
buildMsg(funds, fundMap, msg);
dingTalkService.sendMsg(msg.toString());
}
private static void buildMsg(List<FundList> funds, Map<String, XbFundList> fundMap, StringBuilder msg) {
funds = funds.stream().sorted(Comparator.comparing(FundList::getChange).reversed())
.collect(Collectors.toList());
for (FundList fund : funds) {
if (fundMap.containsKey(fund.getCode())) {
XbFundList fundList = fundMap.get(fund.getCode());
msg.append("基金名称:")
.append(fundList.getName())
.append("涨跌幅:")
.append(fund.getChange()
.multiply(new BigDecimal("100"))
.setScale(2, RoundingMode.HALF_UP))
.append("\n");
}
}
}
}

View File

@@ -1,72 +0,0 @@
package com.xiang.xservice.common.schedule;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.xiang.xmc.service.cache.service.IRedisService;
import com.xiang.xservice.basic.utils.DateUtils;
import com.xiang.xservice.basic.utils.HttpUtils;
import com.xiang.xservice.common.entity.DayResult;
import com.xiang.xservice.common.enums.RedisConstant;
import com.xiang.xservice.common.enums.UrlConstant;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.HashMap;
import java.util.Objects;
/**
* @Author: xiang
* @Date: 2025-10-04 10:09
*/
@Component
@RequiredArgsConstructor
@RestController
public class HolidayQueryJob {
private final IRedisService redisService;
private static final String API_KEY = "d20db0ca13e151ca7323d849d8efc6db";
@Scheduled(cron = "0 0 0 1 1/1 ?")
@PostMapping("/queryHolidayInfoJob")
public void queryHolidayInfoJob() {
YearMonth now = YearMonth.now(); // 当前年月
LocalDate start = now.atDay(1);
LocalDate end = now.atEndOfMonth();
for (LocalDate d = start; !d.isAfter(end); d = d.plusDays(1)) {
try {
String date = DateUtils.getDateFromDate(d);
HashMap<String, String> paramMap = Maps.newHashMap();
paramMap.put("key", API_KEY);
paramMap.put("date", date);
paramMap.put("detail", "");
HashMap<String, String> headers = Maps.newHashMap();
headers.put("Content-Type", "application/x-www-form-urlencoded");
String resp = HttpUtils.doGet(UrlConstant.HOLIDAY_QUERY_URL, headers, paramMap);
if (StringUtils.isNotBlank(resp)) {
JSONObject jsonObject = JSON.parseObject(resp);
String reason = (String) jsonObject.get("reason");
if (!StringUtils.equals(reason, "success")) {
continue;
}
JSONObject result = jsonObject.getJSONObject("result");
DayResult dayResult = JSON.toJavaObject(result, DayResult.class);
if (Objects.isNull(dayResult)) {
continue;
}
redisService.hSet(RedisConstant.DAY_INFO_PREFIX_KEY + RedisConstant.getDate4Key(), date, result);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}