- PortfolioRepository: Date -> NavDate 属性名修正 - MarketDataRepository: 修复 TiingoTicker.Ticker 空引用警告
159 lines
4.9 KiB
C#
159 lines
4.9 KiB
C#
using AssetManager.Data;
|
|
using Microsoft.Extensions.Logging;
|
|
using SqlSugar;
|
|
|
|
namespace AssetManager.Data.Repositories;
|
|
|
|
/// <summary>
|
|
/// 投资组合仓储实现
|
|
/// </summary>
|
|
public class PortfolioRepository : IPortfolioRepository
|
|
{
|
|
private readonly ISqlSugarClient _db;
|
|
private readonly ILogger<PortfolioRepository> _logger;
|
|
|
|
public PortfolioRepository(ISqlSugarClient db, ILogger<PortfolioRepository> logger)
|
|
{
|
|
_db = db;
|
|
_logger = logger;
|
|
}
|
|
|
|
// ===== Portfolio =====
|
|
|
|
public async Task<Portfolio?> GetByIdAsync(string id, string userId)
|
|
{
|
|
return await _db.Queryable<Portfolio>()
|
|
.Where(p => p.Id == id && p.UserId == userId)
|
|
.FirstAsync();
|
|
}
|
|
|
|
public async Task<List<Portfolio>> GetByUserIdAsync(string userId)
|
|
{
|
|
return await _db.Queryable<Portfolio>()
|
|
.Where(p => p.UserId == userId)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<Portfolio> CreateAsync(Portfolio portfolio)
|
|
{
|
|
await _db.Insertable(portfolio).ExecuteCommandAsync();
|
|
return portfolio;
|
|
}
|
|
|
|
public async Task<bool> UpdateAsync(Portfolio portfolio)
|
|
{
|
|
portfolio.UpdatedAt = DateTime.Now;
|
|
return await _db.Updateable(portfolio).ExecuteCommandAsync() > 0;
|
|
}
|
|
|
|
public async Task<bool> DeleteAsync(string id, string userId)
|
|
{
|
|
var portfolio = await GetByIdAsync(id, userId);
|
|
if (portfolio == null) return false;
|
|
|
|
// 删除相关数据
|
|
await _db.Deleteable<Position>().Where(p => p.PortfolioId == id).ExecuteCommandAsync();
|
|
await _db.Deleteable<Transaction>().Where(t => t.PortfolioId == id).ExecuteCommandAsync();
|
|
await _db.Deleteable<PortfolioNavHistory>().Where(n => n.PortfolioId == id).ExecuteCommandAsync();
|
|
|
|
return await _db.Deleteable(portfolio).ExecuteCommandAsync() > 0;
|
|
}
|
|
|
|
// ===== Position =====
|
|
|
|
public async Task<List<Position>> GetPositionsByPortfolioIdAsync(string portfolioId)
|
|
{
|
|
return await _db.Queryable<Position>()
|
|
.Where(p => p.PortfolioId == portfolioId)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<Position?> GetPositionAsync(string portfolioId, string stockCode)
|
|
{
|
|
return await _db.Queryable<Position>()
|
|
.Where(p => p.PortfolioId == portfolioId && p.StockCode == stockCode)
|
|
.FirstAsync();
|
|
}
|
|
|
|
public async Task<Position> CreatePositionAsync(Position position)
|
|
{
|
|
position.CreatedAt = DateTime.Now;
|
|
position.UpdatedAt = DateTime.Now;
|
|
await _db.Insertable(position).ExecuteCommandAsync();
|
|
return position;
|
|
}
|
|
|
|
public async Task<bool> UpdatePositionAsync(Position position)
|
|
{
|
|
position.UpdatedAt = DateTime.Now;
|
|
return await _db.Updateable(position).ExecuteCommandAsync() > 0;
|
|
}
|
|
|
|
public async Task<bool> DeletePositionAsync(string positionId)
|
|
{
|
|
return await _db.Deleteable<Position>()
|
|
.Where(p => p.Id == positionId)
|
|
.ExecuteCommandAsync() > 0;
|
|
}
|
|
|
|
// ===== Transaction =====
|
|
|
|
public async Task<List<Transaction>> GetTransactionsAsync(string portfolioId, int limit, int offset)
|
|
{
|
|
return await _db.Queryable<Transaction>()
|
|
.Where(t => t.PortfolioId == portfolioId)
|
|
.OrderByDescending(t => t.TransactionTime)
|
|
.Skip(offset)
|
|
.Take(limit)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<int> GetTransactionCountAsync(string portfolioId)
|
|
{
|
|
return await _db.Queryable<Transaction>()
|
|
.Where(t => t.PortfolioId == portfolioId)
|
|
.CountAsync();
|
|
}
|
|
|
|
public async Task<Transaction> CreateTransactionAsync(Transaction transaction)
|
|
{
|
|
transaction.CreatedAt = DateTime.Now;
|
|
await _db.Insertable(transaction).ExecuteCommandAsync();
|
|
return transaction;
|
|
}
|
|
|
|
// ===== NavHistory =====
|
|
|
|
public async Task<List<PortfolioNavHistory>> GetNavHistoryAsync(string portfolioId, DateTime? startDate, DateTime? endDate)
|
|
{
|
|
var query = _db.Queryable<PortfolioNavHistory>()
|
|
.Where(n => n.PortfolioId == portfolioId);
|
|
|
|
if (startDate.HasValue)
|
|
{
|
|
query = query.Where(n => n.NavDate >= startDate.Value.Date);
|
|
}
|
|
if (endDate.HasValue)
|
|
{
|
|
query = query.Where(n => n.NavDate <= endDate.Value.Date);
|
|
}
|
|
|
|
return await query.OrderBy(n => n.NavDate).ToListAsync();
|
|
}
|
|
|
|
public async Task<int> DeleteNavHistoryAfterDateAsync(string portfolioId, DateTime date)
|
|
{
|
|
return await _db.Deleteable<PortfolioNavHistory>()
|
|
.Where(n => n.PortfolioId == portfolioId && n.NavDate >= date.Date)
|
|
.ExecuteCommandAsync();
|
|
}
|
|
|
|
public async Task<int> CreateNavHistoryBatchAsync(List<PortfolioNavHistory> records)
|
|
{
|
|
if (records == null || records.Count == 0) return 0;
|
|
|
|
return await _db.Insertable(records)
|
|
.ExecuteCommandAsync();
|
|
}
|
|
}
|