feat(all): 增加简单的任务管理
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package com.lanyuanxiaoyao.leopard.server;
|
||||
|
||||
import com.blinkfox.fenix.EnableFenix;
|
||||
import com.lanyuanxiaoyao.leopard.server.service.StockService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
|
||||
@@ -60,7 +60,7 @@ public class Task extends SimpleEntity {
|
||||
@Column(nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Comment("任务状态")
|
||||
private Status status;
|
||||
private Status status = Status.RUNNING;
|
||||
@Comment("任务开始时间")
|
||||
private LocalDateTime launchedTime;
|
||||
@Comment("任务结束时间")
|
||||
@@ -69,7 +69,6 @@ public class Task extends SimpleEntity {
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum Status implements SimpleEnum {
|
||||
PENDING("待执行"),
|
||||
RUNNING("执行中"),
|
||||
SUCCESS("成功"),
|
||||
FAILURE("失败"),
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
@@ -20,51 +19,57 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
public class StockService extends SimpleServiceSupport<Stock> {
|
||||
private final StockRepository stockRepository;
|
||||
private final TuShareService tuShareService;
|
||||
private final TaskService taskService;
|
||||
|
||||
public StockService(StockRepository repository, TuShareService tuShareService) {
|
||||
public StockService(StockRepository repository, TuShareService tuShareService, TaskService taskService) {
|
||||
super(repository);
|
||||
this.stockRepository = repository;
|
||||
this.tuShareService = tuShareService;
|
||||
this.taskService = taskService;
|
||||
}
|
||||
|
||||
public List<String> findDistinctIndustries() {
|
||||
return stockRepository.findDistinctIndustries();
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
public void refresh() {
|
||||
log.info("开始刷新股票列表");
|
||||
var stocks = list();
|
||||
var stocksMap = stocks.stream().collect(Collectors.toMap(Stock::getCode, stock -> stock));
|
||||
tuShareService.stockList()
|
||||
.data()
|
||||
.items()
|
||||
.forEach(item -> {
|
||||
var code = item.get(0);
|
||||
var name = item.get(1);
|
||||
var fullname = item.get(2);
|
||||
var market = EnumUtil.fromString(Stock.Market.class, item.get(3));
|
||||
var industry = item.get(4);
|
||||
var listed = StrUtil.equals("L", item.get(5));
|
||||
if (stocksMap.containsKey(code)) {
|
||||
var stock = stocksMap.get(code);
|
||||
stock.setName(name);
|
||||
stock.setFullname(fullname);
|
||||
stock.setMarket(market);
|
||||
stock.setIndustry(industry);
|
||||
stock.setListed(listed);
|
||||
} else {
|
||||
var stock = new Stock();
|
||||
stock.setCode(code);
|
||||
stock.setName(name);
|
||||
stock.setFullname(fullname);
|
||||
stock.setMarket(market);
|
||||
stock.setIndustry(industry);
|
||||
stock.setListed(listed);
|
||||
stocks.add(stock);
|
||||
}
|
||||
});
|
||||
repository.saveAll(stocks);
|
||||
log.info("股票列表刷新完成");
|
||||
taskService.startTask(
|
||||
"股票列表刷新",
|
||||
"股票列表刷新",
|
||||
() -> {
|
||||
var stocks = list();
|
||||
var stocksMap = stocks.stream().collect(Collectors.toMap(Stock::getCode, stock -> stock));
|
||||
tuShareService.stockList()
|
||||
.data()
|
||||
.items()
|
||||
.forEach(item -> {
|
||||
var code = item.get(0);
|
||||
var name = item.get(1);
|
||||
var fullname = item.get(2);
|
||||
var market = EnumUtil.fromString(Stock.Market.class, item.get(3));
|
||||
var industry = item.get(4);
|
||||
var listed = StrUtil.equals("L", item.get(5));
|
||||
if (stocksMap.containsKey(code)) {
|
||||
var stock = stocksMap.get(code);
|
||||
stock.setName(name);
|
||||
stock.setFullname(fullname);
|
||||
stock.setMarket(market);
|
||||
stock.setIndustry(industry);
|
||||
stock.setListed(listed);
|
||||
} else {
|
||||
var stock = new Stock();
|
||||
stock.setCode(code);
|
||||
stock.setName(name);
|
||||
stock.setFullname(fullname);
|
||||
stock.setMarket(market);
|
||||
stock.setIndustry(industry);
|
||||
stock.setListed(listed);
|
||||
stocks.add(stock);
|
||||
}
|
||||
});
|
||||
repository.saveOrUpdateAllByNotNullProperties(stocks);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.lanyuanxiaoyao.leopard.server.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.lanyuanxiaoyao.leopard.server.entity.Task;
|
||||
import com.lanyuanxiaoyao.leopard.server.repository.TaskRepository;
|
||||
import com.lanyuanxiaoyao.service.template.repository.SimpleRepository;
|
||||
import com.lanyuanxiaoyao.service.template.service.SimpleServiceSupport;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.function.Supplier;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
@@ -14,9 +17,36 @@ import org.springframework.stereotype.Service;
|
||||
@Slf4j
|
||||
@Service
|
||||
public class TaskService extends SimpleServiceSupport<Task> {
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
|
||||
|
||||
public TaskService(TaskRepository repository) {
|
||||
public TaskService(TaskRepository repository, TransactionTemplate transactionTemplate) {
|
||||
super(repository);
|
||||
this.transactionTemplate = transactionTemplate;
|
||||
}
|
||||
|
||||
public void startTask(String name, String description, Supplier<String> executor) {
|
||||
var task = new Task();
|
||||
task.setName(name);
|
||||
task.setDescription(description);
|
||||
task.setStatus(Task.Status.RUNNING);
|
||||
task.setLaunchedTime(LocalDateTime.now());
|
||||
repository.save(task);
|
||||
transactionTemplate.execute(status -> {
|
||||
try {
|
||||
var result = executor.get();
|
||||
task.setStatus(Task.Status.SUCCESS);
|
||||
if (StrUtil.isNotBlank(result)) {
|
||||
task.setResult(result);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
task.setStatus(Task.Status.FAILURE);
|
||||
task.setError(e.getMessage());
|
||||
status.setRollbackOnly();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
task.setFinishedTime(LocalDateTime.now());
|
||||
repository.save(task);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class TuShareService {
|
||||
public TuShareResponse stockList() {
|
||||
var response = HttpUtil.post(API_URL, buildRequest(
|
||||
"stock_basic",
|
||||
Map.of("list_status", "L"),
|
||||
Map.of("list_status", "D,P,L"),
|
||||
List.of("ts_code", "name", "fullname", "exchange", "industry", "list_status")
|
||||
));
|
||||
var tuShareResponse = mapper.readValue(response, TuShareResponse.class);
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.lanyuanxiaoyao.leopard.server.task;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 任务
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20250829
|
||||
*/
|
||||
public abstract class TaskTemplate {
|
||||
private String name;
|
||||
private String description;
|
||||
|
||||
public abstract Type getType();
|
||||
|
||||
public enum Type {
|
||||
CLASS
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user