From ab36ee35b45fd87f2c7f1ba81c5b016309c22a38 Mon Sep 17 00:00:00 2001 From: liosha84 <138026690+liosha84@users.noreply.github.com> Date: Thu, 19 Jun 2025 18:36:09 +0300 Subject: [PATCH 1/2] Add System component with table display for custom and all beans --- HELP.md | 2 + application.yml | 12 ++ build.gradle | 17 ++ jambotron-ui/src/app/app-routing.module.ts | 7 +- jambotron-ui/src/app/app.component.html | 58 +------ .../system.component/system.component.html | 110 +++++++++++++ .../system.component/system.component.scss | 113 +++++++++++++ .../system.component/system.component.spec.ts | 23 +++ .../system.component/system.component.ts | 148 ++++++++++++++++++ .../column-resize.directive.spec.ts | 8 + .../app/directives/column-resize.directive.ts | 114 ++++++++++++++ jambotron-ui/src/app/models/Bean.ts | 7 + .../src/app/services/system.service.spec.ts | 16 ++ .../src/app/services/system.service.ts | 22 +++ .../jambotron/JambotronApplication.java | 13 ++ .../ZhiPuAi/ZhiPuAiImageService.java | 44 ++++++ .../controllers/SystemController.java | 55 +++++++ .../controllers/ZhiPuAiController.java | 15 ++ .../jambotronGroup/jambotron/model/Bean.java | 86 ++++++++++ .../jambotron/security/WebSecurityConfig.java | 11 +- .../jambotron/system/SystemService.java | 12 ++ .../jambotron/system/SystemServiceImpl.java | 55 +++++++ .../utils/EntityLoggingConsumer.java | 22 +++ src/main/resources/application.properties | 6 +- 24 files changed, 919 insertions(+), 57 deletions(-) create mode 100644 application.yml create mode 100644 jambotron-ui/src/app/components/system.component/system.component.html create mode 100644 jambotron-ui/src/app/components/system.component/system.component.scss create mode 100644 jambotron-ui/src/app/components/system.component/system.component.spec.ts create mode 100644 jambotron-ui/src/app/components/system.component/system.component.ts create mode 100644 jambotron-ui/src/app/directives/column-resize.directive.spec.ts create mode 100644 jambotron-ui/src/app/directives/column-resize.directive.ts create mode 100644 jambotron-ui/src/app/models/Bean.ts create mode 100644 jambotron-ui/src/app/services/system.service.spec.ts create mode 100644 jambotron-ui/src/app/services/system.service.ts create mode 100644 src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ZhiPuAiImageService.java create mode 100644 src/main/java/com/jambotronGroup/jambotron/controllers/SystemController.java create mode 100644 src/main/java/com/jambotronGroup/jambotron/controllers/ZhiPuAiController.java create mode 100644 src/main/java/com/jambotronGroup/jambotron/model/Bean.java create mode 100644 src/main/java/com/jambotronGroup/jambotron/system/SystemService.java create mode 100644 src/main/java/com/jambotronGroup/jambotron/system/SystemServiceImpl.java create mode 100644 src/main/java/com/jambotronGroup/jambotron/utils/EntityLoggingConsumer.java diff --git a/HELP.md b/HELP.md index 7f9f0f5..75481ee 100644 --- a/HELP.md +++ b/HELP.md @@ -106,6 +106,8 @@ To run the application in Docker, follow these steps: ```bash docker-compose -f src/Docker/docker-compose.yml up -d ``` +- For connection from pgadmin use +hostename: **host.docker.internal** ### Reference Documentation For further reference, please consider the following sections: diff --git a/application.yml b/application.yml new file mode 100644 index 0000000..733c6a1 --- /dev/null +++ b/application.yml @@ -0,0 +1,12 @@ +logging: + level: + root: INFO + com.jambotronGroup.jambotron: DEBUG + org.springframework: WARN + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss} %-5level - %msg%n" + file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" + file: + name: logs/application.log + max-size: 10MB + max-history: 30 diff --git a/build.gradle b/build.gradle index f0dff52..0be94ee 100644 --- a/build.gradle +++ b/build.gradle @@ -35,8 +35,25 @@ dependencies { implementation 'org.flywaydb:flyway-core' implementation("org.flywaydb:flyway-database-postgresql:10.4.1") + //implementation 'org.springframework.ai:spring-ai-starter-model-zhipuai' + //implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter' + //implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT") + // Replace the following with the starter dependencies of specific modules you wish to use + //implementation 'org.springframework.ai:spring-ai-zhipuai' + //implementation 'org.springframework.boot:spring-boot-starter-webflux' + //implementation("org.springframework.ai:spring-ai-spring-boot-autoconfigure:1.0.0-M6") + // https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-retry + //implementation("org.springframework.ai:spring-ai-retry:1.0.0") + //implementation group: 'org.springframework.ai', name: 'spring-ai-spring-boot-autoconfigure', version: '1.0.0-M6' } +apply plugin: 'io.spring.dependency-management' + dependencyManagement { + imports { + mavenBom ("org.springframework.ai:spring-ai-retry:1.0.0") + } + } + // copyResouces( type:Copy //tasks copyResouces( type:Copy){ diff --git a/jambotron-ui/src/app/app-routing.module.ts b/jambotron-ui/src/app/app-routing.module.ts index 42b4761..1d741dc 100644 --- a/jambotron-ui/src/app/app-routing.module.ts +++ b/jambotron-ui/src/app/app-routing.module.ts @@ -10,6 +10,8 @@ import { ProfileComponent } from './components/profile/profile.component'; import { RegisterComponent } from './components/register/register.component'; import { LoginComponent } from './components/login/login.component'; import { HomeComponent } from './components/home/home.component'; +import {SystemComponent} from './components/system.component/system.component'; + const routes: Routes = [ { path: 'home', component: HomeComponent }, @@ -22,11 +24,12 @@ const routes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'tutorials', component: TutorialsListComponent }, { path: 'tutorials/:id', component: TutorialDetailsComponent }, - { path: 'add', component: AddTutorialComponent } + { path: 'add', component: AddTutorialComponent }, + { path: 'system', component: SystemComponent} ]; @NgModule({ imports: [RouterModule.forRoot(routes, {useHash: true})], exports: [RouterModule] }) -export class AppRoutingModule { } \ No newline at end of file +export class AppRoutingModule { } diff --git a/jambotron-ui/src/app/app.component.html b/jambotron-ui/src/app/app.component.html index 0564b57..85204c4 100644 --- a/jambotron-ui/src/app/app.component.html +++ b/jambotron-ui/src/app/app.component.html @@ -1,52 +1,3 @@ -
- - -
- -
- } + @if (showAdminBoard) { + + } +
+ diff --git a/jambotron-ui/src/app/components/system.component/system.component.html b/jambotron-ui/src/app/components/system.component/system.component.html new file mode 100644 index 0000000..e42981e --- /dev/null +++ b/jambotron-ui/src/app/components/system.component/system.component.html @@ -0,0 +1,110 @@ + + + + System + + + + + + Content 1 + + @for (column of displayedColumns; track column) { + + + + + } + + + + + + + + + + + + + + +
{{column}}{{element[column]}}  + + +
+
+ + + Name: {{element.name}} + Type: {{element.type}} + +
+
+
+ +
+ + Content 2 + + @for (column of displayedColumns; track column) { + + + + + } + + + + + + + + + + + + + + +
{{column}}{{element[column]}}  + + +
+
+ + + Name: {{element.name}} + Type: {{element.type}} + +
+
+
+
+
+
+
diff --git a/jambotron-ui/src/app/components/system.component/system.component.scss b/jambotron-ui/src/app/components/system.component/system.component.scss new file mode 100644 index 0000000..b4c141e --- /dev/null +++ b/jambotron-ui/src/app/components/system.component/system.component.scss @@ -0,0 +1,113 @@ +mat-card{ + margin: 20px; + background-color: rgba(240, 248, 255, 0.7); + backdrop-filter: blur(8px); +} + +mat-card-title{ + color: cyan; +} + +mat-card-subtitle{ + color: #009dff; +} + +mat-tab{ + color:black; +} + + +table { + width: 100%; + margin-top: 20px; + color:lightgrey; +} + + +mat-list{ + //background-color: #1389d3; + color:black; + width: 100%; +} + +mat-list-item{ + margin: 10px 10px 10px 10px; + background-color: #447694; + + color: #009dff; +} + +tr.example-detail-row { + height: 0; + background: #fffdfd; +} + +tr.example-element-row { + cursor: pointer; + color: #1389d3; + background: #fffdfd; +} + +tr.example-element-row:not(.example-expanded-row):hover { + background: whitesmoke; +} + +tr.example-element-row:not(.example-expanded-row):active { + background: #efefef; +} + +.example-element-row td { + border-bottom-width: 0; +} + +.example-element-detail-wrapper { + overflow: hidden; + display: grid; + grid-template-rows: 0fr; + grid-template-columns: 100%; + transition: grid-template-rows 225ms cubic-bezier(0.4, 0, 0.2, 1); +} + +.example-element-detail-wrapper-expanded { + grid-template-rows: 1fr; + +} + +.example-element-detail { + display: flex; + min-height: 0; +} + +.example-element-diagram { + min-width: 80px; + border: 2px solid black; + padding: 8px; + font-weight: lighter; + margin: 8px 0; + height: 104px; +} + +.example-element-symbol { + font-weight: bold; + font-size: 40px; + line-height: normal; +} + +.example-element-description { + padding: 16px; +} + +.example-element-description-attribution { + opacity: 0.5; +} + +.example-toggle-button { + transition: transform 225ms cubic-bezier(0.4, 0, 0.2, 1); +} + +.example-toggle-button-expanded { + transform: rotate(180deg); +} + + + diff --git a/jambotron-ui/src/app/components/system.component/system.component.spec.ts b/jambotron-ui/src/app/components/system.component/system.component.spec.ts new file mode 100644 index 0000000..bae84c7 --- /dev/null +++ b/jambotron-ui/src/app/components/system.component/system.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SystemComponent } from './system.component'; + +describe('SystemComponent', () => { + let component: SystemComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [SystemComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(SystemComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/components/system.component/system.component.ts b/jambotron-ui/src/app/components/system.component/system.component.ts new file mode 100644 index 0000000..f5f4699 --- /dev/null +++ b/jambotron-ui/src/app/components/system.component/system.component.ts @@ -0,0 +1,148 @@ +import { Component } from '@angular/core'; +import {Bean} from '../../models/Bean'; +import {SystemService} from '../../services/system.service'; +import { + MatCard, + MatCardContent, + MatCardHeader, + MatCardSubtitle, + MatCardTitle, + MatCardTitleGroup +} from '@angular/material/card'; +import {MatDivider} from '@angular/material/divider'; +import { + MatCell, + MatCellDef, + MatColumnDef, + MatHeaderCell, + MatHeaderCellDef, MatHeaderRow, + MatHeaderRowDef, MatRow, MatRowDef, + MatTable +} from '@angular/material/table'; +import {MatIconButton} from '@angular/material/button'; +import {MatIcon} from '@angular/material/icon'; +import {MatList, MatListItem} from '@angular/material/list'; +import {MatTab, MatTabGroup} from '@angular/material/tabs'; + +@Component({ + selector: 'app-system.component', + imports: [ + MatCard, + MatCardSubtitle, + MatCardContent, + MatCardHeader, + MatCardTitle, + MatDivider, + MatTable, + MatColumnDef, + MatHeaderCell, + MatCell, + MatIconButton, + MatIcon, + MatHeaderCellDef, + MatCellDef, + MatHeaderRowDef, + MatRowDef, + MatRow, + MatHeaderRow, + MatList, + MatListItem, + MatTabGroup, + MatTab + ], + templateUrl: './system.component.html', + styleUrl: './system.component.scss' +}) +export class SystemComponent { + + // @ViewChild(MatPaginator) paginator: MatPaginator; + // @ViewChild(MatSort) sort: MatSort; + + customBeans:Bean[] = [] ; + allBeans:Bean[] = [] ; + displayedColumns: string[] = ['shortName', 'typeShortName', 'scope']; + + columnsToDisplayWithExpand = [...this.displayedColumns, 'expand']; + + expandedElement: Bean | null = null; + + resultsLength = 0; + isLoadingResults = true; + isRateLimitReached = false; + + constructor(private systemService: SystemService) { } + + ngOnInit(): void { + this.retrieveBeans(); + } + + retrieveBeans(): void { + this.systemService.getCustomBeans() + .subscribe( + (data: Bean[]) => { + this.customBeans = data; + console.log(data); + }, + (error: any) => { + console.log(error); + }); + this.systemService.getAllBeans() + .subscribe( + (data: Bean[]) => { + this.allBeans = data; + console.log(data); + }, + (error: any) => { + console.log(error); + }); + } + + /** Checks whether an element is expanded. */ + isExpanded(element: Bean) { + return this.expandedElement === element; + } + + /** Toggles the expanded state of an element. */ + toggle(element: Bean) { + this.expandedElement = this.isExpanded(element) ? null : element; + } + + + + ngAfterViewInit() { + //this.exampleDatabase = new ExampleHttpDatabase(this._httpClient); + + // If the user changes the sort order, reset back to the first page. + /* this.sort.sortChange.subscribe(() => (this.paginator.pageIndex = 0)); + + merge(this.sort.sortChange, this.paginator.page) + .pipe( + startWith({}), + switchMap(() => { + this.isLoadingResults = true; + return this.exampleDatabase!.getRepoIssues( + this.sort.active, + this.sort.direction, + this.paginator.pageIndex, + ).pipe(catchError(() => observableOf(null))); + }), + map(data => { + // Flip flag to show that loading has finished. + this.isLoadingResults = false; + this.isRateLimitReached = data === null; + + if (data === null) { + return []; + } + + // Only refresh the result length if there is new data. In case of rate + // limit errors, we do not want to reset the paginator to zero, as that + // would prevent users from re-triggering requests. + this.resultsLength = data.total_count; + return data.items; + }), + ) + .subscribe(data => (this.data = data));*/ + } + +} diff --git a/jambotron-ui/src/app/directives/column-resize.directive.spec.ts b/jambotron-ui/src/app/directives/column-resize.directive.spec.ts new file mode 100644 index 0000000..181e843 --- /dev/null +++ b/jambotron-ui/src/app/directives/column-resize.directive.spec.ts @@ -0,0 +1,8 @@ +import { ColumnResizeDirective } from './column-resize.directive'; + +describe('ColumnResizeDirective', () => { + it('should create an instance', () => { + const directive = new ColumnResizeDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/directives/column-resize.directive.ts b/jambotron-ui/src/app/directives/column-resize.directive.ts new file mode 100644 index 0000000..c842abf --- /dev/null +++ b/jambotron-ui/src/app/directives/column-resize.directive.ts @@ -0,0 +1,114 @@ +import { + Directive, + ElementRef, + OnDestroy, + OnInit, + Renderer2, + NgZone, + Input, +} from '@angular/core'; +import { Subject, fromEvent, takeUntil } from 'rxjs'; + +@Directive({ + selector: '[appColumnResize]', +}) +export class ColumnResizeDirective implements OnInit, OnDestroy { + @Input() resizableTable: HTMLElement | null = null; + + private isResizing = false; + private startX!: number; + private startWidth!: number; + private column: HTMLElement; + private table: HTMLElement | null = null; + private resizer!: HTMLElement; + private destroy$ = new Subject(); + + constructor( + private el: ElementRef, + private renderer: Renderer2, + private zone: NgZone + ) { + this.column = this.el.nativeElement; + } + + ngOnInit() { + this.table = this.resizableTable || this.findParentTable(this.column); + + if (!this.table) { + console.error( + 'Parent table not found. Make sure the directive is applied to a th element within a table.' + ); + return; + } + + this.createResizer(); + this.initializeResizeListener(); + } + + private createResizer() { + this.resizer = this.renderer.createElement('div'); + this.renderer.addClass(this.resizer, 'column-resizer'); + this.renderer.setStyle(this.resizer, 'position', 'absolute'); + this.renderer.setStyle(this.resizer, 'right', '0'); + this.renderer.setStyle(this.resizer, 'top', '0'); + this.renderer.setStyle(this.resizer, 'height', '100%'); + this.renderer.setStyle(this.resizer, 'width', '5px'); + this.renderer.setStyle(this.resizer, 'cursor', 'col-resize'); + this.renderer.appendChild(this.column, this.resizer); + } + + private initializeResizeListener() { + this.zone.runOutsideAngular(() => { + fromEvent(this.resizer, 'mousedown') + .pipe(takeUntil(this.destroy$)) + .subscribe((e: Event) => this.onMouseDown(e as MouseEvent)); + + fromEvent(document, 'mousemove') + .pipe(takeUntil(this.destroy$)) + .subscribe((e: Event) => this.onMouseMove(e as MouseEvent)); + + fromEvent(document, 'mouseup') + .pipe(takeUntil(this.destroy$)) + .subscribe(() => this.onMouseUp()); + }); + } + + private onMouseDown(e: MouseEvent) { + e.preventDefault(); + this.isResizing = true; + this.startX = e.pageX; + this.startWidth = this.column.offsetWidth; + this.renderer.addClass(this.column, 'resizing'); + if (this.table) { + this.renderer.addClass(this.table, 'resizing'); + } + } + + private onMouseMove(e: MouseEvent) { + if (!this.isResizing) return; + const width = this.startWidth + (e.pageX - this.startX); + this.renderer.setStyle(this.column, 'width', `${width}px`); + } + + private onMouseUp() { + if (!this.isResizing) return; + this.isResizing = false; + this.renderer.removeClass(this.column, 'resizing'); + if (this.table) { + this.renderer.removeClass(this.table, 'resizing'); + } + } + + private findParentTable(element: HTMLElement): HTMLElement | null { + while (element && element.tagName !== 'TABLE') { + element = element.parentElement as HTMLElement; + if (!element) return null; + } + return element; + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } +} diff --git a/jambotron-ui/src/app/models/Bean.ts b/jambotron-ui/src/app/models/Bean.ts new file mode 100644 index 0000000..a920cfd --- /dev/null +++ b/jambotron-ui/src/app/models/Bean.ts @@ -0,0 +1,7 @@ +export class Bean { + name?:string; + shortName?:string; + type?:string; + typeShortName?:string; + scope?:string; +} diff --git a/jambotron-ui/src/app/services/system.service.spec.ts b/jambotron-ui/src/app/services/system.service.spec.ts new file mode 100644 index 0000000..8dbc519 --- /dev/null +++ b/jambotron-ui/src/app/services/system.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { SystemService } from './system.service'; + +describe('SystemService', () => { + let service: SystemService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(SystemService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/services/system.service.ts b/jambotron-ui/src/app/services/system.service.ts new file mode 100644 index 0000000..ffb606a --- /dev/null +++ b/jambotron-ui/src/app/services/system.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {Observable} from 'rxjs'; +import {Tutorial} from '../models/tutorial.model'; +import {Bean} from '../models/Bean'; + +@Injectable({ + providedIn: 'root' +}) +export class SystemService { + + baseUrl : string = 'http://localhost:8080/api/system'; + constructor(private http: HttpClient) { } + + getAllBeans(): Observable { + return this.http.get(this.baseUrl+"/beans"); + } + + getCustomBeans(): Observable { + return this.http.get(this.baseUrl+"/beans/custom"); + } +} diff --git a/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java b/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java index debeb88..2bfd3f8 100644 --- a/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java +++ b/src/main/java/com/jambotronGroup/jambotron/JambotronApplication.java @@ -1,14 +1,27 @@ package com.jambotronGroup.jambotron; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.event.Level; +import org.slf4j.helpers.BasicMarker; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import java.util.Iterator; + @SpringBootApplication public class JambotronApplication { + private static final Logger logger = LoggerFactory.getLogger(JambotronApplication.class); public static void main(String[] args) { SpringApplication.run(JambotronApplication.class, args); + + + logger.error("Application Run."); + logger.debug("Application Run."); + logger.info("Application Run."); } } diff --git a/src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ZhiPuAiImageService.java b/src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ZhiPuAiImageService.java new file mode 100644 index 0000000..5b34d19 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/ZhiPuAi/ZhiPuAiImageService.java @@ -0,0 +1,44 @@ +package com.jambotronGroup.jambotron.ZhiPuAi; + + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +//import org.springframework.web.reactive.function.client.WebClient; +// +//@Service +//public class ZhiPuAiImageService { +// +// @Value("${spring.ai.zhipuai.base-url}") +// private String baseUrl; +// +// @Value("${spring.ai.zhipuai.api-key}") +// private String apiKey; +// +// private final WebClient webClient; +// +// public ZhiPuAiImageService(WebClient.Builder webClientBuilder) { +// this.webClient = webClientBuilder.baseUrl(baseUrl).build(); +// } +// +// public String generateImage(String prompt) { +// return webClient.post() +// .uri("/image/generate") +// .header("Authorization", "Bearer " + apiKey) +// .bodyValue(new ImageRequest(prompt)) +// .retrieve() +// .bodyToMono(String.class) +// .block(); +// } +// +// private static class ImageRequest { +// private final String prompt; +// +// public ImageRequest(String prompt) { +// this.prompt = prompt; +// } +// +// public String getPrompt() { +// return prompt; +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/controllers/SystemController.java b/src/main/java/com/jambotronGroup/jambotron/controllers/SystemController.java new file mode 100644 index 0000000..8cca937 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/controllers/SystemController.java @@ -0,0 +1,55 @@ +package com.jambotronGroup.jambotron.controllers; + +import com.jambotronGroup.jambotron.model.Bean; +import com.jambotronGroup.jambotron.model.Setting; +import com.jambotronGroup.jambotron.system.SystemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600, allowCredentials="true") +@RestController +@RequestMapping("/api/system") +public class SystemController { + + @Autowired + SystemService systemService; + + + + @GetMapping("/beans") + public ResponseEntity> getLoadedBeans(@RequestParam(required = false) String title) { + try { + List beans = systemService.getLodedBeans(); + //userRepository.findAll().forEach(users::add); + + + if (beans.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + return new ResponseEntity<>(beans, HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + @GetMapping("/beans/custom") + public ResponseEntity> getLoadedCustomBeans(@RequestParam(required = false) String title) { + try { + List beans = systemService.getLodedCustomBeans(); + //userRepository.findAll().forEach(users::add); + + + if (beans.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + return new ResponseEntity<>(beans, HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } +} diff --git a/src/main/java/com/jambotronGroup/jambotron/controllers/ZhiPuAiController.java b/src/main/java/com/jambotronGroup/jambotron/controllers/ZhiPuAiController.java new file mode 100644 index 0000000..9c0f817 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/controllers/ZhiPuAiController.java @@ -0,0 +1,15 @@ +package com.jambotronGroup.jambotron.controllers; + +public class ZhiPuAiController { + + // This class is a placeholder for the ZhiPuAiController. + // You can implement methods to handle requests related to ZhiPuAi functionality. + // For example, you might want to add methods for generating images or processing text. + + // Example method (to be implemented): + // @GetMapping("/generate-image") + // public ResponseEntity generateImage(@RequestParam String prompt) { + // String imageUrl = zhiPuAiService.generateImage(prompt); + // return new ResponseEntity<>(imageUrl, HttpStatus.OK); + // } +} diff --git a/src/main/java/com/jambotronGroup/jambotron/model/Bean.java b/src/main/java/com/jambotronGroup/jambotron/model/Bean.java new file mode 100644 index 0000000..dd32292 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/model/Bean.java @@ -0,0 +1,86 @@ +package com.jambotronGroup.jambotron.model; + +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import lombok.ToString; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + + +@Entity +public class Bean { + + + private String name; + @Id + private String shortName; + private String type; + private String typeShortName; + private String scope; + + public Bean(String name, String type, String scope) { + this.name = name; + this.type = type; + this.scope = scope; + + this.shortName = getAfterLastDot(name); + this.typeShortName = getAfterLastDot(type); + + } + + @Override + public String toString() { + return String.format("name = %s type= %s", this.shortName, this.typeShortName); + } + + public String getAfterLastDot(String input) { + if (input == null || !input.contains(".")) { + return input; // Return the input if it's null or doesn't contain a dot + } + return input.substring(input.lastIndexOf('.') + 1); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + public String getTypeShortName() { + return typeShortName; + } + + public void setTypeShortName(String typeShortName) { + this.typeShortName = typeShortName; + } +} diff --git a/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java b/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java index 1d1df36..958da04 100644 --- a/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java +++ b/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java @@ -110,13 +110,16 @@ public class WebSecurityConfig {// extends WebSecurityConfigurerAdapter { .requestMatchers("/api/test/**").permitAll() .requestMatchers("/api/tutorials").permitAll() - .requestMatchers("api/users").permitAll() - .requestMatchers("api/users/**").permitAll() + .requestMatchers("/api/users").permitAll() + .requestMatchers("/api/users/**").permitAll() - .requestMatchers("api/roles").permitAll() - .requestMatchers("api/roles/**").permitAll() + .requestMatchers("/api/roles").permitAll() + .requestMatchers("/api/roles/**").permitAll() .requestMatchers("/api/tutorials/**").permitAll() + + .requestMatchers("/api/settings").permitAll() + .requestMatchers("/api/system/**").permitAll() .anyRequest().authenticated() ); diff --git a/src/main/java/com/jambotronGroup/jambotron/system/SystemService.java b/src/main/java/com/jambotronGroup/jambotron/system/SystemService.java new file mode 100644 index 0000000..76c8036 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/system/SystemService.java @@ -0,0 +1,12 @@ +package com.jambotronGroup.jambotron.system; + +import com.jambotronGroup.jambotron.model.Bean; + +import java.util.List; + +public interface SystemService { + List getLodedBeans(); + + List getLodedCustomBeans(); + +} diff --git a/src/main/java/com/jambotronGroup/jambotron/system/SystemServiceImpl.java b/src/main/java/com/jambotronGroup/jambotron/system/SystemServiceImpl.java new file mode 100644 index 0000000..d1f757d --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/system/SystemServiceImpl.java @@ -0,0 +1,55 @@ +package com.jambotronGroup.jambotron.system; + +import com.jambotronGroup.jambotron.JambotronApplication; +import com.jambotronGroup.jambotron.model.Bean; +import com.jambotronGroup.jambotron.utils.EntityLoggingConsumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +@Service +public class SystemServiceImpl implements SystemService { + + @Autowired + private ApplicationContext applicationContext; + @Autowired + private Environment environment; + + private static final Logger logger = LoggerFactory.getLogger(SystemServiceImpl.class); + + + @Override + public List getLodedBeans() { + // Get all bean names from the application context and map them to Bean objects + List beans = Arrays.stream(applicationContext.getBeanDefinitionNames()).map( + name -> new Bean(name, applicationContext.getType(name).getName(),applicationContext.getApplicationName())) + + .toList(); + beans.forEach(new EntityLoggingConsumer(logger)); + return beans; + } + + @Override + public List getLodedCustomBeans() { + List beans = getLodedBeans(); + + beans = beans.stream() + .filter(bean -> bean.getName() != null && + bean.getType().contains( + environment.getRequiredProperty("spring.application.name") + ) + ) + .sorted((o1, o2) -> o1.getName().compareTo(o2.getName())) + .collect(Collectors.toList()); + + return beans; + } +} \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/utils/EntityLoggingConsumer.java b/src/main/java/com/jambotronGroup/jambotron/utils/EntityLoggingConsumer.java new file mode 100644 index 0000000..73d4d83 --- /dev/null +++ b/src/main/java/com/jambotronGroup/jambotron/utils/EntityLoggingConsumer.java @@ -0,0 +1,22 @@ +package com.jambotronGroup.jambotron.utils; + +import org.slf4j.Logger; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import java.util.function.Consumer; + + + +public class EntityLoggingConsumer implements Consumer { + + private Logger _logger; + public EntityLoggingConsumer(Logger logger) + { + _logger = logger; + } + + public void accept(Object o) { + _logger.info(o.toString()); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a91b317..66f0cf0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -41,4 +41,8 @@ spring.flyway.validate-on-migrate=true spring.flyway.user=admin spring.flyway.password=postgrespw -spring.flyway.url=jdbc:postgresql://localhost:5432/jambotronDB \ No newline at end of file +spring.flyway.url=jdbc:postgresql://localhost:5432/jambotronDB + + +spring.ai.zhipuai.base-url=https://open.bigmodel.cn/api/paas/v3 +spring.ai.zhipuai.api-key = 628447c8c65845a48a7226391464a2ea.Dw8ci6TiW0BRF5LI \ No newline at end of file From 12b2c9a45824a69f01e8d69c0d819d7220bc45a6 Mon Sep 17 00:00:00 2001 From: liosha84 <138026690+liosha84@users.noreply.github.com> Date: Thu, 19 Jun 2025 18:37:43 +0300 Subject: [PATCH 2/2] Update .gitignore to exclude application log file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index cfbc25f..a021d0f 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ out/ /.gitattributes /gradle/ /src/main/resources/public/ +/logs/application.log