1
0

Compare commits

...

3 Commits

Author SHA1 Message Date
697a58a0e4 feat: 增加财务指标显示 2025-09-15 18:42:36 +08:00
b569d62a25 fix: 修复大数字显示 2025-09-15 15:20:05 +08:00
d3538ddce0 fix: 修复流动和长期负债的取值 2025-09-15 13:59:01 +08:00
3 changed files with 173 additions and 35 deletions

View File

@@ -9,6 +9,7 @@ import com.lanyuanxiaoyao.service.template.controller.SimpleControllerSupport;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.RestController;
* @author lanyuanxiaoyao * @author lanyuanxiaoyao
* @version 20250829 * @version 20250829
*/ */
@Slf4j
@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> {
@@ -50,9 +52,9 @@ public class StockController extends SimpleControllerSupport<Stock, Void, StockC
NumberHelper.formatPercentageDouble(fi.getFixedAssetsToTotalAssetsRatio()), NumberHelper.formatPercentageDouble(fi.getFixedAssetsToTotalAssetsRatio()),
NumberHelper.formatFinanceDouble(fi.getTotalLiabilities()), NumberHelper.formatFinanceDouble(fi.getTotalLiabilities()),
NumberHelper.formatFinanceDouble(fi.getCurrentLiabilities()), NumberHelper.formatFinanceDouble(fi.getCurrentLiabilities()),
NumberHelper.formatPercentageDouble(fi.getCurrentLiabilitiesToTotalLiabilitiesRatio()), NumberHelper.formatPercentageDouble(fi.getCurrentLiabilitiesToTotalAssetsRatio()),
NumberHelper.formatFinanceDouble(fi.getLongTermLiabilities()), NumberHelper.formatFinanceDouble(fi.getLongTermLiabilities()),
NumberHelper.formatPercentageDouble(fi.getLongTermLiabilitiesToTotalLiabilitiesRatio()) NumberHelper.formatPercentageDouble(fi.getLongTermLiabilitiesToTotalAssetsRatio())
)) ))
.orElse(new BalanceSheetItem()), .orElse(new BalanceSheetItem()),
financeIndicator financeIndicator
@@ -64,9 +66,28 @@ public class StockController extends SimpleControllerSupport<Stock, Void, StockC
.orElse(new IncomeItem()), .orElse(new IncomeItem()),
financeIndicator financeIndicator
.map(fi -> new CashFlowItem( .map(fi -> new CashFlowItem(
NumberHelper.formatFinanceDouble(fi.getNetProfit()) NumberHelper.formatFinanceDouble(fi.getNetProfit()),
NumberHelper.formatFinanceDouble(fi.getCashFlowFromOperatingActivities()),
NumberHelper.formatFinanceDouble(fi.getCashFlowFromInvestingActivities()),
NumberHelper.formatFinanceDouble(fi.getCashFlowFromFinancingActivities())
)) ))
.orElse(new CashFlowItem()) .orElse(new CashFlowItem()),
financeIndicator
.map(fi -> new IndicateItem(
NumberHelper.formatFinanceDouble(fi.getCurrentRatio()),
NumberHelper.formatFinanceDouble(fi.getQuickRatio()),
NumberHelper.formatFinanceDouble(fi.getReturnOnEquity()),
NumberHelper.formatFinanceDouble(fi.getReturnOnAssets()),
NumberHelper.formatFinanceDouble(fi.getAccountsReceivableTurnover()),
NumberHelper.formatDaysDouble(fi.getDaysAccountsReceivableTurnover()),
NumberHelper.formatFinanceDouble(fi.getInventoryTurnover()),
NumberHelper.formatDaysDouble(fi.getDaysInventoryTurnover()),
NumberHelper.formatFinanceDouble(fi.getFixedAssetsTurnover()),
NumberHelper.formatDaysDouble(fi.getDaysFixedAssetsTurnover()),
NumberHelper.formatFinanceDouble(fi.getTotalAssetsTurnover()),
NumberHelper.formatDaysDouble(fi.getDaysTotalAssetsTurnover())
))
.orElse(new IndicateItem())
)); ));
} }
@@ -123,7 +144,8 @@ public class StockController extends SimpleControllerSupport<Stock, Void, StockC
Integer year, Integer year,
BalanceSheetItem balanceSheet, BalanceSheetItem balanceSheet,
IncomeItem income, IncomeItem income,
CashFlowItem cashFlow CashFlowItem cashFlow,
IndicateItem indicate
) { ) {
} }
@@ -170,10 +192,48 @@ public class StockController extends SimpleControllerSupport<Stock, Void, StockC
} }
public record CashFlowItem( public record CashFlowItem(
String netProfit String netProfit,
String cashFlowFromOperatingActivities,
String cashFlowFromInvestingActivities,
String cashFlowFromFinancingActivities
) { ) {
public CashFlowItem() { public CashFlowItem() {
this( this(
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE
);
}
}
public record IndicateItem(
String currentRatio,
String quickRatio,
String roe,
String roa,
String accountsReceivableTurnover,
String daysAccountsReceivableTurnover,
String inventoryTurnover,
String daysInventoryTurnover,
String fixedAssetsTurnover,
String daysFixedAssetsTurnover,
String totalAssetsTurnover,
String daysTotalAssetsTurnover
) {
public IndicateItem() {
this(
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE,
NumberHelper.FINANCE_NULL_DOUBLE NumberHelper.FINANCE_NULL_DOUBLE
); );
} }

View File

@@ -16,19 +16,23 @@ public class NumberHelper {
if (ObjectUtil.isNull(value)) { if (ObjectUtil.isNull(value)) {
return FINANCE_NULL_DOUBLE; return FINANCE_NULL_DOUBLE;
} }
var builder = new StringBuilder(); var result = FINANCE_NULL_DOUBLE;
if (value > 100000000) { var absValue = Double.valueOf(Math.abs(value));
builder.append(value.longValue() / 100000000).append("亿"); if (absValue > 100000000) {
value = value % 100000000; result = NumberUtil.decimalFormat("#.##亿", absValue / 100000000);
} else if (value > 10000) {
result = NumberUtil.decimalFormat("#.##万", absValue / 10000);
} else {
result = NumberUtil.decimalFormat("#.##", absValue);
} }
if (value > 10000) { return value < 0 ? "-" + result : result;
builder.append(value.longValue() / 10000).append(""); }
value = value % 10000;
public static String formatDaysDouble(Double value) {
if (ObjectUtil.isNull(value)) {
return FINANCE_NULL_DOUBLE;
} }
if (value > 0) { return NumberUtil.decimalFormat("#", value);
builder.append(NumberUtil.decimalFormat("#.##", value));
}
return builder.toString();
} }
public static String formatPercentageDouble(Double value) { public static String formatPercentageDouble(Double value) {

View File

@@ -4,7 +4,6 @@ import {amisRender, commonInfo, readOnlyDialogOptions, remoteMappings} from '../
import type {Schema} from 'amis' import type {Schema} from 'amis'
import {isNil} from 'es-toolkit' import {isNil} from 'es-toolkit'
// 格式化财务数字显示的公共函数
const formatFinanceNumber = (value: number): string => { const formatFinanceNumber = (value: number): string => {
if (isNil(value)) { if (isNil(value)) {
return '-' return '-'
@@ -25,7 +24,13 @@ const formatFinanceNumber = (value: number): string => {
return isNegative ? `-${formatted}` : formatted return isNegative ? `-${formatted}` : formatted
} }
// 格式化百分比数字显示的公共函数 const formatDaysNumber = (value: number): string => {
if (isNil(value)) {
return '-'
}
return `${value.toFixed(0)}`
}
const formatPercentageNumber = (value: number): string => { const formatPercentageNumber = (value: number): string => {
if (isNil(value)) { if (isNil(value)) {
return '-' return '-'
@@ -33,7 +38,7 @@ const formatPercentageNumber = (value: number): string => {
return `${(value * 100).toFixed(2)}%` return `${(value * 100).toFixed(2)}%`
} }
type FinanceType = 'PERCENTAGE' | 'FINANCE' type FinanceType = 'PERCENTAGE' | 'FINANCE' | 'DAYS'
const financePropertyLabel = (id: string | undefined, label: string, type: FinanceType, field: string): Schema => { const financePropertyLabel = (id: string | undefined, label: string, type: FinanceType, field: string): Schema => {
if (!id) { if (!id) {
@@ -43,7 +48,20 @@ const financePropertyLabel = (id: string | undefined, label: string, type: Finan
} }
} }
let current = new Date().getFullYear() let current = new Date().getFullYear()
let formatter: (value: number) => string = type === 'PERCENTAGE' ? formatPercentageNumber : formatFinanceNumber let formatter: (value: number) => string
switch (type) {
case 'PERCENTAGE':
formatter = formatPercentageNumber
break
case 'FINANCE':
formatter = formatFinanceNumber
break
case 'DAYS':
formatter = formatDaysNumber
break
default:
formatter = (v: number) => v.toFixed(2)
}
return { return {
type: 'wrapper', type: 'wrapper',
size: 'none', size: 'none',
@@ -229,29 +247,21 @@ function StockDetail() {
{ {
label: financePropertyLabel(id, '总资产', 'FINANCE', 'totalAssets'), label: financePropertyLabel(id, '总资产', 'FINANCE', 'totalAssets'),
content: '${balanceSheet.totalAssets}', content: '${balanceSheet.totalAssets}',
span: 4, span: 2,
},
{
label: financePropertyLabel(id, '总负债', 'FINANCE', 'totalLiabilities'),
content: '${balanceSheet.totalLiabilities}',
span: 2,
}, },
{ {
label: financePropertyLabel(id, '流动资产', 'FINANCE', 'currentAssets'), label: financePropertyLabel(id, '流动资产', 'FINANCE', 'currentAssets'),
content: '${balanceSheet.currentAssets}', content: '${balanceSheet.currentAssets}',
}, },
{
label: financePropertyLabel(id, '流动资产占比', 'PERCENTAGE', 'currentAssetsToTotalAssetsRatio'),
content: '${balanceSheet.currentAssetsRatio}',
},
{
label: financePropertyLabel(id, '非流动资产', 'FINANCE', 'fixedAssets'),
content: '${balanceSheet.fixedAssets}',
},
{ {
label: financePropertyLabel(id, '非流动资产占比', 'PERCENTAGE', 'fixedAssetsToTotalAssetsRatio'), label: financePropertyLabel(id, '非流动资产占比', 'PERCENTAGE', 'fixedAssetsToTotalAssetsRatio'),
content: '${balanceSheet.fixedAssetsRatio}', content: '${balanceSheet.fixedAssetsRatio}',
}, },
{
label: financePropertyLabel(id, '总负债', 'FINANCE', 'totalLiabilities'),
content: '${balanceSheet.totalLiabilities}',
span: 4,
},
{ {
label: financePropertyLabel(id, '流动负债', 'FINANCE', 'currentLiabilities'), label: financePropertyLabel(id, '流动负债', 'FINANCE', 'currentLiabilities'),
content: '${balanceSheet.currentLiabilities}', content: '${balanceSheet.currentLiabilities}',
@@ -260,6 +270,14 @@ function StockDetail() {
label: financePropertyLabel(id, '流动负债占比', 'PERCENTAGE', 'currentLiabilitiesToTotalAssetsRatio'), label: financePropertyLabel(id, '流动负债占比', 'PERCENTAGE', 'currentLiabilitiesToTotalAssetsRatio'),
content: '${balanceSheet.currentLiabilitiesRatio}', content: '${balanceSheet.currentLiabilitiesRatio}',
}, },
{
label: financePropertyLabel(id, '流动资产占比', 'PERCENTAGE', 'currentAssetsToTotalAssetsRatio'),
content: '${balanceSheet.currentAssetsRatio}',
},
{
label: financePropertyLabel(id, '非流动资产', 'FINANCE', 'fixedAssets'),
content: '${balanceSheet.fixedAssets}',
},
{ {
label: financePropertyLabel(id, '非流动负债', 'FINANCE', 'longTermLiabilities'), label: financePropertyLabel(id, '非流动负债', 'FINANCE', 'longTermLiabilities'),
content: '${balanceSheet.longTermLiabilities}', content: '${balanceSheet.longTermLiabilities}',
@@ -300,6 +318,62 @@ function StockDetail() {
}, },
], ],
}, },
'财务指标',
{
className: 'my-2',
type: 'property',
column: 4,
items: [
{
label: financePropertyLabel(id, '流动比率', 'FINANCE', 'currentRatio'),
content: '${indicate.currentRatio}',
},
{
label: financePropertyLabel(id, '速动比率', 'FINANCE', 'quickRatio'),
content: '${indicate.quickRatio}',
},
{
label: financePropertyLabel(id, 'ROE', 'FINANCE', 'returnOnEquity'),
content: '${indicate.roe}',
},
{
label: financePropertyLabel(id, 'ROA', 'FINANCE', 'returnOnAssets'),
content: '${indicate.roa}',
},
{
label: financePropertyLabel(id, '应收账款周转率', 'FINANCE', 'accountsReceivableTurnover'),
content: '${indicate.accountsReceivableTurnover}',
},
{
label: financePropertyLabel(id, '应收账款周转天', 'DAYS', 'daysAccountsReceivableTurnover'),
content: '${indicate.daysAccountsReceivableTurnover}',
},
{
label: financePropertyLabel(id, '存货周转率', 'FINANCE', 'inventoryTurnover'),
content: '${indicate.inventoryTurnover}',
},
{
label: financePropertyLabel(id, '存货周转天', 'DAYS', 'daysInventoryTurnover'),
content: '${indicate.daysInventoryTurnover}',
},
{
label: financePropertyLabel(id, '固定资产周转率', 'FINANCE', 'fixedAssetsTurnover'),
content: '${indicate.fixedAssetsTurnover}',
},
{
label: financePropertyLabel(id, '固定资产周转天', 'DAYS', 'daysFixedAssetsTurnover'),
content: '${indicate.daysFixedAssetsTurnover}',
},
{
label: financePropertyLabel(id, '总资产周转率', 'FINANCE', 'totalAssetsTurnover'),
content: '${indicate.totalAssetsTurnover}',
},
{
label: financePropertyLabel(id, '总资产周转天', 'DAYS', 'daysTotalAssetsTurnover'),
content: '${indicate.daysTotalAssetsTurnover}',
},
],
},
{type: 'divider'}, {type: 'divider'},
], ],
}, },