手动触发更新逻辑,新增 stockInfo api 接口
This commit is contained in:
8
pom.xml
8
pom.xml
@@ -255,11 +255,11 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
</dependency><!-- https://mvnrepository.com/artifact/com.github.yulichang/mybatis-plus-join-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join-boot-starter</artifactId>
|
||||
<version>1.4.11</version>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join-boot-starter</artifactId>
|
||||
<version>1.5.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package link.at17.mid.tushare.api.common;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.github.yulichang.query.MPJLambdaQueryWrapper;
|
||||
|
||||
import link.at17.mid.tushare.data.models.StockInfo;
|
||||
import link.at17.mid.tushare.data.service.StockInfoService;
|
||||
import link.at17.mid.tushare.enums.ListStatus;
|
||||
import link.at17.mid.tushare.enums.StockMarket;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/common/stockInfo")
|
||||
@Slf4j
|
||||
public class StockInfoController {
|
||||
|
||||
@Autowired
|
||||
StockInfoService stockInfoService;
|
||||
|
||||
@GetMapping("list")
|
||||
private List<StockInfo> list(
|
||||
@Param("listStatus") ListStatus listStatus,
|
||||
@Param("stockMarket") StockMarket stockMarket) {
|
||||
MPJLambdaQueryWrapper<StockInfo> ew = new MPJLambdaQueryWrapper<StockInfo>();
|
||||
ew.setAlias("i");
|
||||
ew.eq(Objects.nonNull(listStatus), StockInfo::getListStatus, listStatus);
|
||||
ew.likeLeft(Objects.nonNull(stockMarket), StockInfo::getTsCode, stockMarket);
|
||||
return stockInfoService.list(ew);
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public class StockCodeUtil {
|
||||
* @return
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public static String toStandardCode(String code) throws UnsupportedOperationException {
|
||||
public static String eastmoneyToTushare(String code) throws UnsupportedOperationException {
|
||||
if (StringUtils.isEmpty(code)) {
|
||||
return code;
|
||||
}
|
||||
|
||||
@@ -178,6 +178,14 @@ public class R<T> implements Serializable {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行带返回值的方法后返回,该返回值会作为 R 的 data。发生异常时,抛出 RException,包裹异常信息
|
||||
* @param supplier 带返回值的方法如 R.judgeThrow(() -> service.getString())
|
||||
* @return
|
||||
* @see {@link #judgeThrow(ThrowingSupplier)}
|
||||
* @see {@link #judge(ThrowingSupplier)}
|
||||
* @see {@link #judge(ThrowingRunnable)}
|
||||
*/
|
||||
public static R<?> judge(ThrowingSupplier<?> supplier) {
|
||||
try {
|
||||
return R.ok(supplier.get());
|
||||
@@ -186,12 +194,49 @@ public class R<T> implements Serializable {
|
||||
throw RException.badRequest(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行无返回值的方法后返回,发生异常时,抛出 RException,包裹异常信息
|
||||
* @param throwingRunnable void 方法如 R.judgeThrow(() -> service.someMethod())
|
||||
* @return
|
||||
* @throws Exception
|
||||
* @see {@link #judgeThrow(ThrowingSupplier)}
|
||||
* @see {@link #judge(ThrowingSupplier)}
|
||||
* @see {@link #judge(ThrowingRunnable)}
|
||||
*/
|
||||
public static R<?> judge(ThrowingRunnable throwingRunnable) {
|
||||
try {
|
||||
throwingRunnable.run();
|
||||
return R.ok();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw RException.badRequest(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行带返回值的方法后返回,该返回值会作为 R 的 data。发生异常时,抛出异常而非返回一个包含异常信息的 R
|
||||
* @param supplier
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static R<?> judgeThrow(ThrowingSupplier<?> supplier) throws Exception {
|
||||
return R.ok(supplier.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行无返回值的方法后返回,发生异常时,抛出异常而非返回一个包含异常信息的 R
|
||||
* @param throwingRunnable void 方法如 R.judgeThrow(() -> service.someMethod())
|
||||
* @return
|
||||
* @throws Exception
|
||||
* @see {@link #judgeThrow(ThrowingSupplier)}
|
||||
* @see {@link #judge(ThrowingSupplier)}
|
||||
*/
|
||||
public static R<?> judgeThrow(ThrowingRunnable throwingRunnable) throws Exception {
|
||||
throwingRunnable.run();
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据布尔值判断返回<br>
|
||||
* true 返回 R.ok(T okData)<br>
|
||||
@@ -214,9 +259,14 @@ public class R<T> implements Serializable {
|
||||
public static R<?> judge(boolean condition, String failedMessage) {
|
||||
return R.judge(condition, null, failedMessage);
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface ThrowingSupplier<T> {
|
||||
T get() throws Exception;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ThrowingRunnable {
|
||||
void run() throws Exception;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.quartz.CronTrigger;
|
||||
import org.quartz.JobBuilder;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
@@ -104,8 +105,8 @@ public class UpdatePlanService extends BaseServiceImpl<UpdatePlanDao, UpdatePlan
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public void rescheduleTask(@Validated UpdatePlan updatePlan) throws SchedulerException {
|
||||
JobKey jobKey = JobKey.jobKey(updatePlan.getId().toString(), JOB_GROUP_NAME);
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(updatePlan.getId().toString(), JOB_GROUP_NAME);
|
||||
JobKey jobKey = getJobKey(updatePlan);
|
||||
TriggerKey triggerKey = getTriggerKey(updatePlan);
|
||||
|
||||
deleteTask(updatePlan.getId());
|
||||
|
||||
@@ -139,6 +140,33 @@ public class UpdatePlanService extends BaseServiceImpl<UpdatePlanDao, UpdatePlan
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即触发任务
|
||||
* @param updatePlan
|
||||
*/
|
||||
public void triggerTask(@Valid UpdatePlan updatePlan) throws SchedulerException {
|
||||
JobKey jobKey = getJobKey(updatePlan);
|
||||
for (JobExecutionContext context : scheduler.getCurrentlyExecutingJobs()) {
|
||||
if (context.getJobDetail().getKey().equals(jobKey)) {
|
||||
throw new IllegalStateException("已有同名任务在运行中");
|
||||
}
|
||||
}
|
||||
if (scheduler.getJobDetail(jobKey) == null) {
|
||||
throw new SchedulerException("指定的任务不存在");
|
||||
}
|
||||
scheduler.triggerJob(jobKey);
|
||||
}
|
||||
|
||||
public void interruptTask(@Valid UpdatePlan updatePlan) throws SchedulerException {
|
||||
JobKey jobKey = getJobKey(updatePlan);
|
||||
for (JobExecutionContext context : scheduler.getCurrentlyExecutingJobs()) {
|
||||
if (context.getJobDetail().getKey().equals(jobKey)) {
|
||||
scheduler.interrupt(jobKey);
|
||||
}
|
||||
}
|
||||
throw new SchedulerException("任务未在执行");
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行方法
|
||||
* @param updatePlan
|
||||
@@ -158,5 +186,22 @@ public class UpdatePlanService extends BaseServiceImpl<UpdatePlanDao, UpdatePlan
|
||||
public List<UpdatePlan> list() {
|
||||
return list(new LambdaQueryWrapper<UpdatePlan>().orderByAsc(UpdatePlan::getId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 UpdatePlan 生成 JobKey
|
||||
* @param updatePlan
|
||||
* @return
|
||||
*/
|
||||
private JobKey getJobKey(UpdatePlan updatePlan) {
|
||||
return JobKey.jobKey(updatePlan.getId().toString(), JOB_GROUP_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 UpdatePlan 生成 TriggerKey
|
||||
* @param updatePlan
|
||||
* @return
|
||||
*/
|
||||
private TriggerKey getTriggerKey(UpdatePlan updatePlan) {
|
||||
return TriggerKey.triggerKey(updatePlan.getId().toString(), JOB_GROUP_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@ package link.at17.mid.tushare.task.job;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.InterruptableJob;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.quartz.UnableToInterruptJobException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -17,7 +20,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Component
|
||||
@Slf4j
|
||||
@Validated
|
||||
public class UpdatePlanJob implements Job {
|
||||
@DisallowConcurrentExecution
|
||||
public class UpdatePlanJob implements Job, InterruptableJob {
|
||||
|
||||
@Autowired
|
||||
private UpdatePlanService updatePlanService;
|
||||
@@ -58,4 +62,10 @@ public class UpdatePlanJob implements Job {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interrupt() throws UnableToInterruptJobException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -95,11 +94,11 @@ public class UpdatePlanController extends BaseController {
|
||||
return R.judge(updatePlanService.update(new UpdateWrapper<UpdatePlan>().eq(idField, id).set(dbField, value)));
|
||||
}
|
||||
|
||||
@GetMapping("/execute")
|
||||
@PostMapping("/manualTrigger")
|
||||
@ResponseBody
|
||||
public void execute(Integer id) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, InvocationTargetException {
|
||||
public R<?> manualTrigger(Integer id) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, InvocationTargetException {
|
||||
UpdatePlan updatePlan = updatePlanService.getById(id);
|
||||
updatePlanService.execute(updatePlan);
|
||||
return R.judge(() -> updatePlanService.triggerTask(updatePlan));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -97,6 +97,8 @@ td[handler] {cursor: move}
|
||||
</script>
|
||||
<script type="text/html" id="barDemo">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
|
||||
<a class="layui-btn layui-btn-xs" lay-event="trigger">触发</a>
|
||||
<a class="layui-btn layui-btn-xs" lay-event="interrupt">停止</a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
|
||||
</script>
|
||||
</div>
|
||||
@@ -147,7 +149,7 @@ td[handler] {cursor: move}
|
||||
d.valid ? '<font color="green">有效</font>' : '<font color="red">无效</font>' +
|
||||
'</span>';
|
||||
}}
|
||||
,{fixed: 'right', title:'操作', width: 125, minWidth: 125, toolbar: '#barDemo'}
|
||||
,{fixed: 'right', title:'操作', minWidth: 125, toolbar: '#barDemo'}
|
||||
]]
|
||||
,done: function(){
|
||||
var id = this.id;
|
||||
@@ -368,13 +370,29 @@ td[handler] {cursor: move}
|
||||
table.on('tool(plan-table)', function(obj){ // 双击 toolDouble
|
||||
var data = obj.data;
|
||||
//console.log(obj)
|
||||
if(obj.event === 'del'){
|
||||
if(obj.event === 'edit'){
|
||||
openNewForm(obj.data.id)
|
||||
}
|
||||
else if(obj.event === 'del'){
|
||||
layer.confirm('真的删除行么', function(index){
|
||||
obj.del();
|
||||
layer.close(index);
|
||||
});
|
||||
} else if(obj.event === 'edit'){
|
||||
openNewForm(obj.data.id)
|
||||
}
|
||||
else if(obj.event === 'trigger'){
|
||||
var load = layui.layer.load(4);
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '/admin/manage/reviews/plans/manualTrigger',
|
||||
data: {id: obj.data.id},
|
||||
success: res => {
|
||||
layer.msg('操作成功', {time: 1000});
|
||||
},
|
||||
error: res => {
|
||||
layer.msg(res.responseJSON.message || '操作失败', {time: 2000});
|
||||
},
|
||||
complete: () => {if (load) layui.layer.close(load)}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user