Ai Chat tenant bazlı çalıştıracağız

This commit is contained in:
Sedat ÖZTÜRK 2026-06-23 15:55:47 +03:00
parent 62118406c2
commit ab955483eb
10 changed files with 31 additions and 29 deletions

View file

@ -7,5 +7,6 @@ public class AiBotDto : FullAuditedEntityDto<Guid>
{ {
public string Name { get; set; } public string Name { get; set; }
public string ApiUrl { get; set; } public string ApiUrl { get; set; }
public string Description { get; set; }
} }

View file

@ -1239,14 +1239,14 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
InsertFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { InsertFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new() { FieldName = "Id", FieldDbType = DbType.Guid, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey } new() { FieldName = "Id", FieldDbType = DbType.Guid, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
}), }),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 450, true, true, true, true, false), EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 750, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{ {
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items = [ new() { Order=1, ColCount=2, ColSpan=1, ItemType="group", Items = [
new EditingFormItemDto { Order=1, DataField="Name", ColSpan=1, EditorType2=EditorTypes.dxTextBox }, new EditingFormItemDto { Order=1, DataField="Name", ColSpan=1, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=2, DataField="Description", ColSpan=1, EditorType2=EditorTypes.dxTextArea }, new EditingFormItemDto { Order=2, DataField="IsActive", ColSpan=1, EditorType2=EditorTypes.dxCheckBox },
new EditingFormItemDto { Order=3, DataField="ApiUrl", ColSpan=1, EditorType2=EditorTypes.dxTextBox }, new EditingFormItemDto { Order=3, DataField="ApiUrl", ColSpan=2, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=4, DataField="IsActive", ColSpan=1, EditorType2=EditorTypes.dxCheckBox } new EditingFormItemDto { Order=4, DataField="Description", ColSpan=2, EditorType2=EditorTypes.dxHtmlEditor, EditorOptions=EditorOptionValues.HtmlEditorOptions },
]} ]}
}), }),
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[]
@ -1293,15 +1293,14 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new() { new() {
ListFormCode = listForm.ListFormCode, ListFormCode = listForm.ListFormCode,
CultureName = LanguageCodes.En, CultureName = LanguageCodes.En,
SourceDbType = DbType.String, SourceDbType = DbType.Boolean,
FieldName = "Description", FieldName = "IsActive",
CaptionName = "App.Listform.ListformField.Description", CaptionName = "App.Listform.ListformField.IsActive",
Width = 0, Width = 0,
ListOrderNo = 3, ListOrderNo = 3,
Visible = true, Visible = true,
IsActive = true, IsActive = true,
AllowSearch = true, AllowSearch = true,
ValidationRuleJson = DefaultValidationRuleRequiredJson,
ColumnCustomizationJson = DefaultColumnCustomizationJson, ColumnCustomizationJson = DefaultColumnCustomizationJson,
PermissionJson = DefaultFieldPermissionJson(listForm.Name), PermissionJson = DefaultFieldPermissionJson(listForm.Name),
PivotSettingsJson = DefaultPivotSettingsJson PivotSettingsJson = DefaultPivotSettingsJson
@ -1325,14 +1324,15 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new() { new() {
ListFormCode = listForm.ListFormCode, ListFormCode = listForm.ListFormCode,
CultureName = LanguageCodes.En, CultureName = LanguageCodes.En,
SourceDbType = DbType.Boolean, SourceDbType = DbType.String,
FieldName = "IsActive", FieldName = "Description",
CaptionName = "App.Listform.ListformField.IsActive", CaptionName = "App.Listform.ListformField.Description",
Width = 0, Width = 0,
ListOrderNo = 5, ListOrderNo = 5,
Visible = true, Visible = false,
IsActive = true, IsActive = true,
AllowSearch = true, AllowSearch = true,
ValidationRuleJson = DefaultValidationRuleRequiredJson,
ColumnCustomizationJson = DefaultColumnCustomizationJson, ColumnCustomizationJson = DefaultColumnCustomizationJson,
PermissionJson = DefaultFieldPermissionJson(listForm.Name), PermissionJson = DefaultFieldPermissionJson(listForm.Name),
PivotSettingsJson = DefaultPivotSettingsJson PivotSettingsJson = DefaultPivotSettingsJson

View file

@ -192,8 +192,8 @@ public class PlatformDbContext :
b.ConfigureByConvention(); b.ConfigureByConvention();
b.Property(a => a.Name).IsRequired().HasMaxLength(128); b.Property(a => a.Name).IsRequired().HasMaxLength(128);
b.Property(a => a.Description).HasMaxLength(256);
b.Property(a => a.ApiUrl).HasMaxLength(256); b.Property(a => a.ApiUrl).HasMaxLength(256);
b.Property(a => a.Description).HasColumnType("text");
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter(null); b.HasIndex(x => new { x.Name }).IsUnique().HasFilter(null);
}); });

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Sozsoft.Platform.Migrations namespace Sozsoft.Platform.Migrations
{ {
[DbContext(typeof(PlatformDbContext))] [DbContext(typeof(PlatformDbContext))]
[Migration("20260622213308_Initial")] [Migration("20260623105928_Initial")]
partial class Initial partial class Initial
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -689,8 +689,7 @@ namespace Sozsoft.Platform.Migrations
.HasColumnType("nvarchar(256)"); .HasColumnType("nvarchar(256)");
b.Property<string>("Description") b.Property<string>("Description")
.HasMaxLength(256) .HasColumnType("text");
.HasColumnType("nvarchar(256)");
b.Property<bool>("IsActive") b.Property<bool>("IsActive")
.HasColumnType("bit"); .HasColumnType("bit");

View file

@ -921,7 +921,7 @@ namespace Sozsoft.Platform.Migrations
{ {
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false), Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Description = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), Description = table.Column<string>(type: "text", nullable: true),
ApiUrl = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true), ApiUrl = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
IsActive = table.Column<bool>(type: "bit", nullable: false) IsActive = table.Column<bool>(type: "bit", nullable: false)
}, },

