-suscess chat ai system
All checks were successful
Build Docker Image / Build Docker Image (push) Successful in 6m31s
Build Docker Image / Restart Docker Compose (push) Successful in 1s

This commit is contained in:
2025-12-01 16:08:27 +07:00
parent 9a5c174fc5
commit d6b171a0a7

View File

@@ -1,7 +1,8 @@
import { GeneralService } from './../../services/generalservice'; import { GeneralService } from './../../services/generalservice';
import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms'; import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
import { IChat } from '../../interfaces/main.interface' import { IChat } from '../../interfaces/main.interface';
import { Component, HostListener } from '@angular/core'; import { Component, HostListener, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
@Component({ @Component({
selector: 'app-chat-widget-component', selector: 'app-chat-widget-component',
@@ -9,76 +10,62 @@ import { Component, HostListener } from '@angular/core';
templateUrl: './chat-widget-component.html', templateUrl: './chat-widget-component.html',
styleUrl: './chat-widget-component.css', styleUrl: './chat-widget-component.css',
}) })
export class ChatWidgetComponent { export class ChatWidgetComponent implements OnDestroy {
// --- State ---
isOpen = false; isOpen = false;
// newMessage = '';
chatForm!: FormGroup;
messages:IChat[]=[];
// State สำหรับจัดการขนาด
isMaximized = false; isMaximized = false;
isResizing = false; isLoading = false; // Added to track API state
first = true;
// ขนาดเริ่มต้น (px) // --- Form & Data ---
chatForm!: FormGroup;
messages: IChat[] = [];
private subscriptions: Subscription = new Subscription();
// --- Resize State ---
chatWidth = 320; chatWidth = 320;
chatHeight = 384; chatHeight = 384;
isResizing = false;
// ตัวแปรสำหรับคำนวณการลาก
private startX = 0; private startX = 0;
private startY = 0; private startY = 0;
private startWidth = 0; private startWidth = 0;
private startHeight = 0; private startHeight = 0;
constructor(private generalService: GeneralService) {
this.setupFormControl();
}
constructor( ngOnDestroy(): void {
private generalService: GeneralService // Best Practice: Unsubscribe to prevent memory leaks
) { this.subscriptions.unsubscribe();
this.setupFormControl(); // เรียกใช้ตอนเริ่ม Component
} }
setupFormControl() { setupFormControl() {
this.chatForm = new FormGroup({ this.chatForm = new FormGroup({
message: new FormControl('', [Validators.required]) message: new FormControl('', [Validators.required]),
}); });
} }
toggleChat() { toggleChat() {
this.isOpen = !this.isOpen; this.isOpen = !this.isOpen;
let body = {methods: 'ind'}
this.OnAiChat(body);
const isAlreadyHave = this.messages.some(sub => sub.text == 'รอAi ประมวณผลสักครู่');
if(isAlreadyHave === false){
this.messages.push({
text: 'รอAi ประมวณผลสักครู่',
isUser: false
})
}
this.isMaximized = false; this.isMaximized = false;
}
OnAiChat(value: any){ // Only trigger welcome message logic if opening
let url = 'https://n8n.nuttakit.work/webhook/Ai' if (this.isOpen) {
let request = { if (this.first) {
methods: value.methods || 'cht', // Initial handshake with AI
message: value.message ?? '' this.OnAiChat({ methods: 'ind' });
}
this.generalService.postUrl(url, request).subscribe({ // Add "Waiting" message only if it doesn't exist
next: (result: any) => { const isAlreadyHave = this.messages.some((sub) => sub.text === 'รอAi ประมวณผลสักครู่');
if (result.code === 200) { if (!isAlreadyHave) {
this.messages.push(result.data) this.messages.push({
}else{ text: 'รอAi ประมวณผลสักครู่',
this.generalService.trowApi(result); isUser: false,
});
} }
},
error: (error: any) => {
},
complete: () => {
} }
}) }
} }
toggleMaximize() { toggleMaximize() {
@@ -86,44 +73,79 @@ export class ChatWidgetComponent {
} }
sendMessage() { sendMessage() {
let newMessage = this.chatForm.get('message')?.value; if (this.chatForm.invalid) return;
if (newMessage.trim()) {
this.messages.push({ text: newMessage, isUser: true }); const messageText = this.chatForm.get('message')?.value;
newMessage = '';
// setTimeout(() => { if (messageText && messageText.trim()) {
// this.messages.push({ // 1. Add User Message to UI
// text: 'รับทราบครับ ระบบกำลังประมวลผล...', this.messages.push({ text: messageText, isUser: true });
// isUser: false
// }); // 2. Clear the form input
// }, 1000); this.chatForm.reset();
// 3. Set loading state
this.isLoading = true;
// 4. Send to API
this.OnAiChat({ methods: 'cht', message: messageText });
} }
} }
// --- Logic สำหรับการ Resize (ลากขยาย) --- OnAiChat(value: { methods: string; message?: string }) {
// Best Practice: Move URL to environment.ts in the future
const url = 'https://n8n.nuttakit.work/webhook/Ai';
const request = {
methods: value.methods || 'cht',
message: value.message ?? '',
};
const sub = this.generalService.postUrl(url, request).subscribe({
next: (result: any) => {
if (result.code === 200) {
// Push AI response
this.messages.push(result.data);
this.first = false;
} else {
// Handle API logic errors
// specific check for the method if it exists
if(this.generalService['trowApi']) {
this.generalService.trowApi(result);
}
}
},
error: (error: any) => {
console.error('Chat Error:', error);
this.messages.push({ text: 'ขออภัย เกิดข้อผิดพลาดในการเชื่อมต่อ', isUser: false });
},
complete: () => {
this.isLoading = false;
},
});
this.subscriptions.add(sub);
}
// --- Resize Logic (Preserved) ---
startResizing(event: MouseEvent) { startResizing(event: MouseEvent) {
event.preventDefault(); // ป้องกันการเลือก Text event.preventDefault();
this.isResizing = true; this.isResizing = true;
// บันทึกตำแหน่งเมาส์และขนาดปัจจุบัน
this.startX = event.clientX; this.startX = event.clientX;
this.startY = event.clientY; this.startY = event.clientY;
this.startWidth = this.chatWidth; this.startWidth = this.chatWidth;
this.startHeight = this.chatHeight; this.startHeight = this.chatHeight;
} }
// ใช้ @HostListener เพื่อดักจับ MouseMove ทั่วทั้ง Window
@HostListener('window:mousemove', ['$event']) @HostListener('window:mousemove', ['$event'])
onMouseMove(event: MouseEvent) { onMouseMove(event: MouseEvent) {
if (!this.isResizing) return; if (!this.isResizing) return;
// คำนวณความต่าง (Delta) // Logic assumes resizing from Top-Left corner (expanding Up and Left)
// หมายเหตุ: ลากไปทางซ้าย (ค่า X น้อยลง) ต้องทำให้กว้างขึ้น -> ใช้ startX - clientX
// ลากไปข้างบน (ค่า Y น้อยลง) ต้องทำให้สูงขึ้น -> ใช้ startY - clientY
const deltaX = this.startX - event.clientX; const deltaX = this.startX - event.clientX;
const deltaY = this.startY - event.clientY; const deltaY = this.startY - event.clientY;
// กำหนดขนาดใหม่ (จำกัดขนาดต่ำสุดไม่ให้เล็กเกินไป)
this.chatWidth = Math.max(300, this.startWidth + deltaX); this.chatWidth = Math.max(300, this.startWidth + deltaX);
this.chatHeight = Math.max(350, this.startHeight + deltaY); this.chatHeight = Math.max(350, this.startHeight + deltaY);
} }