feat: 增加财务信息采集
This commit is contained in:
@@ -10,6 +10,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
import org.hibernate.annotations.Comment;
|
||||||
import org.hibernate.annotations.DynamicInsert;
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
import org.hibernate.annotations.DynamicUpdate;
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||||
@@ -29,4 +30,66 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|||||||
public class BalanceSheet extends SimpleEntity {
|
public class BalanceSheet extends SimpleEntity {
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private Stock stock;
|
private Stock stock;
|
||||||
|
@Comment("年报年度")
|
||||||
|
private Integer year;
|
||||||
|
@Comment("原始名称:total_share,描述:期末总股本")
|
||||||
|
private Double endingTotalShares;
|
||||||
|
@Comment("原始名称:cap_rese,描述:资本公积金")
|
||||||
|
private Double capitalSurplus;
|
||||||
|
@Comment("原始名称:undist_profit,描述:未分配利润")
|
||||||
|
private Double undistributedProfit;
|
||||||
|
@Comment("原始名称:money_cap,描述:货币资金")
|
||||||
|
private Double monetaryFunds;
|
||||||
|
@Comment("原始名称:accounts_receiv,描述:应收账款")
|
||||||
|
private Double accountsReceivable;
|
||||||
|
@Comment("原始名称:inventories,描述:存货")
|
||||||
|
private Double inventories;
|
||||||
|
@Comment("原始名称:total_cur_assets,描述:流动资产合计")
|
||||||
|
private Double totalCurrentAssets;
|
||||||
|
@Comment("原始名称:lt_eqt_invest,描述:长期股权投资")
|
||||||
|
private Double longTermEquityInvestments;
|
||||||
|
@Comment("原始名称:lt_rec,描述:长期应收款")
|
||||||
|
private Double longTermReceivables;
|
||||||
|
@Comment("原始名称:fix_assets,描述:固定资产")
|
||||||
|
private Double fixedAssets;
|
||||||
|
@Comment("原始名称:r_and_d,描述:研发支出")
|
||||||
|
private Double researchAndDevelopmentExpenditures;
|
||||||
|
@Comment("原始名称:goodwill,描述:商誉")
|
||||||
|
private Double goodwill;
|
||||||
|
@Comment("原始名称:total_nca,描述:非流动资产合计")
|
||||||
|
private Double totalNonCurrentAssets;
|
||||||
|
@Comment("原始名称:total_assets,描述:资产总计")
|
||||||
|
private Double totalAssets;
|
||||||
|
@Comment("原始名称:lt_borr,描述:长期借款")
|
||||||
|
private Double longTermBorrowings;
|
||||||
|
@Comment("原始名称:st_borr,描述:短期借款")
|
||||||
|
private Double shortTermBorrowings;
|
||||||
|
@Comment("原始名称:acct_payable,描述:应付账款")
|
||||||
|
private Double accountsPayable;
|
||||||
|
@Comment("原始名称:adv_receipts,描述:预收款项")
|
||||||
|
private Double advancesReceived;
|
||||||
|
@Comment("原始名称:total_cur_lab,描述:流动负债合计")
|
||||||
|
private Double totalCurrentLiabilities;
|
||||||
|
@Comment("原始名称:total_ncl,描述:非流动负债合计")
|
||||||
|
private Double totalNonCurrentLiabilities;
|
||||||
|
@Comment("原始名称:total_lab,描述:负债合计")
|
||||||
|
private Double totalLiabilities;
|
||||||
|
@Comment("原始名称:total_hldr_eqy_exc_min_int,描述:股东权益合计(不含少数股东权益)")
|
||||||
|
private Double totalShareholdersEquityExcludingMinorityInterest;
|
||||||
|
@Comment("原始名称:total_hldr_eqy_inc_min_int,描述:股东权益合计(含少数股东权益)")
|
||||||
|
private Double totalShareholdersEquityIncludingMinorityInterest;
|
||||||
|
@Comment("原始名称:total_lab_hldr_eqy,描述:负债及股东权益总计")
|
||||||
|
private Double totalLiabilitiesAndShareholdersEquity;
|
||||||
|
@Comment("原始名称:acc_receivable,描述:应收款项")
|
||||||
|
private Double receivables;
|
||||||
|
@Comment("原始名称:payables,描述:应付款项")
|
||||||
|
private Double payables;
|
||||||
|
@Comment("原始名称:accounts_receiv_bill,描述:应收票据及应收账款")
|
||||||
|
private Double notesAndAccountsReceivable;
|
||||||
|
@Comment("原始名称:accounts_pay_bill,描述:应付票据及应付账款")
|
||||||
|
private Double notesAndAccountsPayable;
|
||||||
|
@Comment("原始名称:oth_rcv_total,描述:其他应收款(合计)(元)")
|
||||||
|
private Double otherReceivablesTotal;
|
||||||
|
@Comment("原始名称:fix_assets_total,描述:固定资产(合计)(元)")
|
||||||
|
private Double fixedAssetsTotal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
import org.hibernate.annotations.Comment;
|
||||||
import org.hibernate.annotations.DynamicInsert;
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
import org.hibernate.annotations.DynamicUpdate;
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||||
@@ -29,4 +30,32 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|||||||
public class CashFlow extends SimpleEntity {
|
public class CashFlow extends SimpleEntity {
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private Stock stock;
|
private Stock stock;
|
||||||
|
@Comment("年报年度")
|
||||||
|
private Integer year;
|
||||||
|
@Comment("原始名称:net_profit,描述:净利润")
|
||||||
|
private Double netProfit;
|
||||||
|
@Comment("原始名称:fin_exp,描述:财务费用")
|
||||||
|
private Double financialExpense;
|
||||||
|
@Comment("原始名称:c_f_sale_sg,描述:销售商品、提供劳务收到的现金")
|
||||||
|
private Double cashReceivedFromSalesAndServices;
|
||||||
|
@Comment("原始名称:c_f_oth_oper_a,描述:经营活动现金流入小计")
|
||||||
|
private Double subtotalOfCashInflowsFromOperatingActivities;
|
||||||
|
@Comment("原始名称:c_paid_to_for_empl,描述:支付给职工以及为职工支付的现金")
|
||||||
|
private Double cashPaidToAndForEmployees;
|
||||||
|
@Comment("原始名称:c_paid_for_taxes,描述:支付的各项税费")
|
||||||
|
private Double cashPaidForVariousTaxes;
|
||||||
|
@Comment("原始名称:st_cashflow_act,描述:经营活动产生的现金流量净额")
|
||||||
|
private Double netCashFlowFromOperatingActivities;
|
||||||
|
@Comment("原始名称:stoc_inflows_inv_act,描述:投资活动现金流入小计")
|
||||||
|
private Double subtotalOfCashInflowsFromInvestingActivities;
|
||||||
|
@Comment("原始名称:c_paid_subs_oth_biz,描述:购置固定资产、无形资产和其他长期资产支付的现金")
|
||||||
|
private Double cashPaidForAcquisitionOfFixedIntangibleAndOtherLongTermAssets;
|
||||||
|
@Comment("原始名称:stoc_cashout_inv_act,描述:投资活动现金流出小计")
|
||||||
|
private Double subtotalOfCashOutflowsFromInvestingActivities;
|
||||||
|
@Comment("原始名称:stoc_cashout_fin_act,描述:筹资活动现金流出小计")
|
||||||
|
private Double subtotalOfCashOutflowsFromFinancingActivities;
|
||||||
|
@Comment("原始名称:c_cash_equ_beg_period,描述:期初现金及现金等价物余额")
|
||||||
|
private Double beginningBalanceOfCashAndCashEquivalents;
|
||||||
|
@Comment("原始名称:c_cash_equ_end_period,描述:期末现金及现金等价物余额")
|
||||||
|
private Double endingBalanceOfCashAndCashEquivalents;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
import org.hibernate.annotations.Comment;
|
||||||
import org.hibernate.annotations.DynamicInsert;
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
import org.hibernate.annotations.DynamicUpdate;
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||||
@@ -29,4 +30,60 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|||||||
public class Income extends SimpleEntity {
|
public class Income extends SimpleEntity {
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private Stock stock;
|
private Stock stock;
|
||||||
|
@Comment("年报年度")
|
||||||
|
private Integer year;
|
||||||
|
@Comment("原始名称:basic_eps,描述:基本每股收益")
|
||||||
|
private Double basicEarningsPerShare;
|
||||||
|
@Comment("原始名称:diluted_eps,描述:稀释每股收益")
|
||||||
|
private Double dilutedEarningsPerShare;
|
||||||
|
@Comment("原始名称:total_revenue,描述:营业总收入")
|
||||||
|
private Double totalOperatingRevenue;
|
||||||
|
@Comment("原始名称:revenue,描述:营业收入")
|
||||||
|
private Double operatingRevenue;
|
||||||
|
@Comment("原始名称:total_cogs,描述:营业总成本")
|
||||||
|
private Double totalOperatingCost;
|
||||||
|
@Comment("原始名称:oper_cost,描述:减:营业成本")
|
||||||
|
private Double operatingCost;
|
||||||
|
@Comment("原始名称:sell_exp,描述:减:销售费用")
|
||||||
|
private Double sellingExpense;
|
||||||
|
@Comment("原始名称:admin_exp,描述:减:管理费用")
|
||||||
|
private Double administrativeExpense;
|
||||||
|
@Comment("原始名称:fin_exp,描述:减:财务费用")
|
||||||
|
private Double financialExpense;
|
||||||
|
@Comment("原始名称:oper_exp,描述:营业支出")
|
||||||
|
private Double operatingExpense;
|
||||||
|
@Comment("原始名称:operate_profit,描述:营业利润")
|
||||||
|
private Double operatingProfit;
|
||||||
|
@Comment("原始名称:non_oper_income,描述:加:营业外收入")
|
||||||
|
private Double addNonOperatingIncome;
|
||||||
|
@Comment("原始名称:non_oper_exp,描述:减:营业外支出")
|
||||||
|
private Double lessNonOperatingExpense;
|
||||||
|
@Comment("原始名称:total_profit,描述:利润总额")
|
||||||
|
private Double totalProfit;
|
||||||
|
@Comment("原始名称:income_tax,描述:所得税费用")
|
||||||
|
private Double incomeTaxExpense;
|
||||||
|
@Comment("原始名称:n_income,描述:净利润(含少数股东损益)")
|
||||||
|
private Double netProfitIncludingMinorityInterest;
|
||||||
|
@Comment("原始名称:n_income_attr_p,描述:净利润(不含少数股东损益)")
|
||||||
|
private Double netProfitExcludingMinorityInterest;
|
||||||
|
@Comment("原始名称:compr_inc_attr_p,描述:归属于母公司(或股东)的综合收益总额")
|
||||||
|
private Double comprehensiveIncomeAttributableToParent;
|
||||||
|
@Comment("原始名称:compr_inc_attr_m_s,描述:归属于少数股东的综合收益总额")
|
||||||
|
private Double comprehensiveIncomeAttributableToMinorityShareholders;
|
||||||
|
@Comment("原始名称:ebit,描述:息税前利润")
|
||||||
|
private Double earningsBeforeInterestAndTax;
|
||||||
|
@Comment("原始名称:ebida,描述:息税折旧摊销前利润")
|
||||||
|
private Double earningsBeforeInterestTaxDepreciationAndAmortization;
|
||||||
|
@Comment("原始名称:undist_profit,描述:年初未分配利润")
|
||||||
|
private Double beginningUndistributedProfit;
|
||||||
|
@Comment("原始名称:distable_profit,描述:可分配利润")
|
||||||
|
private Double distributableProfit;
|
||||||
|
@Comment("原始名称:rd_exp,描述:研发费用")
|
||||||
|
private Double researchAndDevelopmentExpense;
|
||||||
|
@Comment("原始名称:fin_exp_int_exp,描述:财务费用-利息费用")
|
||||||
|
private Double financialExpenseInterestExpense;
|
||||||
|
@Comment("原始名称:continued_net_profit,描述:持续经营净利润")
|
||||||
|
private Double netProfitFromContinuingOperations;
|
||||||
|
@Comment("原始名称:end_net_profit,描述:终止经营净利润")
|
||||||
|
private Double netProfitFromDiscontinuedOperations;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.lanyuanxiaoyao.leopard.core.repository;
|
||||||
|
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.BalanceSheet;
|
||||||
|
import com.lanyuanxiaoyao.service.template.repository.SimpleRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @version 20250911
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface BalanceSheetRepository extends SimpleRepository<BalanceSheet> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.lanyuanxiaoyao.leopard.core.repository;
|
||||||
|
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.CashFlow;
|
||||||
|
import com.lanyuanxiaoyao.service.template.repository.SimpleRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @version 20250911
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface CashFlowRepository extends SimpleRepository<CashFlow> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.lanyuanxiaoyao.leopard.core.repository;
|
||||||
|
|
||||||
|
import com.lanyuanxiaoyao.leopard.core.entity.Income;
|
||||||
|
import com.lanyuanxiaoyao.service.template.repository.SimpleRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @version 20250911
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface IncomeRepository extends SimpleRepository<Income> {
|
||||||
|
}
|
||||||
@@ -23,10 +23,9 @@ import org.springframework.stereotype.Service;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class TuShareService {
|
public class TuShareService {
|
||||||
|
public static final DateTimeFormatter TRADE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||||
private static final String API_URL = "https://api.tushare.pro";
|
private static final String API_URL = "https://api.tushare.pro";
|
||||||
private static final String API_TOKEN = "64ebff4fa679167600b905ee45dd88e76f3963c0ff39157f3f085f0e";
|
private static final String API_TOKEN = "64ebff4fa679167600b905ee45dd88e76f3963c0ff39157f3f085f0e";
|
||||||
public static final DateTimeFormatter TRADE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
|
|
||||||
|
|
||||||
private final ObjectMapper mapper;
|
private final ObjectMapper mapper;
|
||||||
|
|
||||||
public TuShareService(Jackson2ObjectMapperBuilder builder) {
|
public TuShareService(Jackson2ObjectMapperBuilder builder) {
|
||||||
@@ -108,6 +107,124 @@ public class TuShareService {
|
|||||||
return tuShareResponse;
|
return tuShareResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public TuShareResponse incomeList(int year) {
|
||||||
|
var response = HttpUtil.post(API_URL, buildRequest(
|
||||||
|
"income_vip",
|
||||||
|
Map.of("period", LocalDate.of(year, 12, 31).format(TRADE_FORMAT)),
|
||||||
|
List.of(
|
||||||
|
"ts_code",
|
||||||
|
"basic_eps",
|
||||||
|
"diluted_eps",
|
||||||
|
"total_revenue",
|
||||||
|
"revenue",
|
||||||
|
"total_cogs",
|
||||||
|
"oper_cost",
|
||||||
|
"sell_exp",
|
||||||
|
"admin_exp",
|
||||||
|
"fin_exp",
|
||||||
|
"oper_exp",
|
||||||
|
"operate_profit",
|
||||||
|
"non_oper_income",
|
||||||
|
"non_oper_exp",
|
||||||
|
"total_profit",
|
||||||
|
"income_tax",
|
||||||
|
"n_income",
|
||||||
|
"n_income_attr_p",
|
||||||
|
"compr_inc_attr_p",
|
||||||
|
"compr_inc_attr_m_s",
|
||||||
|
"ebit",
|
||||||
|
"ebida",
|
||||||
|
"undist_profit",
|
||||||
|
"distable_profit",
|
||||||
|
"rd_exp",
|
||||||
|
"fin_exp_int_exp",
|
||||||
|
"continued_net_profit",
|
||||||
|
"end_net_profit"
|
||||||
|
)
|
||||||
|
));
|
||||||
|
var tuShareResponse = mapper.readValue(response, TuShareResponse.class);
|
||||||
|
if (tuShareResponse.code != 0) {
|
||||||
|
throw new RuntimeException(tuShareResponse.message);
|
||||||
|
}
|
||||||
|
return tuShareResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public TuShareResponse balanceList(int year) {
|
||||||
|
var response = HttpUtil.post(API_URL, buildRequest(
|
||||||
|
"balancesheet_vip",
|
||||||
|
Map.of("period", LocalDate.of(year, 12, 31).format(TRADE_FORMAT)),
|
||||||
|
List.of(
|
||||||
|
"ts_code",
|
||||||
|
"total_share",
|
||||||
|
"cap_rese",
|
||||||
|
"undist_profit",
|
||||||
|
"money_cap",
|
||||||
|
"accounts_receiv",
|
||||||
|
"inventories",
|
||||||
|
"total_cur_assets",
|
||||||
|
"lt_eqt_invest",
|
||||||
|
"lt_rec",
|
||||||
|
"fix_assets",
|
||||||
|
"r_and_d",
|
||||||
|
"goodwill",
|
||||||
|
"total_nca",
|
||||||
|
"total_assets",
|
||||||
|
"lt_borr",
|
||||||
|
"st_borr",
|
||||||
|
"acct_payable",
|
||||||
|
"adv_receipts",
|
||||||
|
"total_cur_lab",
|
||||||
|
"total_ncl",
|
||||||
|
"total_lab",
|
||||||
|
"total_hldr_eqy_exc_min_int",
|
||||||
|
"total_hldr_eqy_inc_min_int",
|
||||||
|
"total_lab_hldr_eqy",
|
||||||
|
"acc_receivable",
|
||||||
|
"payables",
|
||||||
|
"accounts_receiv_bill",
|
||||||
|
"accounts_pay_bill",
|
||||||
|
"oth_rcv_total",
|
||||||
|
"fix_assets_total"
|
||||||
|
)
|
||||||
|
));
|
||||||
|
var tuShareResponse = mapper.readValue(response, TuShareResponse.class);
|
||||||
|
if (tuShareResponse.code != 0) {
|
||||||
|
throw new RuntimeException(tuShareResponse.message);
|
||||||
|
}
|
||||||
|
return tuShareResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public TuShareResponse cashFlowList(int year) {
|
||||||
|
var response = HttpUtil.post(API_URL, buildRequest(
|
||||||
|
"cashflow_vip",
|
||||||
|
Map.of("period", LocalDate.of(year, 12, 31).format(TRADE_FORMAT)),
|
||||||
|
List.of(
|
||||||
|
"ts_code",
|
||||||
|
"net_profit",
|
||||||
|
"fin_exp",
|
||||||
|
"c_f_sale_sg",
|
||||||
|
"c_f_oth_oper_a",
|
||||||
|
"c_paid_to_for_empl",
|
||||||
|
"c_paid_for_taxes",
|
||||||
|
"st_cashflow_act",
|
||||||
|
"stoc_inflows_inv_act",
|
||||||
|
"c_paid_subs_oth_biz",
|
||||||
|
"stoc_cashout_inv_act",
|
||||||
|
"stoc_cashout_fin_act",
|
||||||
|
"c_cash_equ_beg_period",
|
||||||
|
"c_cash_equ_end_period"
|
||||||
|
)
|
||||||
|
));
|
||||||
|
var tuShareResponse = mapper.readValue(response, TuShareResponse.class);
|
||||||
|
if (tuShareResponse.code != 0) {
|
||||||
|
throw new RuntimeException(tuShareResponse.message);
|
||||||
|
}
|
||||||
|
return tuShareResponse;
|
||||||
|
}
|
||||||
|
|
||||||
public record TuShareResponse(
|
public record TuShareResponse(
|
||||||
Integer code,
|
Integer code,
|
||||||
@JsonProperty("msg")
|
@JsonProperty("msg")
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
package com.lanyuanxiaoyao.leopard.server.service.task;
|
||||||
|
|
||||||
|
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.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.server.service.TaskService;
|
||||||
|
import com.lanyuanxiaoyao.leopard.server.service.TuShareService;
|
||||||
|
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新财务数据
|
||||||
|
*
|
||||||
|
* @author lanyuanxiaoyao
|
||||||
|
* @version 20250911
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@LiteflowComponent("update_finance")
|
||||||
|
public class UpdateFinanceNode extends TaskNodeComponent {
|
||||||
|
private final TuShareService tuShareService;
|
||||||
|
|
||||||
|
private final StockRepository stockRepository;
|
||||||
|
private final IncomeRepository incomeRepository;
|
||||||
|
private final BalanceSheetRepository balanceSheetRepository;
|
||||||
|
private final CashFlowRepository cashFlowRepository;
|
||||||
|
|
||||||
|
public UpdateFinanceNode(TaskService taskService, TuShareService tuShareService, StockRepository stockRepository, IncomeRepository incomeRepository, BalanceSheetRepository balanceSheetRepository, CashFlowRepository cashFlowRepository) {
|
||||||
|
super(taskService);
|
||||||
|
this.tuShareService = tuShareService;
|
||||||
|
this.stockRepository = stockRepository;
|
||||||
|
this.incomeRepository = incomeRepository;
|
||||||
|
this.balanceSheetRepository = balanceSheetRepository;
|
||||||
|
this.cashFlowRepository = cashFlowRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process() {
|
||||||
|
var stocks = stockRepository.findAll();
|
||||||
|
var stocksMap = stocks.stream().collect(Collectors.toMap(Stock::getCode, stock -> stock));
|
||||||
|
var currentYear = LocalDate.now().getYear();
|
||||||
|
for (int year = 1990; year < currentYear; year++) {
|
||||||
|
|
||||||
|
var response = tuShareService.incomeList(year);
|
||||||
|
for (List<String> item : response.data().items()) {
|
||||||
|
var code = item.get(0);
|
||||||
|
if (!stocksMap.containsKey(code)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var stock = stocksMap.get(code);
|
||||||
|
var income = new Income();
|
||||||
|
income.setStock(stock);
|
||||||
|
income.setYear(year);
|
||||||
|
income.setBasicEarningsPerShare(Double.parseDouble(item.get(1)));
|
||||||
|
income.setDilutedEarningsPerShare(Double.parseDouble(item.get(2)));
|
||||||
|
income.setTotalOperatingRevenue(Double.parseDouble(item.get(3)));
|
||||||
|
income.setOperatingRevenue(Double.parseDouble(item.get(4)));
|
||||||
|
income.setTotalOperatingCost(Double.parseDouble(item.get(5)));
|
||||||
|
income.setOperatingCost(Double.parseDouble(item.get(6)));
|
||||||
|
income.setSellingExpense(Double.parseDouble(item.get(7)));
|
||||||
|
income.setAdministrativeExpense(Double.parseDouble(item.get(8)));
|
||||||
|
income.setFinancialExpense(Double.parseDouble(item.get(9)));
|
||||||
|
income.setOperatingExpense(Double.parseDouble(item.get(10)));
|
||||||
|
income.setOperatingProfit(Double.parseDouble(item.get(11)));
|
||||||
|
income.setAddNonOperatingIncome(Double.parseDouble(item.get(12)));
|
||||||
|
income.setLessNonOperatingExpense(Double.parseDouble(item.get(13)));
|
||||||
|
income.setTotalProfit(Double.parseDouble(item.get(14)));
|
||||||
|
income.setIncomeTaxExpense(Double.parseDouble(item.get(15)));
|
||||||
|
income.setNetProfitIncludingMinorityInterest(Double.parseDouble(item.get(16)));
|
||||||
|
income.setNetProfitExcludingMinorityInterest(Double.parseDouble(item.get(17)));
|
||||||
|
income.setComprehensiveIncomeAttributableToParent(Double.parseDouble(item.get(18)));
|
||||||
|
income.setComprehensiveIncomeAttributableToMinorityShareholders(Double.parseDouble(item.get(19)));
|
||||||
|
income.setEarningsBeforeInterestAndTax(Double.parseDouble(item.get(20)));
|
||||||
|
income.setEarningsBeforeInterestTaxDepreciationAndAmortization(Double.parseDouble(item.get(21)));
|
||||||
|
income.setBeginningUndistributedProfit(Double.parseDouble(item.get(22)));
|
||||||
|
income.setDistributableProfit(Double.parseDouble(item.get(23)));
|
||||||
|
income.setResearchAndDevelopmentExpense(Double.parseDouble(item.get(24)));
|
||||||
|
income.setFinancialExpenseInterestExpense(Double.parseDouble(item.get(25)));
|
||||||
|
income.setNetProfitFromContinuingOperations(Double.parseDouble(item.get(26)));
|
||||||
|
income.setNetProfitFromDiscontinuedOperations(Double.parseDouble(item.get(27)));
|
||||||
|
incomeRepository.save(income);
|
||||||
|
}
|
||||||
|
|
||||||
|
response = tuShareService.balanceList(year);
|
||||||
|
for (List<String> item : response.data().items()) {
|
||||||
|
var code = item.get(0);
|
||||||
|
if (!stocksMap.containsKey(code)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var stock = stocksMap.get(code);
|
||||||
|
var balanceSheet = new BalanceSheet();
|
||||||
|
balanceSheet.setStock(stock);
|
||||||
|
balanceSheet.setYear(year);
|
||||||
|
balanceSheet.setEndingTotalShares(Double.parseDouble(item.get(1)));
|
||||||
|
balanceSheet.setCapitalSurplus(Double.parseDouble(item.get(2)));
|
||||||
|
balanceSheet.setUndistributedProfit(Double.parseDouble(item.get(3)));
|
||||||
|
balanceSheet.setMonetaryFunds(Double.parseDouble(item.get(4)));
|
||||||
|
balanceSheet.setAccountsReceivable(Double.parseDouble(item.get(5)));
|
||||||
|
balanceSheet.setInventories(Double.parseDouble(item.get(6)));
|
||||||
|
balanceSheet.setTotalCurrentAssets(Double.parseDouble(item.get(7)));
|
||||||
|
balanceSheet.setLongTermEquityInvestments(Double.parseDouble(item.get(8)));
|
||||||
|
balanceSheet.setLongTermReceivables(Double.parseDouble(item.get(9)));
|
||||||
|
balanceSheet.setFixedAssets(Double.parseDouble(item.get(10)));
|
||||||
|
balanceSheet.setResearchAndDevelopmentExpenditures(Double.parseDouble(item.get(11)));
|
||||||
|
balanceSheet.setGoodwill(Double.parseDouble(item.get(12)));
|
||||||
|
balanceSheet.setTotalNonCurrentAssets(Double.parseDouble(item.get(13)));
|
||||||
|
balanceSheet.setTotalAssets(Double.parseDouble(item.get(14)));
|
||||||
|
balanceSheet.setLongTermBorrowings(Double.parseDouble(item.get(15)));
|
||||||
|
balanceSheet.setShortTermBorrowings(Double.parseDouble(item.get(16)));
|
||||||
|
balanceSheet.setAccountsPayable(Double.parseDouble(item.get(17)));
|
||||||
|
balanceSheet.setAdvancesReceived(Double.parseDouble(item.get(18)));
|
||||||
|
balanceSheet.setTotalCurrentLiabilities(Double.parseDouble(item.get(19)));
|
||||||
|
balanceSheet.setTotalNonCurrentLiabilities(Double.parseDouble(item.get(20)));
|
||||||
|
balanceSheet.setTotalLiabilities(Double.parseDouble(item.get(21)));
|
||||||
|
balanceSheet.setTotalShareholdersEquityExcludingMinorityInterest(Double.parseDouble(item.get(22)));
|
||||||
|
balanceSheet.setTotalShareholdersEquityIncludingMinorityInterest(Double.parseDouble(item.get(23)));
|
||||||
|
balanceSheet.setTotalLiabilitiesAndShareholdersEquity(Double.parseDouble(item.get(24)));
|
||||||
|
balanceSheet.setAccountsReceivable(Double.parseDouble(item.get(25)));
|
||||||
|
balanceSheet.setPayables(Double.parseDouble(item.get(26)));
|
||||||
|
balanceSheet.setNotesAndAccountsReceivable(Double.parseDouble(item.get(27)));
|
||||||
|
balanceSheet.setNotesAndAccountsPayable(Double.parseDouble(item.get(28)));
|
||||||
|
balanceSheet.setOtherReceivablesTotal(Double.parseDouble(item.get(29)));
|
||||||
|
balanceSheet.setFixedAssetsTotal(Double.parseDouble(item.get(30)));
|
||||||
|
balanceSheetRepository.save(balanceSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
response = tuShareService.cashFlowList(year);
|
||||||
|
for (List<String> item : response.data().items()) {
|
||||||
|
var code = item.get(0);
|
||||||
|
if (!stocksMap.containsKey(code)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var stock = stocksMap.get(code);
|
||||||
|
var cashFlow = new CashFlow();
|
||||||
|
cashFlow.setStock(stock);
|
||||||
|
cashFlow.setYear(year);
|
||||||
|
cashFlow.setNetProfit(Double.parseDouble(item.get(1)));
|
||||||
|
cashFlow.setFinancialExpense(Double.parseDouble(item.get(2)));
|
||||||
|
cashFlow.setCashReceivedFromSalesAndServices(Double.parseDouble(item.get(3)));
|
||||||
|
cashFlow.setSubtotalOfCashInflowsFromOperatingActivities(Double.parseDouble(item.get(4)));
|
||||||
|
cashFlow.setCashPaidToAndForEmployees(Double.parseDouble(item.get(5)));
|
||||||
|
cashFlow.setCashPaidForVariousTaxes(Double.parseDouble(item.get(6)));
|
||||||
|
cashFlow.setNetCashFlowFromOperatingActivities(Double.parseDouble(item.get(7)));
|
||||||
|
cashFlow.setSubtotalOfCashInflowsFromInvestingActivities(Double.parseDouble(item.get(8)));
|
||||||
|
cashFlow.setCashPaidForAcquisitionOfFixedIntangibleAndOtherLongTermAssets(Double.parseDouble(item.get(9)));
|
||||||
|
cashFlow.setSubtotalOfCashOutflowsFromInvestingActivities(Double.parseDouble(item.get(10)));
|
||||||
|
cashFlow.setSubtotalOfCashOutflowsFromFinancingActivities(Double.parseDouble(item.get(11)));
|
||||||
|
cashFlow.setBeginningBalanceOfCashAndCashEquivalents(Double.parseDouble(item.get(12)));
|
||||||
|
cashFlowRepository.save(cashFlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
setStep((year - 1990) * 100 / (currentYear - 1990));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,24 +29,39 @@ POST {{api_url}}
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"api_name": "income",
|
"api_name": "income_vip",
|
||||||
"token": "{{api_key}}",
|
"token": "{{api_key}}",
|
||||||
"params": {
|
"params": {
|
||||||
"ts_code": "600000.SH"
|
"period": "20241231"
|
||||||
},
|
},
|
||||||
"fields": [
|
"fields": [
|
||||||
"ts_code",
|
"basic_eps",
|
||||||
"ann_date",
|
"diluted_eps",
|
||||||
"fiscal_year",
|
|
||||||
"report_type",
|
|
||||||
"net_profit",
|
|
||||||
"total_revenue",
|
"total_revenue",
|
||||||
"total_cost",
|
"revenue",
|
||||||
"gross_profit",
|
"total_cogs",
|
||||||
"operating_profit",
|
"oper_cost",
|
||||||
"net_profit_before_tax",
|
"sell_exp",
|
||||||
"net_profit_to_parent",
|
"admin_exp",
|
||||||
"total_revenue_to_parent"
|
"fin_exp",
|
||||||
|
"oper_exp",
|
||||||
|
"operate_profit",
|
||||||
|
"non_oper_income",
|
||||||
|
"non_oper_exp",
|
||||||
|
"total_profit",
|
||||||
|
"income_tax",
|
||||||
|
"n_income",
|
||||||
|
"n_income_attr_p",
|
||||||
|
"compr_inc_attr_p",
|
||||||
|
"compr_inc_attr_m_s",
|
||||||
|
"ebit",
|
||||||
|
"ebida",
|
||||||
|
"undist_profit",
|
||||||
|
"distable_profit",
|
||||||
|
"rd_exp",
|
||||||
|
"fin_exp_int_exp",
|
||||||
|
"continued_net_profit",
|
||||||
|
"end_net_profit"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user