fix 字段名称错误

This commit is contained in:
niannian zheng 2026-03-15 21:44:48 +08:00
parent 60f3b487ff
commit 49b9adfdab
5 changed files with 77 additions and 75 deletions

View File

@ -45,7 +45,7 @@ public class PortfolioController : ControllerBase
var response = await _portfolioFacade.CreatePortfolioWithValidationAsync(request, userId);
return Ok(new ApiResponse<CreatePortfolioResponse>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = response,
message = "创建成功"
});
@ -54,7 +54,7 @@ public class PortfolioController : ControllerBase
{
return BadRequest(new ApiResponse<CreatePortfolioResponse>
{
code = StatusCodes.BadRequest,
code = Models.StatusCodes.BadRequest,
data = null,
message = ex.Message
});
@ -72,7 +72,7 @@ public class PortfolioController : ControllerBase
return Ok(new ApiResponse<List<PortfolioListItem>>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = portfolios,
message = "success"
});
@ -91,7 +91,7 @@ public class PortfolioController : ControllerBase
var portfolio = await _portfolioFacade.GetPortfolioDetailAsync(id, userId);
return Ok(new ApiResponse<PortfolioDetailResponse>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = portfolio,
message = "success"
});
@ -100,7 +100,7 @@ public class PortfolioController : ControllerBase
{
return NotFound(new ApiResponse<PortfolioDetailResponse>
{
code = StatusCodes.NotFound,
code = Models.StatusCodes.NotFound,
data = null,
message = "组合不存在"
});
@ -120,7 +120,7 @@ public class PortfolioController : ControllerBase
{
return NotFound(new ApiResponse<object>
{
code = StatusCodes.NotFound,
code = Models.StatusCodes.NotFound,
data = null,
message = "组合不存在"
});
@ -128,7 +128,7 @@ public class PortfolioController : ControllerBase
return Ok(new ApiResponse<object>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = null,
message = "删除成功"
});
@ -148,9 +148,9 @@ public class PortfolioController : ControllerBase
var request = new NavHistoryRequest
{
startDate = startDate,
endDate = endDate,
interval = interval ?? "daily"
StartDate = startDate,
EndDate = endDate,
Interval = interval ?? "daily"
};
try
@ -158,7 +158,7 @@ public class PortfolioController : ControllerBase
var response = await _portfolioFacade.GetNavHistoryAsync(id, request, userId);
return Ok(new ApiResponse<NavHistoryResponse>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = response,
message = "success"
});
@ -167,7 +167,7 @@ public class PortfolioController : ControllerBase
{
return NotFound(new ApiResponse<NavHistoryResponse>
{
code = StatusCodes.NotFound,
code = Models.StatusCodes.NotFound,
data = null,
message = "组合不存在"
});
@ -189,7 +189,7 @@ public class PortfolioController : ControllerBase
var response = await _portfolioFacade.BackfillNavHistoryAsync(id, userId, force);
return Ok(new ApiResponse<BackfillNavResponse>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = response,
message = "success"
});
@ -198,7 +198,7 @@ public class PortfolioController : ControllerBase
{
return NotFound(new ApiResponse<BackfillNavResponse>
{
code = StatusCodes.NotFound,
code = Models.StatusCodes.NotFound,
data = null,
message = "组合不存在"
});
@ -220,7 +220,7 @@ public class PortfolioController : ControllerBase
var transaction = await _portfolioFacade.CreateTransactionAsync(id, request, userId);
return Ok(new ApiResponse<TransactionItem>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = transaction,
message = "交易创建成功"
});
@ -229,7 +229,7 @@ public class PortfolioController : ControllerBase
{
return NotFound(new ApiResponse<TransactionItem>
{
code = StatusCodes.NotFound,
code = Models.StatusCodes.NotFound,
data = null,
message = "组合不存在"
});
@ -249,20 +249,20 @@ public class PortfolioController : ControllerBase
var request = new GetTransactionsRequest
{
portfolioId = id,
limit = limit,
offset = offset
PortfolioId = id,
Limit = limit,
Offset = offset
};
var transactions = await _portfolioFacade.GetTransactionsAsync(id, request, userId);
return Ok(new ApiResponse<GetTransactionsResponse>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = new GetTransactionsResponse
{
items = transactions,
total = transactions.Count
Items = transactions,
Total = transactions.Count
},
message = "success"
});
@ -281,7 +281,7 @@ public class PortfolioController : ControllerBase
var signal = await _portfolioFacade.GetStrategySignalAsync(id, userId);
return Ok(new ApiResponse<StrategySignalResponse>
{
code = StatusCodes.Success,
code = Models.StatusCodes.Success,
data = signal,
message = "success"
});
@ -290,7 +290,7 @@ public class PortfolioController : ControllerBase
{
return NotFound(new ApiResponse<StrategySignalResponse>
{
code = StatusCodes.NotFound,
code = Models.StatusCodes.NotFound,
data = null,
message = "组合不存在"
});

View File

@ -28,7 +28,7 @@ public class StrategyController : ControllerBase
return User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? throw new Exception("User not authenticated");
}
private StrategyListItemDTO MapToStrategyListItemDTO(Strategy strategy)
private StrategyListItemDto MapToStrategyListItemDTO(Strategy strategy)
{
List<string> tags = new List<string>();
if (!string.IsNullOrEmpty(strategy.Tags))
@ -41,18 +41,18 @@ public class StrategyController : ControllerBase
catch { }
}
return new StrategyListItemDTO
return new StrategyListItemDto
{
id = strategy.Id,
userId = strategy.UserId,
name = strategy.Alias,
type = strategy.Type,
description = strategy.Description,
tags = tags,
riskLevel = strategy.RiskLevel,
config = strategy.Config,
createdAt = strategy.CreatedAt,
updatedAt = strategy.UpdatedAt
Id = strategy.Id,
UserId = strategy.UserId,
Name = strategy.Alias,
Type = strategy.Type,
Description = strategy.Description,
Tags = tags,
RiskLevel = strategy.RiskLevel,
Config = strategy.Config,
CreatedAt = strategy.CreatedAt,
UpdatedAt = strategy.UpdatedAt
};
}
@ -64,7 +64,7 @@ public class StrategyController : ControllerBase
/// 此接口用于获取当前登录用户的所有策略列表。
/// </remarks>
[HttpGet("strategies")]
public ActionResult<ApiResponse<List<StrategyListItemDTO>>> GetStrategies()
public ActionResult<ApiResponse<List<StrategyListItemDto>>> GetStrategies()
{
try
{
@ -76,7 +76,7 @@ public class StrategyController : ControllerBase
_logger.LogInformation("Strategies retrieved successfully");
return Ok(new ApiResponse<List<StrategyListItemDTO>>
return Ok(new ApiResponse<List<StrategyListItemDto>>
{
code = AssetManager.Models.StatusCodes.Success,
data = strategyListItems,
@ -87,7 +87,7 @@ public class StrategyController : ControllerBase
{
_logger.LogError(ex, "Error retrieving strategies");
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<List<StrategyListItemDTO>>
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<List<StrategyListItemDto>>
{
code = AssetManager.Models.StatusCodes.InternalServerError,
data = null,
@ -105,7 +105,7 @@ public class StrategyController : ControllerBase
/// 此接口用于获取指定策略的详细信息。
/// </remarks>
[HttpGet("{id}")]
public ActionResult<ApiResponse<StrategyListItemDTO>> GetStrategyById(string id)
public ActionResult<ApiResponse<StrategyListItemDto>> GetStrategyById(string id)
{
try
{
@ -117,7 +117,7 @@ public class StrategyController : ControllerBase
_logger.LogInformation($"Strategy {id} retrieved successfully");
return Ok(new ApiResponse<StrategyListItemDTO>
return Ok(new ApiResponse<StrategyListItemDto>
{
code = AssetManager.Models.StatusCodes.Success,
data = strategyItem,
@ -128,7 +128,7 @@ public class StrategyController : ControllerBase
{
_logger.LogError(ex, $"Error retrieving strategy {id}");
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDTO>
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDto>
{
code = AssetManager.Models.StatusCodes.InternalServerError,
data = null,
@ -146,11 +146,11 @@ public class StrategyController : ControllerBase
/// 此接口用于创建新的策略。
/// </remarks>
[HttpPost]
public ActionResult<ApiResponse<StrategyListItemDTO>> CreateStrategy([FromBody] CreateStrategyRequest request)
public ActionResult<ApiResponse<StrategyListItemDto>> CreateStrategy([FromBody] CreateStrategyRequest request)
{
try
{
_logger.LogInformation($"Request to create strategy: {request.name}");
_logger.LogInformation($"Request to create strategy: {request.Name}");
var userId = GetCurrentUserId();
var strategy = _strategyService.CreateStrategy(request, userId);
@ -158,7 +158,7 @@ public class StrategyController : ControllerBase
_logger.LogInformation($"Strategy {strategy.Id} created successfully");
return Ok(new ApiResponse<StrategyListItemDTO>
return Ok(new ApiResponse<StrategyListItemDto>
{
code = AssetManager.Models.StatusCodes.Success,
data = strategyItem,
@ -169,7 +169,7 @@ public class StrategyController : ControllerBase
{
_logger.LogError(ex, "Error creating strategy");
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDTO>
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDto>
{
code = AssetManager.Models.StatusCodes.InternalServerError,
data = null,
@ -188,7 +188,7 @@ public class StrategyController : ControllerBase
/// 此接口用于更新指定策略的信息。
/// </remarks>
[HttpPut("{id}")]
public ActionResult<ApiResponse<StrategyListItemDTO>> UpdateStrategy(string id, [FromBody] UpdateStrategyRequest request)
public ActionResult<ApiResponse<StrategyListItemDto>> UpdateStrategy(string id, [FromBody] UpdateStrategyRequest request)
{
try
{
@ -200,7 +200,7 @@ public class StrategyController : ControllerBase
_logger.LogInformation($"Strategy {id} updated successfully");
return Ok(new ApiResponse<StrategyListItemDTO>
return Ok(new ApiResponse<StrategyListItemDto>
{
code = AssetManager.Models.StatusCodes.Success,
data = strategyItem,
@ -211,7 +211,7 @@ public class StrategyController : ControllerBase
{
_logger.LogError(ex, $"Error updating strategy {id}");
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDTO>
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategyListItemDto>
{
code = AssetManager.Models.StatusCodes.InternalServerError,
data = null,

View File

@ -54,15 +54,15 @@ public class PortfolioService : IPortfolioService
.Where(s => s.Id == request.StrategyId && s.UserId == userId)
.First();
if (strategy != null && !string.IsNullOrEmpty(strategy.Config))
if (Strategy != null && !string.IsNullOrEmpty(Strategy.Config))
{
try
{
// 风险平价策略
if (strategy.Type?.Equals("risk_parity", StringComparison.OrdinalIgnoreCase) == true)
if (Strategy.Type?.Equals("risk_parity", StringComparison.OrdinalIgnoreCase) == true)
{
// 处理可能的双层转义
string configJson = strategy.Config;
string configJson = Strategy.Config;
if (configJson.StartsWith("\"") && configJson.EndsWith("\""))
{
// 去掉外层的引号和转义
@ -219,7 +219,7 @@ public class PortfolioService : IPortfolioService
.Where(pos => pos.PortfolioId == portfolio.Id)
.ToList();
foreach (var pos in positions)
foreach (var pos in Positions)
{
if (pos.StockCode == null || pos.Currency == null)
{
@ -235,7 +235,7 @@ public class PortfolioService : IPortfolioService
if (priceResponse.Price > 0)
{
CurrentPrice = priceResponse.Price;
previousClose = priceResponse.PreviousClose > 0 ? priceResponse.PreviousClose : currentPrice;
previousClose = priceResponse.PreviousClose > 0 ? priceResponse.PreviousClose : CurrentPrice;
}
}
catch (Exception ex)
@ -243,14 +243,14 @@ public class PortfolioService : IPortfolioService
_logger.LogWarning(ex, "获取标的 {StockCode} 实时价格失败,使用成本价作为当前价", pos.StockCode);
}
decimal currentPositionValue = pos.Shares * currentPrice;
decimal currentPositionValue = pos.Shares * CurrentPrice;
decimal costPositionValue = pos.Shares * pos.AvgPrice;
decimal TodayProfit = previousClose > 0 ? pos.Shares * (currentPrice - previousClose) : 0;
decimal TodayProfit = previousClose > 0 ? pos.Shares * (CurrentPrice - previousClose) : 0;
// 换算到目标本位币
decimal currentInTarget = await _exchangeRateService.ConvertAmountAsync(currentPositionValue, pos.Currency, targetCurrency);
decimal costInTarget = await _exchangeRateService.ConvertAmountAsync(costPositionValue, pos.Currency, targetCurrency);
decimal todayProfitInTarget = await _exchangeRateService.ConvertAmountAsync(todayProfit, pos.Currency, targetCurrency);
decimal todayProfitInTarget = await _exchangeRateService.ConvertAmountAsync(TodayProfit, pos.Currency, targetCurrency);
_logger.LogInformation("标的 {StockCode} 换算: {Amount} {From} → {Converted} {To},汇率: {Rate}",
pos.StockCode, currentPositionValue, pos.Currency, currentInTarget, targetCurrency,
@ -302,7 +302,7 @@ public class PortfolioService : IPortfolioService
decimal totalTodayProfit = 0;
var positionItems = new List<PositionItem>();
foreach (var pos in positions)
foreach (var pos in Positions)
{
if (pos.StockCode == null || pos.Currency == null)
{
@ -318,7 +318,7 @@ public class PortfolioService : IPortfolioService
if (priceResponse.Price > 0)
{
CurrentPrice = priceResponse.Price;
previousClose = priceResponse.PreviousClose > 0 ? priceResponse.PreviousClose : currentPrice;
previousClose = priceResponse.PreviousClose > 0 ? priceResponse.PreviousClose : CurrentPrice;
}
}
catch (Exception ex)
@ -326,16 +326,16 @@ public class PortfolioService : IPortfolioService
_logger.LogWarning(ex, "获取标的 {StockCode} 实时价格失败,使用成本价作为当前价", pos.StockCode);
}
decimal positionValue = pos.Shares * currentPrice;
decimal positionValue = pos.Shares * CurrentPrice;
decimal cost = pos.Shares * pos.AvgPrice;
decimal Profit = positionValue - cost;
double ProfitRate = cost > 0 ? (double)(profit / cost * 100) : 0;
decimal TodayProfit = previousClose > 0 ? pos.Shares * (currentPrice - previousClose) : 0;
double ProfitRate = cost > 0 ? (double)(Profit / cost * 100) : 0;
decimal TodayProfit = previousClose > 0 ? pos.Shares * (CurrentPrice - previousClose) : 0;
// 转换为组合本位币
decimal positionValueInTarget = await _exchangeRateService.ConvertAmountAsync(positionValue, pos.Currency, targetCurrency);
decimal costInTarget = await _exchangeRateService.ConvertAmountAsync(cost, pos.Currency, targetCurrency);
decimal todayProfitInTarget = await _exchangeRateService.ConvertAmountAsync(todayProfit, pos.Currency, targetCurrency);
decimal todayProfitInTarget = await _exchangeRateService.ConvertAmountAsync(TodayProfit, pos.Currency, targetCurrency);
totalPortfolioValue += positionValueInTarget;
totalCost += costInTarget;
@ -349,10 +349,10 @@ public class PortfolioService : IPortfolioService
Symbol = pos.StockCode,
Amount = (int)pos.Shares,
AveragePrice = (double)pos.AvgPrice,
CurrentPrice = (double)currentPrice,
CurrentPrice = (double)TodayProfit,
TotalValue = (double)positionValueInTarget,
Profit = (double)(positionValueInTarget - costInTarget),
ProfitRate = profitRate,
ProfitRate = ProfitRate,
ChangeAmount = (double)todayProfitInTarget,
Ratio = 0, // 后面统一计算比例
DeviationRatio = 0, // 后续实现
@ -367,7 +367,7 @@ public class PortfolioService : IPortfolioService
}
decimal TotalReturn = totalPortfolioValue - totalCost;
double totalReturnRate = totalCost > 0 ? (double)(totalReturn / totalCost * 100) : 0;
double totalReturnRate = totalCost > 0 ? (double)(TotalReturn / totalCost * 100) : 0;
return new PortfolioDetailResponse
{
@ -382,7 +382,7 @@ public class PortfolioService : IPortfolioService
Description = "策略描述"
},
PortfolioValue = (double)totalPortfolioValue,
TotalReturn = (double)totalReturn,
TotalReturn = (double)TotalReturn,
TodayProfit = (double)totalTodayProfit,
HistoricalChange = totalReturnRate,
DailyVolatility = 0, // 后续实现
@ -390,7 +390,7 @@ public class PortfolioService : IPortfolioService
LogicModel = "HFEA 风险平价逻辑",
LogicModelStatus = "监控中",
LogicModelDescription = "目标权重 季度调仓",
TotalItems = positions.Count,
TotalItems = Positions.Count,
TotalRatio = 100.0,
Positions = positionItems
};
@ -576,7 +576,7 @@ public class PortfolioService : IPortfolioService
.ToList();
decimal totalPortfolioValue = 0;
foreach (var pos in positions)
foreach (var pos in Positions)
{
if (pos.StockCode == null)
{
@ -598,7 +598,7 @@ public class PortfolioService : IPortfolioService
_logger.LogWarning(ex, "获取标的 {StockCode} 实时价格失败,使用成本价计算组合总价值", pos.StockCode);
}
totalPortfolioValue += pos.Shares * currentPrice;
totalPortfolioValue += pos.Shares * CurrentPrice;
}
portfolio.TotalValue = totalPortfolioValue;
@ -648,7 +648,7 @@ public class PortfolioService : IPortfolioService
public Task<List<TransactionItem>> GetTransactionsAsync(string portfolioId, GetTransactionsRequest request, string userId)
{
var response = GetTransactions(portfolioId, userId, request.limit, request.offset);
var response = GetTransactions(portfolioId, userId, request.Limit, request.Offset);
return Task.FromResult(response.Items ?? new List<TransactionItem>());
}
@ -659,7 +659,7 @@ public class PortfolioService : IPortfolioService
return new TransactionItem
{
Id = response.id,
Id = response.Id,
PortfolioId = portfolioId,
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
@ -667,7 +667,7 @@ public class PortfolioService : IPortfolioService
StockCode = request.StockCode,
Amount = response.TotalAmount,
Currency = request.Currency,
Status = response.status,
Status = response.Status,
Remark = request.Remark
};
}
@ -687,9 +687,9 @@ public class PortfolioService : IPortfolioService
var Positions = _db.Queryable<Position>()
.Where(pos => pos.PortfolioId == portfolioId)
.ToList();
if (positions.Any())
if (Positions.Any())
{
_db.Deleteable(positions).ExecuteCommand();
_db.Deleteable(Positions).ExecuteCommand();
}
// 删除相关交易

View File

@ -1,6 +1,7 @@
using AssetManager.Data;
using AssetManager.Data.Repositories;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
using SqlSugar;
using Xunit;

View File

@ -3,6 +3,7 @@ using AssetManager.Infrastructure.Services;
using AssetManager.Models.DTOs;
using AssetManager.Services;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
using SqlSugar;
using Xunit;