Skip to content

Commit 1500ee5

Browse files
pythonHuangclaude
andcommitted
feat: 大模型供应商管理+模型助手-系统设置增加大模型设置页(供应商CRUD/可用模型/启用禁用),菜单增加模型助手(流程智能编排助手:对话生成流程预览确认入库;接口智能接入助手:对话生成套件接口预览确认接入),对话支持切换供应商与模型
Co-Authored-By: Claude Code <noreply@anthropic.com>
1 parent 9c23dbb commit 1500ee5

11 files changed

Lines changed: 891 additions & 43 deletions

File tree

‎Juggle.Api/Controllers/Api/AiController.cs‎

Lines changed: 153 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
using Juggle.Application.Models.Response;
2+
using Juggle.Application.Services;
23
using Juggle.Application.Services.Impl;
4+
using Juggle.Domain.Entities;
5+
using Juggle.Infrastructure.Persistence;
36
using Microsoft.AspNetCore.Authorization;
47
using Microsoft.AspNetCore.Mvc;
8+
using Microsoft.EntityFrameworkCore;
59

610
namespace Juggle.Api.Controllers.Api;
711

812
/// <summary>
9-
/// AI 大模型控制器:模型配置 + 需求对话生成接口流程编排。
13+
/// AI 大模型控制器:供应商管理 + 需求对话生成接口流程编排 + 接口智能接入。
1014
/// 支持任意 OpenAI 兼容接口(DeepSeek / 通义千问 / Kimi / OpenAI 等)。
1115
/// </summary>
1216
[ApiController]
@@ -15,8 +19,76 @@ namespace Juggle.Api.Controllers.Api;
1519
public class AiController : ControllerBase
1620
{
1721
private readonly AiService _aiService;
22+
private readonly JuggleDbContext _db;
23+
private readonly ITenantAccessor _tenant;
1824

19-
public AiController(AiService aiService) => _aiService = aiService;
25+
public AiController(AiService aiService, JuggleDbContext db, ITenantAccessor tenant)
26+
{
27+
_aiService = aiService;
28+
_db = db;
29+
_tenant = tenant;
30+
}
31+
32+
// ==================== 供应商管理 ====================
33+
34+
/// <summary>供应商列表(含启停状态)</summary>
35+
[HttpGet("providers")]
36+
public async Task<ApiResult> Providers()
37+
=> ApiResult.Success(await _aiService.GetProvidersAsync());
38+
39+
/// <summary>启用的供应商(下拉选择用)</summary>
40+
[HttpGet("providers/enabled")]
41+
public async Task<ApiResult> EnabledProviders()
42+
=> ApiResult.Success(await _aiService.GetEnabledProvidersAsync());
43+
44+
/// <summary>新增/更新供应商</summary>
45+
[HttpPost("provider/save")]
46+
public async Task<ApiResult> SaveProvider([FromBody] AiProviderSaveRequest req)
47+
{
48+
AiProviderEntity entity;
49+
if (req.Id > 0)
50+
{
51+
entity = await _db.AiProviders.FindAsync(req.Id) ?? throw new Exception("供应商不存在");
52+
}
53+
else
54+
{
55+
entity = new AiProviderEntity { CreatedAt = DateTime.Now.ToString("o"), TenantId = _tenant.TenantId };
56+
_db.AiProviders.Add(entity);
57+
}
58+
entity.ProviderName = req.ProviderName;
59+
entity.BaseUrl = req.BaseUrl;
60+
entity.ApiKey = req.ApiKey;
61+
entity.Model = req.Model;
62+
entity.Models = req.Models;
63+
entity.Enabled = req.Enabled ? 1 : 0;
64+
entity.Remark = req.Remark;
65+
entity.UpdatedAt = DateTime.Now.ToString("o");
66+
await _db.SaveChangesAsync();
67+
return ApiResult.Success(entity.Id);
68+
}
69+
70+
/// <summary>删除供应商</summary>
71+
[HttpDelete("provider/{id}")]
72+
public async Task<ApiResult> DeleteProvider(long id)
73+
{
74+
var entity = await _db.AiProviders.FindAsync(id);
75+
if (entity == null) return ApiResult.Fail("供应商不存在");
76+
entity.Deleted = 1;
77+
await _db.SaveChangesAsync();
78+
return ApiResult.Success();
79+
}
80+
81+
/// <summary>启用/禁用供应商</summary>
82+
[HttpPost("provider/toggle")]
83+
public async Task<ApiResult> ToggleProvider([FromBody] AiProviderToggleRequest req)
84+
{
85+
var entity = await _db.AiProviders.FindAsync(req.Id);
86+
if (entity == null) return ApiResult.Fail("供应商不存在");
87+
entity.Enabled = req.Enabled ? 1 : 0;
88+
entity.UpdatedAt = DateTime.Now.ToString("o");
89+
await _db.SaveChangesAsync();
90+
return ApiResult.Success();
91+
}
2092

2193
/// <summary>读取 AI 模型配置</summary>
2294
[HttpGet("config")]
@@ -47,11 +119,47 @@ public async Task<ApiResult> GenerateFlow([FromBody] AiGenerateFlowRequest req)
47119
{
48120
try
49121
{
50-
var flow = await _aiService.GenerateFlowAsync(req.Requirement, req.Apis, req.InputParams, req.OutputParams);
122+
var flow = await _aiService.GenerateFlowAsync(req.Requirement, req.Apis, req.InputParams, req.OutputParams, req.ProviderId, req.Model);
51123
return ApiResult.Success(flow);
52124
}
53125
catch (Exception ex) { return ApiResult.Fail(ex.Message); }
54126
}
127+
128+
/// <summary>确认生成流程:创建流程定义并写入编排内容</summary>
129+
[HttpPost("apply-flow")]
130+
public async Task<ApiResult> ApplyFlow([FromBody] AiApplyFlowRequest req)
131+
{
132+
try
133+
{
134+
var result = await _aiService.ApplyFlowAsync(req.FlowName, req.FlowDesc, req.GroupName, req.Nodes);
135+
return ApiResult.Success(result);
136+
}
137+
catch (Exception ex) { return ApiResult.Fail(ex.Message); }
138+
}
139+
140+
/// <summary>根据需求对话生成套件与接口(预览)</summary>
141+
[HttpPost("generate-apis")]
142+
public async Task<ApiResult> GenerateApis([FromBody] AiGenerateApisRequest req)
143+
{
144+
try
145+
{
146+
var result = await _aiService.GenerateApisAsync(req.Requirement, req.ExistingSuites, req.ProviderId, req.Model);
147+
return ApiResult.Success(result);
148+
}
149+
catch (Exception ex) { return ApiResult.Fail(ex.Message); }
150+
}
151+
152+
/// <summary>确认接入:套件与接口写入数据库</summary>
153+
[HttpPost("apply-apis")]
154+
public async Task<ApiResult> ApplyApis([FromBody] AiApplyApisRequest req)
155+
{
156+
try
157+
{
158+
var result = await _aiService.ApplyApisAsync(req.Suites, req.Apis);
159+
return ApiResult.Success(result);
160+
}
161+
catch (Exception ex) { return ApiResult.Fail(ex.Message); }
162+
}
55163
}
56164

