feat: 股票集中显示股票对应的得分
This commit is contained in:
@@ -2,10 +2,11 @@ package com.lanyuanxiaoyao.leopard.core.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.Constants;
|
||||
import com.lanyuanxiaoyao.service.template.entity.SimpleEntity;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
@@ -31,7 +32,7 @@ public class StockCollection extends SimpleEntity {
|
||||
@Column(nullable = false)
|
||||
private String description;
|
||||
|
||||
@ManyToMany
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@ToString.Exclude
|
||||
private Set<Stock> stocks;
|
||||
private Set<StockScore> scores;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.lanyuanxiaoyao.leopard.core.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.Constants;
|
||||
import com.lanyuanxiaoyao.service.template.entity.SimpleEntity;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import org.hibernate.annotations.DynamicInsert;
|
||||
import org.hibernate.annotations.DynamicUpdate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@ToString(callSuper = true)
|
||||
@FieldNameConstants
|
||||
@Entity
|
||||
@DynamicUpdate
|
||||
@DynamicInsert
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
@Table(name = Constants.DATABASE_PREFIX + "stock_score")
|
||||
public class StockScore extends SimpleEntity {
|
||||
@ManyToOne
|
||||
private Stock stock;
|
||||
@ManyToOne
|
||||
private StockCollection collection;
|
||||
private Double score;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.lanyuanxiaoyao.leopard.core.task;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.StockCollection;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.StockScore;
|
||||
import com.lanyuanxiaoyao.leopard.core.repository.StockCollectionRepository;
|
||||
import com.lanyuanxiaoyao.leopard.core.service.selector.PyramidStockSelector;
|
||||
import com.lanyuanxiaoyao.leopard.core.service.selector.StockSelector;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -33,13 +33,23 @@ public class PyramidSelect extends TaskRunner {
|
||||
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
@Override
|
||||
public String process(Map<String, Object> params, StepUpdater updater) throws Exception {
|
||||
public String process(Map<String, Object> params, StepUpdater updater) {
|
||||
var candidates = pyramidStockSelector.select(new PyramidStockSelector.Request(LocalDate.now().getYear(), 50));
|
||||
|
||||
var collection = new StockCollection();
|
||||
collection.setName("金字塔选股");
|
||||
collection.setDescription("金字塔选股");
|
||||
collection.setStocks(candidates.stream().map(StockSelector.Candidate::stock).collect(Collectors.toSet()));
|
||||
collection.setScores(
|
||||
candidates.stream()
|
||||
.map(candidate -> {
|
||||
var score = new StockScore();
|
||||
score.setStock(candidate.stock());
|
||||
score.setScore(candidate.score());
|
||||
score.setCollection(collection);
|
||||
return score;
|
||||
})
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
stockCollectionRepository.save(collection);
|
||||
|
||||
return """
|
||||
|
||||
@@ -3,18 +3,18 @@ package com.lanyuanxiaoyao.leopard.server.controller;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.StockCollection;
|
||||
import com.lanyuanxiaoyao.leopard.core.service.StockCollectionService;
|
||||
import com.lanyuanxiaoyao.leopard.core.service.StockService;
|
||||
import com.lanyuanxiaoyao.leopard.server.entity.StockDetailVo;
|
||||
import com.lanyuanxiaoyao.leopard.server.entity.StockScoreVo;
|
||||
import com.lanyuanxiaoyao.service.template.controller.GlobalResponse;
|
||||
import com.lanyuanxiaoyao.service.template.controller.SimpleControllerSupport;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("stock_collection")
|
||||
public class StockCollectionController extends SimpleControllerSupport<StockCollection, StockCollectionController.SaveItem, StockCollectionController.ListItem, StockCollectionController.DetailItem> {
|
||||
public class StockCollectionController extends SimpleControllerSupport<StockCollection, Void, StockCollectionController.ListItem, StockCollectionController.DetailItem> {
|
||||
private final StockService stockService;
|
||||
|
||||
public StockCollectionController(StockCollectionService service, StockService stockService) {
|
||||
@@ -23,16 +23,13 @@ public class StockCollectionController extends SimpleControllerSupport<StockColl
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<SaveItem, StockCollection> saveItemMapper() {
|
||||
return item -> {
|
||||
var collection = new StockCollection();
|
||||
collection.setId(item.id());
|
||||
collection.setName(item.name());
|
||||
collection.setDescription(item.description());
|
||||
var stocks = stockService.list(item.stockIds());
|
||||
collection.setStocks(new HashSet<>(stocks));
|
||||
return collection;
|
||||
};
|
||||
public GlobalResponse<Long> save(Void unused) throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Void, StockCollection> saveItemMapper() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,7 +38,7 @@ public class StockCollectionController extends SimpleControllerSupport<StockColl
|
||||
collection.getId(),
|
||||
collection.getName(),
|
||||
collection.getDescription(),
|
||||
collection.getStocks().size()
|
||||
collection.getScores().size()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -51,22 +48,15 @@ public class StockCollectionController extends SimpleControllerSupport<StockColl
|
||||
collection.getId(),
|
||||
collection.getName(),
|
||||
collection.getDescription(),
|
||||
collection.getStocks().size(),
|
||||
collection.getStocks()
|
||||
collection.getScores().size(),
|
||||
collection.getScores()
|
||||
.stream()
|
||||
.map(StockDetailVo::of)
|
||||
.collect(Collectors.toSet())
|
||||
.map(StockScoreVo::of)
|
||||
.sorted(Comparator.comparing(StockScoreVo::score).reversed())
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
public record SaveItem(
|
||||
Long id,
|
||||
String name,
|
||||
String description,
|
||||
Set<Long> stockIds
|
||||
) {
|
||||
}
|
||||
|
||||
public record ListItem(
|
||||
Long id,
|
||||
String name,
|
||||
@@ -80,7 +70,7 @@ public class StockCollectionController extends SimpleControllerSupport<StockColl
|
||||
String name,
|
||||
String description,
|
||||
Integer count,
|
||||
Set<StockDetailVo> stocks
|
||||
List<StockScoreVo> scores
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.lanyuanxiaoyao.leopard.server.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.Stock;
|
||||
import com.lanyuanxiaoyao.leopard.core.entity.StockScore;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
* @version 20250917
|
||||
*/
|
||||
public record StockScoreVo(
|
||||
Long id,
|
||||
String code,
|
||||
String name,
|
||||
String fullname,
|
||||
Stock.Market market,
|
||||
String industry,
|
||||
LocalDate listedDate,
|
||||
Double score
|
||||
) {
|
||||
public static StockScoreVo of(StockScore score) {
|
||||
return new StockScoreVo(
|
||||
score.getStock().getId(),
|
||||
score.getStock().getCode(),
|
||||
score.getStock().getName(),
|
||||
score.getStock().getFullname(),
|
||||
score.getStock().getMarket(),
|
||||
score.getStock().getIndustry(),
|
||||
score.getStock().getListedDate(),
|
||||
score.getScore()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,20 @@ function StockCollectionDetail() {
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
source: '${stocks}',
|
||||
source: '${scores}',
|
||||
...crudCommonOptions(),
|
||||
...paginationTemplate(15, undefined, ['filter-toggler']),
|
||||
columns: stockListColumns(navigate),
|
||||
...paginationTemplate(100, undefined, ['filter-toggler']),
|
||||
columns: stockListColumns(
|
||||
navigate,
|
||||
[
|
||||
{
|
||||
name: 'score',
|
||||
label: '得分',
|
||||
width: 50,
|
||||
align: 'center',
|
||||
}
|
||||
]
|
||||
),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import '@fortawesome/fontawesome-free/css/all.min.css'
|
||||
import axios from 'axios'
|
||||
import {isEqual} from 'es-toolkit'
|
||||
import type {NavigateFunction} from 'react-router'
|
||||
import type {ColumnSchema} from 'amis/lib/renderers/Table2'
|
||||
|
||||
export const commonInfo = {
|
||||
debug: isEqual(import.meta.env.MODE, 'development'),
|
||||
@@ -336,7 +337,7 @@ export function remoteMappings(name: string, field: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export function stockListColumns(navigate: NavigateFunction) {
|
||||
export function stockListColumns(navigate: NavigateFunction, extraColumns: Array<ColumnSchema> = []) {
|
||||
return [
|
||||
{
|
||||
name: 'code',
|
||||
@@ -370,6 +371,7 @@ export function stockListColumns(navigate: NavigateFunction) {
|
||||
align: 'center',
|
||||
...date('listedDate'),
|
||||
},
|
||||
...extraColumns,
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
|
||||
Reference in New Issue
Block a user