perf: 股票详情页显示财报
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
package com.lanyuanxiaoyao.leopard.server.controller;
|
package com.lanyuanxiaoyao.leopard.server.controller;
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
||||||
|
import com.lanyuanxiaoyao.leopard.server.helper.NumberHelper;
|
||||||
import com.lanyuanxiaoyao.leopard.server.service.StockService;
|
import com.lanyuanxiaoyao.leopard.server.service.StockService;
|
||||||
import com.lanyuanxiaoyao.service.template.controller.GlobalResponse;
|
import com.lanyuanxiaoyao.service.template.controller.GlobalResponse;
|
||||||
import com.lanyuanxiaoyao.service.template.controller.SimpleControllerSupport;
|
import com.lanyuanxiaoyao.service.template.controller.SimpleControllerSupport;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
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;
|
||||||
|
|
||||||
@@ -16,8 +19,11 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("stock")
|
@RequestMapping("stock")
|
||||||
public class StockController extends SimpleControllerSupport<Stock, Void, StockController.DetailItem, StockController.DetailItem> {
|
public class StockController extends SimpleControllerSupport<Stock, Void, StockController.DetailItem, StockController.DetailItem> {
|
||||||
public StockController(StockService service) {
|
private final StockService stockService;
|
||||||
|
|
||||||
|
public StockController(StockService service, StockService stockService) {
|
||||||
super(service);
|
super(service);
|
||||||
|
this.stockService = stockService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -25,6 +31,37 @@ public class StockController extends SimpleControllerSupport<Stock, Void, StockC
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("finance/{id}")
|
||||||
|
public GlobalResponse<FinanceItem> finance(@PathVariable("id") Long id) {
|
||||||
|
// 财报默认是上一年的
|
||||||
|
var year = LocalDate.now().minusYears(1).getYear();
|
||||||
|
var balanceSheet = stockService.findBalanceSheet(id, year);
|
||||||
|
var income = stockService.findIncome(id, year);
|
||||||
|
var cashFlow = stockService.findCashFlow(id, year);
|
||||||
|
return GlobalResponse.responseSuccess(new FinanceItem(
|
||||||
|
id,
|
||||||
|
year,
|
||||||
|
balanceSheet
|
||||||
|
.map(bs -> new BalanceSheetItem(
|
||||||
|
NumberHelper.formatFinanceDouble(bs.getTotalAssets()),
|
||||||
|
NumberHelper.formatFinanceDouble(bs.getTotalLiabilities())
|
||||||
|
))
|
||||||
|
.orElse(new BalanceSheetItem()),
|
||||||
|
income
|
||||||
|
.map(ic -> new IncomeItem(
|
||||||
|
NumberHelper.formatFinanceDouble(ic.getTotalOperatingRevenue()),
|
||||||
|
NumberHelper.formatFinanceDouble(ic.getTotalOperatingCost()),
|
||||||
|
NumberHelper.formatFinanceDouble(ic.getTotalProfit())
|
||||||
|
))
|
||||||
|
.orElse(new IncomeItem()),
|
||||||
|
cashFlow
|
||||||
|
.map(cf -> new CashFlowItem(
|
||||||
|
NumberHelper.formatFinanceDouble(cf.getNetProfit())
|
||||||
|
))
|
||||||
|
.orElse(new CashFlowItem())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Function<Void, Stock> saveItemMapper() {
|
protected Function<Void, Stock> saveItemMapper() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@@ -62,4 +99,49 @@ public class StockController extends SimpleControllerSupport<Stock, Void, StockC
|
|||||||
LocalDate listedDate
|
LocalDate listedDate
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record FinanceItem(
|
||||||
|
Long id,
|
||||||
|
Integer year,
|
||||||
|
BalanceSheetItem balanceSheet,
|
||||||
|
IncomeItem income,
|
||||||
|
CashFlowItem cashFlow
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public record BalanceSheetItem(
|
||||||
|
String totalAssets,
|
||||||
|
String totalLiabilities
|
||||||
|
) {
|
||||||
|
public BalanceSheetItem() {
|
||||||
|
this(
|
||||||
|
NumberHelper.FINANCE_NULL_DOUBLE,
|
||||||
|
NumberHelper.FINANCE_NULL_DOUBLE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record IncomeItem(
|
||||||
|
String totalOperatingRevenue,
|
||||||
|
String totalOperatingCost,
|
||||||
|
String totalProfit
|
||||||
|
) {
|
||||||
|
public IncomeItem() {
|
||||||
|
this(
|
||||||
|
NumberHelper.FINANCE_NULL_DOUBLE,
|
||||||
|
NumberHelper.FINANCE_NULL_DOUBLE,
|
||||||
|
NumberHelper.FINANCE_NULL_DOUBLE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record CashFlowItem(
|
||||||
|
String netProfit
|
||||||
|
) {
|
||||||
|
public CashFlowItem() {
|
||||||
|
this(
|
||||||
|
NumberHelper.FINANCE_NULL_DOUBLE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
package com.lanyuanxiaoyao.leopard.server.service;
|
package com.lanyuanxiaoyao.leopard.server.service;
|
||||||
|
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.BalanceSheet;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.CashFlow;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.Income;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.QBalanceSheet;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.QCashFlow;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.QIncome;
|
||||||
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.repository.BalanceSheetRepository;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.repository.CashFlowRepository;
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.repository.IncomeRepository;
|
||||||
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
|
import com.lanyuanxiaoyao.leopard.core.repository.StockRepository;
|
||||||
import com.lanyuanxiaoyao.service.template.service.SimpleServiceSupport;
|
import com.lanyuanxiaoyao.service.template.service.SimpleServiceSupport;
|
||||||
import java.util.List;
|
import java.util.Optional;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -15,13 +24,36 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class StockService extends SimpleServiceSupport<Stock> {
|
public class StockService extends SimpleServiceSupport<Stock> {
|
||||||
private final StockRepository stockRepository;
|
private final StockRepository stockRepository;
|
||||||
|
private final BalanceSheetRepository balanceSheetRepository;
|
||||||
|
private final IncomeRepository incomeRepository;
|
||||||
|
private final CashFlowRepository cashFlowRepository;
|
||||||
|
|
||||||
public StockService(StockRepository repository) {
|
public StockService(StockRepository repository, BalanceSheetRepository balanceSheetRepository, IncomeRepository incomeRepository, CashFlowRepository cashFlowRepository) {
|
||||||
super(repository);
|
super(repository);
|
||||||
this.stockRepository = repository;
|
this.stockRepository = repository;
|
||||||
|
this.balanceSheetRepository = balanceSheetRepository;
|
||||||
|
this.incomeRepository = incomeRepository;
|
||||||
|
this.cashFlowRepository = cashFlowRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> findDistinctIndustries() {
|
public Optional<BalanceSheet> findBalanceSheet(Long stockId, Integer year) {
|
||||||
return stockRepository.findDistinctIndustries();
|
return balanceSheetRepository.findOne(
|
||||||
|
QBalanceSheet.balanceSheet.year.eq(year)
|
||||||
|
.and(QBalanceSheet.balanceSheet.stock.id.eq(stockId))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Income> findIncome(Long stockId, Integer year) {
|
||||||
|
return incomeRepository.findOne(
|
||||||
|
QIncome.income.year.eq(year)
|
||||||
|
.and(QIncome.income.stock.id.eq(stockId))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<CashFlow> findCashFlow(Long stockId, Integer year) {
|
||||||
|
return cashFlowRepository.findOne(
|
||||||
|
QCashFlow.cashFlow.year.eq(year)
|
||||||
|
.and(QCashFlow.cashFlow.stock.id.eq(stockId))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,12 @@
|
|||||||
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
||||||
<!--<logger name="org.hibernate.SQL" level="DEBUG"/>-->
|
<!--<logger name="org.hibernate.SQL" level="DEBUG"/>-->
|
||||||
|
|
||||||
<root level="INFO">
|
<springProfile name="build">
|
||||||
<appender-ref ref="Console"/>
|
<appender-ref ref="Console"/>
|
||||||
<appender-ref ref="RollingFile"/>
|
<appender-ref ref="RollingFile"/>
|
||||||
|
</springProfile>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="Console"/>
|
||||||
</root>
|
</root>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -26,9 +26,44 @@ function StockDetail() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{label: '行业', content: '${industry}'},
|
{label: '行业', content: '${industry}'},
|
||||||
|
{label: '上市日期', content: '${listedDate}'},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{type: 'divider'},
|
{type: 'divider'},
|
||||||
|
{
|
||||||
|
type: 'service',
|
||||||
|
api: `get:${commonInfo.baseUrl}/stock/finance/${id}`,
|
||||||
|
body: [
|
||||||
|
'资产负债表',
|
||||||
|
{
|
||||||
|
className: 'my-2',
|
||||||
|
type: 'property',
|
||||||
|
items: [
|
||||||
|
{label: '总资产', content: '${balanceSheet.totalAssets}'},
|
||||||
|
{label: '总负债', content: '${balanceSheet.totalLiabilities}'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'利润表',
|
||||||
|
{
|
||||||
|
className: 'my-2',
|
||||||
|
type: 'property',
|
||||||
|
items: [
|
||||||
|
{label: '营业总收入', content: '${income.totalOperatingRevenue}'},
|
||||||
|
{label: '营业总成本', content: '${income.totalOperatingCost}'},
|
||||||
|
{label: '营业总利润', content: '${income.totalProfit}'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'现金流量表',
|
||||||
|
{
|
||||||
|
className: 'my-2',
|
||||||
|
type: 'property',
|
||||||
|
items: [
|
||||||
|
{label: '净利润', content: '${cashFlow.netProfit}'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{type: 'divider'},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user