57165
public class AiConfigRequest
@@ -64,7 +172,49 @@ public class AiConfigRequest
64172
public class AiGenerateFlowRequest
65173
{
66174
public string Requirement { get; set; } = "";
175+
public long ProviderId { get; set; }
176+
public string? Model { get; set; }
67177
public List<Dictionary<string, object?>>? Apis { get; set; }
68178
public List<Dictionary<string, object?>>? InputParams { get; set; }
69179
public List<Dictionary<string, object?>>? OutputParams { get; set; }
70180
}
181+
182+
public class AiApplyFlowRequest
183+
{
184+
public string FlowName { get; set; } = "";
185+
public string? FlowDesc { get; set; }
186+
public string? GroupName { get; set; }
187+
public List<Dictionary<string, object?>>? Nodes { get; set; }
188+
}
189+
190+
public class AiGenerateApisRequest
191+
{
192+
public string Requirement { get; set; } = "";
193+
public long ProviderId { get; set; }
194+
public string? Model { get; set; }
195+
public List<Dictionary<string, object?>>? ExistingSuites { get; set; }
196+
}
197+
198+
public class AiApplyApisRequest
199+
{
200+
public List<Dictionary<string, object?>>? Suites { get; set; }
201+
public List<Dictionary<string, object?>>? Apis { get; set; }
202+
}
203+
204+
public class AiProviderSaveRequest
205+
{
206+
public long Id { get; set; }
207+
public string ProviderName { get; set; } = "";
208+
public string BaseUrl { get; set; } = "";
209+
public string ApiKey { get; set; } = "";
210+
public string Model { get; set; } = "";
211+
public string Models { get; set; } = "";
212+
public bool Enabled { get; set; } = true;
213+
public string? Remark { get; set; }
214+
}
215+
216+
public class AiProviderToggleRequest
217+
{
218+
public long Id { get; set; }
219+
public bool Enabled { get; set; }
220+
}

‎Juggle.Api/Program.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ await ctx.Response.WriteAsync(
246246
try { db.Database.ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS t_report(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, group_name TEXT, source_type TEXT, source_ref TEXT, custom_sql TEXT, params_config TEXT, layout_json TEXT, status INTEGER DEFAULT 1, created_at TEXT, created_by INTEGER, updated_at TEXT, updated_by INTEGER, tenant_id INTEGER, deleted INTEGER DEFAULT 0);"); } catch { }
247247
// 数据视图字段中文对照
248248
try { db.Database.ExecuteSqlRaw("ALTER TABLE t_data_view ADD COLUMN column_mapping TEXT DEFAULT NULL;"); } catch { }
249+
// AI 大模型供应商表
250+
try { db.Database.ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS t_ai_provider(id INTEGER PRIMARY KEY AUTOINCREMENT, provider_name TEXT, base_url TEXT, api_key TEXT, model TEXT, models TEXT, enabled INTEGER DEFAULT 1, remark TEXT, created_at TEXT, created_by INTEGER, updated_at TEXT, updated_by INTEGER, tenant_id INTEGER, deleted INTEGER DEFAULT 0);"); } catch { }
249251
// 补建参数位置字段
250252
try { db.Database.ExecuteSqlRaw("ALTER TABLE t_parameter ADD COLUMN param_position TEXT DEFAULT NULL;"); } catch { }
251253
}

0 commit comments

Comments
 (0)