View file

@ -686,8 +686,7 @@ namespace Sozsoft.Platform.Migrations
.HasColumnType("nvarchar(256)"); .HasColumnType("nvarchar(256)");
b.Property<string>("Description") b.Property<string>("Description")
.HasMaxLength(256) .HasColumnType("text");
.HasColumnType("nvarchar(256)");
b.Property<bool>("IsActive") b.Property<bool>("IsActive")
.HasColumnType("bit"); .HasColumnType("bit");

View file

@ -30,7 +30,7 @@
"promptType": "define", "promptType": "define",
"text": "={{ $('Webhook').item.json.body.question }}", "text": "={{ $('Webhook').item.json.body.question }}",
"options": { "options": {
"systemMessage": "Kullanıcı: {{ $json.body.question }}\n\nDoğrudan yanıt ver. Açıklayıcı, öğretici ve samimi ol." "systemMessage": "{{ $json.body.description }}"
} }
}, },
"type": "@n8n/n8n-nodes-langchain.agent", "type": "@n8n/n8n-nodes-langchain.agent",
@ -184,7 +184,7 @@
"executionOrder": "v1", "executionOrder": "v1",
"availableInMCP": false "availableInMCP": false
}, },
"versionId": "84010ee3-81a9-48c8-9b48-a0661355d85c", "versionId": "d9036bcb-7257-49a0-b848-ff451bce5bb8",
"meta": { "meta": {
"templateCredsSetupCompleted": true, "templateCredsSetupCompleted": true,
"instanceId": "1d288821beaaeeada5e8dce6f282c802098a0c83ef6ddb35a174b09a9d43850e" "instanceId": "1d288821beaaeeada5e8dce6f282c802098a0c83ef6ddb35a174b09a9d43850e"

View file

@ -1,8 +1,9 @@
import { FullAuditedEntityDto } from '../abp' import { FullAuditedEntityDto } from '../abp'
export interface AiDto extends FullAuditedEntityDto<string> { export interface AiBotDto extends FullAuditedEntityDto<string> {
name: string name: string
apiUrl?: string apiUrl?: string
description?: string
} }
export type ChatType = 'chat' | 'query' | 'analyze' export type ChatType = 'chat' | 'query' | 'analyze'

View file

@ -1,4 +1,4 @@
import { AiDto } from '@/proxy/ai/models' import { AiBotDto } from '@/proxy/ai/models'
import { PagedAndSortedResultRequestDto, PagedResultDto } from '../proxy' import { PagedAndSortedResultRequestDto, PagedResultDto } from '../proxy'
import apiService, { Config } from './api.service' import apiService, { Config } from './api.service'
@ -6,7 +6,7 @@ export class AiService {
apiName = 'Default' apiName = 'Default'
getList = (input: PagedAndSortedResultRequestDto, config?: Partial<Config>) => getList = (input: PagedAndSortedResultRequestDto, config?: Partial<Config>) =>
apiService.fetchData<PagedResultDto<AiDto>, PagedAndSortedResultRequestDto>( apiService.fetchData<PagedResultDto<AiBotDto>, PagedAndSortedResultRequestDto>(
{ {
method: 'GET', method: 'GET',
url: '/api/app/ai-bot', url: '/api/app/ai-bot',

View file

@ -4,7 +4,7 @@ import { useStoreState } from '@/store'
import { Avatar, Button, Drawer, Dropdown, ScrollBar } from '@/components/ui' import { Avatar, Button, Drawer, Dropdown, ScrollBar } from '@/components/ui'
import { useLocalization } from '@/utils/hooks/useLocalization' import { useLocalization } from '@/utils/hooks/useLocalization'
import { aiService } from '@/services/ai.service' import { aiService } from '@/services/ai.service'
import { AiDto } from '@/proxy/ai/models' import { AiBotDto } from '@/proxy/ai/models'
import { Container } from '@/components/shared' import { Container } from '@/components/shared'
import { Helmet } from 'react-helmet' import { Helmet } from 'react-helmet'
import { APP_NAME } from '@/constants/app.constant' import { APP_NAME } from '@/constants/app.constant'
@ -104,10 +104,10 @@ const Assistant = () => {
const aiPosts: Message[] = [] const aiPosts: Message[] = []
const [input, setInput] = useState('') const [input, setInput] = useState('')
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [bot, setBot] = useState<AiDto[]>([]) const [bot, setBot] = useState<AiBotDto[]>([])
const [selectedBot, setSelectedBot] = useState<string | null>(null) const [selectedBot, setSelectedBot] = useState<string | null>(null)
const { avatar } = useStoreState((state) => state.auth.user) const { user, tenant } = useStoreState((state) => state.auth)
const inputRef = useRef<HTMLTextAreaElement | null>(null) const inputRef = useRef<HTMLTextAreaElement | null>(null)
const bottomRef = useRef<HTMLDivElement | null>(null) const bottomRef = useRef<HTMLDivElement | null>(null)
@ -329,6 +329,8 @@ const Assistant = () => {
biletId: conversationId, biletId: conversationId,
question: userMessage, question: userMessage,
sessionId: conversationId, sessionId: conversationId,
tenantName: tenant.tenantName ?? null,
// description: selectedBotItem?.description?.replace(/\r?\n/g, '\\n'),
}), }),
}) })
@ -643,7 +645,7 @@ const Assistant = () => {
className={`w-8 h-8 rounded-full flex items-center justify-center ${msg.role === 'user' ? 'bg-blue-500' : 'bg-gray-600'}`} className={`w-8 h-8 rounded-full flex items-center justify-center ${msg.role === 'user' ? 'bg-blue-500' : 'bg-gray-600'}`}
> >
{msg.role === 'user' ? ( {msg.role === 'user' ? (
<Avatar size={32} shape="circle" src={avatar} alt="avatar" /> <Avatar size={32} shape="circle" src={user.avatar} alt="avatar" />
) : ( ) : (
<FaRobot className="w-5 h-5 text-white" /> <FaRobot className="w-5 h-5 text-white" />
)} )}