feat: 增加日线数据显示
This commit is contained in:
1
.idea/data_source_mapping.xml
generated
1
.idea/data_source_mapping.xml
generated
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourcePerFileMappings">
|
||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/63824900-a456-4883-8de4-8f436cd00c71/console.sql" value="63824900-a456-4883-8de4-8f436cd00c71" />
|
||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/f7d817dc-8c9c-479f-b469-583df17cb013/console.sql" value="f7d817dc-8c9c-479f-b469-583df17cb013" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -7,6 +7,8 @@ import com.lanyuanxiaoyao.leopard.server.service.StockService;
|
||||
import com.lanyuanxiaoyao.service.template.controller.GlobalResponse;
|
||||
import com.lanyuanxiaoyao.service.template.controller.SimpleControllerSupport;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -94,11 +96,29 @@ public class StockController extends SimpleControllerSupport<Stock, Void, StockC
|
||||
@GetMapping("finance/{id}/{field}")
|
||||
public GlobalResponse<Map<String, Object>> financeCharts(@PathVariable("id") Long id, @PathVariable("field") String field) {
|
||||
var data = stockService.findFinanceIndicatorRecent(id, 5);
|
||||
return GlobalResponse.responseDetailData(
|
||||
data.stream()
|
||||
.map(item -> BeanUtil.getFieldValue(item, field))
|
||||
.toList()
|
||||
);
|
||||
var xList = new ArrayList<Integer>();
|
||||
var yList = new ArrayList<Object>();
|
||||
for (var indicator : data) {
|
||||
xList.add(indicator.getYear());
|
||||
yList.add(BeanUtil.getFieldValue(indicator, field));
|
||||
}
|
||||
return GlobalResponse.responseMapData(Map.of(
|
||||
"xList", xList, "yList", yList
|
||||
));
|
||||
}
|
||||
|
||||
@GetMapping("daily/{id}")
|
||||
public GlobalResponse<Map<String, Object>> dailyCharts(@PathVariable("id") Long id) {
|
||||
var data = stockService.findDailyRecent(id, 100);
|
||||
var xList = new ArrayList<String>();
|
||||
var yList = new ArrayList<List<Double>>();
|
||||
for (var daily : data) {
|
||||
xList.add(daily.getTradeDate().toString());
|
||||
yList.add(List.of(daily.getOpen(), daily.getClose(), daily.getLow(), daily.getHigh()));
|
||||
}
|
||||
return GlobalResponse.responseMapData(Map.of(
|
||||
"xList", xList, "yList", yList
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.lanyuanxiaoyao.leopard.server.service;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Daily;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
|
||||
import com.lanyuanxiaoyao.service.template.service.SimpleServiceSupport;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DailyService extends SimpleServiceSupport<Daily> {
|
||||
public DailyService(DailyRepository repository) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
package com.lanyuanxiaoyao.leopard.server.service;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Daily;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Daily_;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.FinanceIndicator_;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.QDaily;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.QFinanceIndicator;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.DailyRepository;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.FinanceIndicatorRepository;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
|
||||
import com.lanyuanxiaoyao.service.template.service.SimpleServiceSupport;
|
||||
@@ -23,12 +27,13 @@ import org.springframework.stereotype.Service;
|
||||
public class StockService extends SimpleServiceSupport<Stock> {
|
||||
private final StockRepository stockRepository;
|
||||
private final FinanceIndicatorRepository financeIndicatorRepository;
|
||||
private final DailyRepository dailyRepository;
|
||||
|
||||
|
||||
public StockService(StockRepository repository, FinanceIndicatorRepository financeIndicatorRepository) {
|
||||
public StockService(StockRepository repository, FinanceIndicatorRepository financeIndicatorRepository, DailyRepository dailyRepository) {
|
||||
super(repository);
|
||||
this.stockRepository = repository;
|
||||
this.financeIndicatorRepository = financeIndicatorRepository;
|
||||
this.dailyRepository = dailyRepository;
|
||||
}
|
||||
|
||||
public Optional<FinanceIndicator> findFinanceIndicator(Long stockId, Integer year) {
|
||||
@@ -46,4 +51,13 @@ public class StockService extends SimpleServiceSupport<Stock> {
|
||||
Sort.by(Sort.Direction.ASC, FinanceIndicator_.YEAR)
|
||||
);
|
||||
}
|
||||
|
||||
public List<Daily> findDailyRecent(Long stockId, int days) {
|
||||
var current = LocalDate.now();
|
||||
return dailyRepository.findAll(
|
||||
QDaily.daily.stock.id.eq(stockId)
|
||||
.and(QDaily.daily.tradeDate.between(current.minusDays(days), current)),
|
||||
Sort.by(Sort.Direction.ASC, Daily_.TRADE_DATE)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</appender>
|
||||
|
||||
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
||||
<!--<logger name="org.hibernate.SQL" level="DEBUG"/>-->
|
||||
<logger name="org.hibernate.SQL" level="DEBUG"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="Console"/>
|
||||
|
||||
@@ -47,7 +47,6 @@ const financePropertyLabel = (id: string | undefined, label: string, type: Finan
|
||||
tpl: label,
|
||||
}
|
||||
}
|
||||
let current = new Date().getFullYear()
|
||||
let formatter: (value: number) => string
|
||||
switch (type) {
|
||||
case 'PERCENTAGE':
|
||||
@@ -138,13 +137,7 @@ const financePropertyLabel = (id: string | undefined, label: string, type: Finan
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [
|
||||
current - 5,
|
||||
current - 4,
|
||||
current - 3,
|
||||
current - 2,
|
||||
current - 1,
|
||||
],
|
||||
data: '${xList || []}',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#e0e0e0',
|
||||
@@ -183,7 +176,7 @@ const financePropertyLabel = (id: string | undefined, label: string, type: Finan
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: '${detail || []}',
|
||||
data: '${yList || []}',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
showSymbol: true,
|
||||
@@ -416,6 +409,135 @@ function StockDetail() {
|
||||
],
|
||||
},
|
||||
{type: 'divider'},
|
||||
"100天日线数据",
|
||||
{
|
||||
type: 'chart',
|
||||
height: 800,
|
||||
api: `get:${commonInfo.baseUrl}/stock/daily/${id}`,
|
||||
config: {
|
||||
backgroundColor: '#fff',
|
||||
animation: true,
|
||||
animationDuration: 1000,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
},
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
||||
borderColor: '#333',
|
||||
borderWidth: 1,
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: 12,
|
||||
},
|
||||
padding: 12,
|
||||
formatter: function (params: any) {
|
||||
const param = params[0]
|
||||
const open = param.data[0]
|
||||
const close = param.data[1]
|
||||
const lowest = param.data[2]
|
||||
const highest = param.data[3]
|
||||
|
||||
return [
|
||||
`<div style="font-weight: bold; margin-bottom: 4px;">${param.name}</div>`,
|
||||
`<div style="display: flex; justify-content: space-between; margin: 2px 0;">`,
|
||||
`<span>开盘:</span>`,
|
||||
`<span style="margin-left: 12px; font-weight: bold;">${open}</span>`,
|
||||
`</div>`,
|
||||
`<div style="display: flex; justify-content: space-between; margin: 2px 0;">`,
|
||||
`<span>收盘:</span>`,
|
||||
`<span style="margin-left: 12px; font-weight: bold;">${close}</span>`,
|
||||
`</div>`,
|
||||
`<div style="display: flex; justify-content: space-between; margin: 2px 0;">`,
|
||||
`<span>最低:</span>`,
|
||||
`<span style="margin-left: 12px; font-weight: bold;">${lowest}</span>`,
|
||||
`</div>`,
|
||||
`<div style="display: flex; justify-content: space-between; margin: 2px 0;">`,
|
||||
`<span>最高:</span>`,
|
||||
`<span style="margin-left: 12px; font-weight: bold;">${highest}</span>`,
|
||||
`</div>`,
|
||||
].join('')
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
left: '10%',
|
||||
right: '10%',
|
||||
top: '10%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
data: '${xList || []}',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#e0e0e0',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#666',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
scale: true,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#e0e0e0',
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#666',
|
||||
fontWeight: 'bold',
|
||||
formatter: function (value: number) {
|
||||
return value.toFixed(0)
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
color: '#f0f0f0',
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
show: true,
|
||||
type: 'slider',
|
||||
top: '90%',
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'candlestick',
|
||||
data: '${yList || []}',
|
||||
itemStyle: {
|
||||
color: '#eb5454',
|
||||
color0: '#4aaa93',
|
||||
borderColor: '#eb5454',
|
||||
borderColor0: '#4aaa93',
|
||||
borderWidth: 1,
|
||||
},
|
||||
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user