feat: 新增功能

- 移除 OpenApiService.GenerateContentAsync 的 isAsync 查询参数及其分支处理(不再在该接口直接创建并返回 ImageStore 任务 Id)。
- 保留 alt=sse 的代理处理逻辑。
- 在 ImageStoreTaskAggregateRoot 中新增字段:
  - Prompt:提示词(大文本)
  - ReferenceImageUrls:参考图 URL 列表(JSON 存储)
- 兼容性提示:接口去掉了 isAsync 参数,调用方需相应调整异步任务创建流程。
This commit is contained in:
chenchun
2025-12-26 18:29:47 +08:00
parent 599b6335d5
commit 34246d8a62
3 changed files with 142 additions and 14 deletions

129
Yi.Abp.Net8/CLAUDE.md Normal file
View File

@@ -0,0 +1,129 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
Yi.Abp.Net8 is a modular, multi-tenant SaaS platform built on ABP Framework 8.3.4 with .NET 8.0. It uses **SqlSugar** (not EF Core) as the ORM and follows Domain-Driven Design (DDD) principles. The platform includes AI/ML features (chat, models, agents, token tracking), RBAC, forum, messaging, and digital collectibles modules.
## Architecture
### Solution Structure
```
Yi.Abp.Net8/
├── src/ # Main application host
│ └── Yi.Abp.Web/ # ASP.NET Core 8.0 Web Host (port 19001)
├── framework/ # Framework layer (shared infrastructure)
│ ├── Yi.Framework.Core # Core utilities, JSON handling
│ ├── Yi.Framework.SqlSugarCore # SqlSugar ORM abstraction (v5.1.4.197-preview22)
│ ├── Yi.Framework.SqlSugarCore.Abstractions # Repository interfaces
│ ├── Yi.Framework.AspNetCore # ASP.NET Core extensions
│ ├── Yi.Framework.AspNetCore.Authentication.OAuth # QQ, Gitee OAuth
│ ├── Yi.Framework.Ddd.Application # DDD application base classes
│ ├── Yi.Framework.BackgroundWorkers.Hangfire # Job scheduling
│ ├── Yi.Framework.Caching.FreeRedis # Redis caching
│ └── Yi.Framework.SemanticKernel # AI/ML integration
├── module/ # Business modules (each follows 5-layer DDD pattern)
│ ├── ai-hub/ # AI services (chat, models, sessions, agents)
│ ├── rbac/ # Role-Based Access Control (core auth/authz)
│ ├── bbs/ # Forum/community
│ ├── chat-hub/ # Real-time messaging
│ ├── audit-logging/ # Audit trail tracking
│ ├── code-gen/ # Code generation
│ ├── tenant-management/ # Multi-tenancy support
│ ├── digital-collectibles/ # NFT/digital assets
│ └── ai-stock/ # AI-powered stock analysis
├── test/ # Unit tests (xUnit + NSubstitute + Shouldly)
├── client/ # HTTP API clients
└── tool/ # Development utilities
```
### Module Structure (DDD Layers)
Each module follows this pattern:
```
module/[feature]/
├── [Feature].Domain.Shared/ # Constants, enums, shared DTOs
├── [Feature].Domain/ # Entities, aggregates, domain services
├── [Feature].Application.Contracts/ # Service interfaces, DTOs
├── [Feature].Application/ # Application services (implementations)
└── [Feature].SqlSugarCore/ # Repository implementations, DbContext
```
**Dependency Flow:** Application → Domain + Application.Contracts → Domain.Shared → Framework
### Module Registration
All modules are registered in `src/Yi.Abp.Web/YiAbpWebModule.cs`. When adding a new module:
1. Add `DependsOn` attribute in `YiAbpWebModule`
2. Add conventional controller in `PreConfigureServices`:
```csharp
options.ConventionalControllers.Create(typeof(YiFramework[Feature]ApplicationModule).Assembly,
option => option.RemoteServiceName = "[service-name]");
```
### API Routing
All API routes use the unified prefix: `/api/app/{service-name}/{controller}/{action}`
Registered service names:
- `default` - Main application services
- `rbac` - Authentication, authorization, user/role management
- `ai-hub` - AI chat, models, sessions, agents
- `bbs` - Forum posts and comments
- `chat-hub` - Real-time messaging
- `tenant-management` - Multi-tenant configuration
- `code-gen` - Code generation utilities
- `digital-collectibles` - NFT/digital assets
- `ai-stock` - Stock analysis
## Database
**ORM:** SqlSugar (NOT Entity Framework Core)
**Configuration** (`appsettings.json`):
```json
"DbConnOptions": {
"Url": "DataSource=yi-abp-dev.db",
"DbType": "Sqlite", // Sqlite, Mysql, Sqlserver, Oracle, PostgreSQL
"EnabledCodeFirst": true, // Auto-create tables
"EnabledDbSeed": true, // Auto-seed data
"EnabledSaasMultiTenancy": true
}
```
**Multi-tenancy:** Tenant isolation via `HeaderTenantResolveContributor` (NOT cookie-based). Tenant is resolved from `__tenant` header.
## Key Technologies
| Component | Technology |
|-----------|-----------|
| Framework | ABP 8.3.4 |
| .NET Version | .NET 8.0 |
| ORM | SqlSugar 5.1.4.197-preview22 |
| Authentication | JWT Bearer + Refresh Tokens |
| OAuth | QQ, Gitee |
| Caching | FreeRedis (optional) |
| Background Jobs | Hangfire (in-memory or Redis) |
| Logging | Serilog (daily rolling files) |
| Testing | xUnit + NSubstitute + Shouldly |
| Container | Autofac |
## Important Notes
- **JSON Serialization:** Uses Microsoft's `System.Text.Json`, NOT Newtonsoft.Json. Date format handled via `DatetimeJsonConverter`.
- **Multi-tenancy:** Tenant resolved from `__tenant` header, NOT cookies.
- **Rate Limiting:** Disabled in development, enabled in production (1000 req/60s sliding window).
- **Swagger:** Available at `/swagger` in development.
- **Hangfire Dashboard:** Available at `/hangfire` (requires JWT authorization).
- **Background Workers:** Disabled in development (`AbpBackgroundWorkerOptions.IsEnabled = false`).
## Development Workflow
1. **Branch:** Main branch is `abp`, current development branch is `ai-hub`.
2. **Commit Convention:** Chinese descriptive messages with prefixes (`feat:`, `fix:`, `style:`).
3. **Testing:** Run `dotnet test` before committing.
4. **Building:** Use `dotnet build --no-restore` for faster builds after initial restore.

