feat: 新增ai-stock模块

This commit is contained in:
橙子
2025-03-02 01:54:12 +08:00
parent c1535fd116
commit 287634cf99
38 changed files with 1308 additions and 25 deletions

View File

@@ -0,0 +1,106 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Yi.Framework.Stock.Application.Contracts.Dtos.StockHolding;
using Yi.Framework.Stock.Application.Contracts.Dtos.StockTransaction;
using Yi.Framework.Stock.Application.Contracts.IServices;
using Yi.Framework.Stock.Domain.Entities;
using Yi.Framework.SqlSugarCore.Abstractions;
using Volo.Abp.Users;
namespace Yi.Framework.Stock.Application.Services
{
/// <summary>
/// 用户持仓服务实现
/// </summary>
[Authorize]
public class StockHoldingService : ApplicationService, IStockHoldingService
{
private readonly ISqlSugarRepository<StockHoldingAggregateRoot> _stockHoldingRepository;
private readonly ISqlSugarRepository<StockTransactionEntity> _stockTransactionRepository;
public StockHoldingService(
ISqlSugarRepository<StockHoldingAggregateRoot> stockHoldingRepository,
ISqlSugarRepository<StockTransactionEntity> stockTransactionRepository)
{
_stockHoldingRepository = stockHoldingRepository;
_stockTransactionRepository = stockTransactionRepository;
}
/// <summary>
/// 获取当前用户的持仓列表
/// </summary>
[Authorize]
[HttpGet("stock/user-holdings")]
public async Task<PagedResultDto<StockHoldingDto>> GetUserHoldingsAsync(StockHoldingGetListInputDto input)
{
Guid userId = CurrentUser.GetId();
RefAsync<int> total = 0;
var query = _stockHoldingRepository._DbQueryable
.Where(h => h.UserId == userId)
.WhereIF(!string.IsNullOrEmpty(input.StockCode), h => h.StockCode.Contains(input.StockCode))
.WhereIF(!string.IsNullOrEmpty(input.StockName), h => h.StockName.Contains(input.StockName))
.OrderByIF(!string.IsNullOrEmpty(input.Sorting),input.Sorting)
.OrderByIF(string.IsNullOrEmpty(input.Sorting),t=>t.CreationTime,OrderByType.Desc);
var list = await query
.Select(h => new StockHoldingDto
{
Id = h.Id,
UserId = h.UserId,
StockId = h.StockId,
StockCode = h.StockCode,
StockName = h.StockName,
CreationTime = h.CreationTime
})
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<StockHoldingDto>(total, list);
}
/// <summary>
/// 获取当前用户的交易记录
/// </summary>
[Authorize]
[HttpGet("stock/user-transactions")]
public async Task<PagedResultDto<StockTransactionDto>> GetUserTransactionsAsync(StockTransactionGetListInputDto input)
{
Guid userId = CurrentUser.GetId();
RefAsync<int> total = 0;
var query = _stockTransactionRepository._DbQueryable
.Where(t => t.UserId == userId)
.WhereIF(!string.IsNullOrEmpty(input.StockCode), t => t.StockCode.Contains(input.StockCode))
.WhereIF(!string.IsNullOrEmpty(input.StockName), t => t.StockName.Contains(input.StockName))
.WhereIF(input.TransactionType.HasValue, t => t.TransactionType == input.TransactionType.Value)
.WhereIF(input.StartTime.HasValue, t => t.CreationTime >= input.StartTime.Value)
.WhereIF(input.EndTime.HasValue, t => t.CreationTime <= input.EndTime.Value)
.OrderByIF(!string.IsNullOrEmpty(input.Sorting),input.Sorting)
.OrderByIF(string.IsNullOrEmpty(input.Sorting),t=>t.CreationTime,OrderByType.Desc);
var list = await query
.Select(t => new StockTransactionDto
{
Id = t.Id,
UserId = t.UserId,
StockId = t.StockId,
StockCode = t.StockCode,
StockName = t.StockName,
TransactionType = t.TransactionType,
Price = t.Price,
Quantity = t.Quantity,
TotalAmount = t.TotalAmount,
Fee = t.Fee,
CreationTime = t.CreationTime
})
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<StockTransactionDto>(total, list);
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Yi.Framework.Stock.Application.Contracts.Dtos.StockMarket;
using Yi.Framework.Stock.Application.Contracts.Dtos.StockPrice;
using Yi.Framework.Stock.Application.Contracts.IServices;
using Yi.Framework.Stock.Domain.Entities;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.Stock.Application.Services
{
/// <summary>
/// 股市服务实现
/// </summary>
public class StockMarketService : ApplicationService, IStockMarketService
{
private readonly ISqlSugarRepository<StockMarketAggregateRoot> _stockMarketRepository;
private readonly ISqlSugarRepository<StockPriceRecordEntity> _stockPriceRecordRepository;
public StockMarketService(
ISqlSugarRepository<StockMarketAggregateRoot> stockMarketRepository,
ISqlSugarRepository<StockPriceRecordEntity> stockPriceRecordRepository)
{
_stockMarketRepository = stockMarketRepository;
_stockPriceRecordRepository = stockPriceRecordRepository;
}
/// <summary>
/// 获取股市列表
/// </summary>
[HttpGet("stock/markets")]
public async Task<PagedResultDto<StockMarketDto>> GetStockMarketListAsync(StockMarketGetListInputDto input)
{
RefAsync<int> total = 0;
var query = _stockMarketRepository._DbQueryable
.WhereIF(!string.IsNullOrEmpty(input.MarketCode), m => m.MarketCode.Contains(input.MarketCode))
.WhereIF(!string.IsNullOrEmpty(input.MarketName), m => m.MarketName.Contains(input.MarketName))
.WhereIF(input.State.HasValue, m => m.State == input.State.Value)
.OrderByIF(!string.IsNullOrEmpty(input.Sorting),input.Sorting)
.OrderByIF(string.IsNullOrEmpty(input.Sorting),m=>m.OrderNum,OrderByType.Asc)
.OrderByIF(string.IsNullOrEmpty(input.Sorting),m=>m.CreationTime,OrderByType.Desc);
var list = await query
.Select(m => new StockMarketDto
{
Id = m.Id,
MarketCode = m.MarketCode,
MarketName = m.MarketName,
Description = m.Description,
State = m.State,
CreationTime = m.CreationTime
})
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<StockMarketDto>(total, list);
}
/// <summary>
/// 获取股市价格记录看板
/// </summary>
[HttpGet("stock/price-records")]
public async Task<PagedResultDto<StockPriceRecordDto>> GetStockPriceRecordListAsync(StockPriceRecordGetListInputDto input)
{
RefAsync<int> total = 0;
var query = _stockPriceRecordRepository._DbQueryable
.WhereIF(input.StockId.HasValue, p => p.StockId == input.StockId.Value)
.WhereIF(input.StartTime.HasValue, p => p.CreationTime >= input.StartTime.Value)
.WhereIF(input.EndTime.HasValue, p => p.CreationTime <= input.EndTime.Value)
.WhereIF(input.PeriodType.HasValue, p => p.PeriodType == input.PeriodType.Value)
.OrderByIF(!string.IsNullOrEmpty(input.Sorting),input.Sorting)
.OrderByIF(string.IsNullOrEmpty(input.Sorting),p=>p.CreationTime,OrderByType.Desc);
var list = await query
.Select(p => new StockPriceRecordDto
{
Id = p.Id,
StockId = p.StockId,
CreationTime = p.CreationTime,
CurrentPrice = p.CurrentPrice,
Volume = p.Volume,
Turnover = p.Turnover,
PeriodType = p.PeriodType
})
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<StockPriceRecordDto>(total, list);
}
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Yi.Framework.Stock.Application.Contracts.Dtos.StockNews;
using Yi.Framework.Stock.Application.Contracts.IServices;
using Yi.Framework.Stock.Domain.Entities;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.Stock.Application.Services
{
/// <summary>
/// 股市新闻服务实现
/// </summary>
public class StockNewsService : ApplicationService, IStockNewsService
{
private readonly ISqlSugarRepository<StockNewsAggregateRoot> _stockNewsRepository;
public StockNewsService(ISqlSugarRepository<StockNewsAggregateRoot> stockNewsRepository)
{
_stockNewsRepository = stockNewsRepository;
}
/// <summary>
/// 获取股市新闻列表
/// </summary>
[HttpGet("/api/stock/news")]
public async Task<PagedResultDto<StockNewsDto>> GetStockNewsListAsync(StockNewsGetListInputDto input)
{
RefAsync<int> total = 0;
// 计算10天前的日期
DateTime tenDaysAgo = DateTime.Now.AddDays(-10);
var query = _stockNewsRepository._DbQueryable
.WhereIF(!string.IsNullOrEmpty(input.Title), n => n.Title.Contains(input.Title))
.WhereIF(!string.IsNullOrEmpty(input.Source), n => n.Source.Contains(input.Source))
.WhereIF(input.StartTime.HasValue, n => n.PublishTime >= input.StartTime.Value)
.WhereIF(input.EndTime.HasValue, n => n.PublishTime <= input.EndTime.Value)
// 如果IsRecent为true则只查询最近10天的新闻
.WhereIF(input.IsRecent, n => n.PublishTime >= tenDaysAgo)
.OrderByIF(!string.IsNullOrEmpty(input.Sorting),input.Sorting)
.OrderByIF(string.IsNullOrEmpty(input.Sorting),n=>n.OrderNum,OrderByType.Asc)
.OrderByIF(string.IsNullOrEmpty(input.Sorting),n=>n.PublishTime,OrderByType.Desc) ;
var list = await query
.Select(n => new StockNewsDto
{
Id = n.Id,
Title = n.Title,
Content = n.Content,
PublishTime = n.PublishTime,
Source = n.Source,
CreationTime = n.CreationTime,
OrderNum = n.OrderNum
})
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<StockNewsDto>(total, list);
}
}
}

View File

@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<ItemGroup>
<ProjectReference Include="..\..\..\framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj" />
<ProjectReference Include="..\Yi.Framework.Stock.Application.Contracts\Yi.Framework.Stock.Application.Contracts.csproj" />
<ProjectReference Include="..\Yi.Framework.Stock.Domain\Yi.Framework.Stock.Domain.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,17 @@
using Yi.Framework.Stock.Application.Contracts;
using Yi.Framework.Stock.Domain;
using Yi.Framework.Ddd.Application;
namespace Yi.Framework.Stock.Application
{
[DependsOn(
typeof(YiFrameworkStockApplicationContractsModule),
typeof(YiFrameworkStockDomainModule),
typeof(YiFrameworkDddApplicationModule)
)]
public class YiFrameworkStockApplicationModule : AbpModule
{
}
}