View File

@@ -261,13 +261,11 @@ public class OpenApiService : ApplicationService
/// 生成-Gemini (尊享服务专用) /// 生成-Gemini (尊享服务专用)
/// </summary> /// </summary>
/// <param name="input"></param> /// <param name="input"></param>
/// <param name="isAsync"></param>
/// <param name="modelId"></param> /// <param name="modelId"></param>
/// <param name="alt"></param> /// <param name="alt"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
[HttpPost("openApi/v1beta/models/{modelId}:{action:regex(^(generateContent|streamGenerateContent)$)}")] [HttpPost("openApi/v1beta/models/{modelId}:{action:regex(^(generateContent|streamGenerateContent)$)}")]
public async Task GenerateContentAsync([FromBody] JsonElement input, public async Task GenerateContentAsync([FromBody] JsonElement input,
[FromQuery] bool isAsync,
[FromRoute] string modelId, [FromRoute] string modelId,
[FromQuery] string? alt, CancellationToken cancellationToken) [FromQuery] string? alt, CancellationToken cancellationToken)
{ {
@@ -298,18 +296,7 @@ public class OpenApiService : ApplicationService
throw new UserFriendlyException("尊享token包用量不足请先购买尊享token包"); throw new UserFriendlyException("尊享token包用量不足请先购买尊享token包");
} }
//如果异步直接走job处理进行存储
if (isAsync)
{
var task = new ImageStoreTaskAggregateRoot();
await _imageStoreRepository.InsertAsync(task);
await _httpContextAccessor.HttpContext.Response.WriteAsJsonAsync(new
{
Id = task.Id
}, cancellationToken);
//todo 发送job,参数怎么办?需要先全存下来吗?全存下来,就要解析全部提示词 和 附件内容了
}
//ai网关代理httpcontext //ai网关代理httpcontext
if (alt == "sse") if (alt == "sse")
{ {

View File

@@ -7,6 +7,18 @@ namespace Yi.Framework.AiHub.Domain.Entities.Chat;
[SugarTable("Ai_ImageStoreTask")] [SugarTable("Ai_ImageStoreTask")]
public class ImageStoreTaskAggregateRoot : FullAuditedAggregateRoot<Guid> public class ImageStoreTaskAggregateRoot : FullAuditedAggregateRoot<Guid>
{ {
/// <summary>
/// 提示词
/// </summary>
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string Prompt { get; set; }
/// <summary>
/// 参考图Url
/// </summary>
[SugarColumn(IsJson = true)]
public List<string> ReferenceImageUrls { get; set; }
/// <summary> /// <summary>
/// 图片绝对路径 /// 图片绝对路径
/// </summary> /// </summary>