Merge pull request #29 from liosha84/development

Development
This commit is contained in:
liosha84
2025-07-04 10:07:55 +03:00
committed by GitHub
52 changed files with 6437 additions and 327 deletions
+4
View File
@@ -43,4 +43,8 @@ out/
/logs/application.log /logs/application.log
/logs/ /logs/
/.idea/ /.idea/
/src/main/resources/static/
/logs/ /logs/
+13 -5
View File
@@ -35,6 +35,8 @@ dependencies {
implementation 'org.flywaydb:flyway-core' implementation 'org.flywaydb:flyway-core'
implementation("org.flywaydb:flyway-database-postgresql:10.4.1") implementation("org.flywaydb:flyway-database-postgresql:10.4.1")
implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter:1.0.0-M6'
//implementation 'org.springframework.ai:spring-ai-starter-model-zhipuai' //implementation 'org.springframework.ai:spring-ai-starter-model-zhipuai'
//implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter' //implementation 'org.springframework.ai:spring-ai-zhipuai-spring-boot-starter'
//implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT") //implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT")
@@ -67,12 +69,12 @@ apply plugin: 'io.spring.dependency-management'
apply plugin: 'java' apply plugin: 'java'
tasks.register('copyResources', Copy) { /*tasks.register('copyResources', Copy) {
from 'jambotron-ui/dist/jambotron-ui/browser' from 'jambotron-ui/dist/jambotron-ui/browser'
into 'src/main/resources/public' into 'src/main/resources/public'
} }*/
processResources.dependsOn(copyResources) //processResources.dependsOn(copyResources)
compileJava.dependsOn(copyResources) //compileJava.dependsOn(copyResources)
//bootRun.dependsOn("flywayMigrate") //bootRun.dependsOn("flywayMigrate")
//flyway { //flyway {
@@ -84,12 +86,18 @@ compileJava.dependsOn(copyResources)
// locations = ['filesystem:src/main/resources/db.migration/'] // locations = ['filesystem:src/main/resources/db.migration/']
//} //}
sourceSets { /*sourceSets {
main { main {
resources { resources {
srcDir 'jambotron-ui/dist/jambotron-ui/browser' srcDir 'jambotron-ui/dist/jambotron-ui/browser'
} }
} }
}*/
tasks.register('copyAngularBuild', Copy) {
//dependsOn buildAngular
from 'jambotron-ui/dist/jambotron-ui' // Path to your Angular dist folder
into "src/main/resources/static" // Path INSIDE the WAR
} }
tasks.named('test') { tasks.named('test') {
+13 -10
View File
@@ -15,9 +15,12 @@
"prefix": "app", "prefix": "app",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular/build:application", "builder": "@angular-devkit/build-angular:browser",
"options": { "options": {
"browser": "src/main.ts", "outputPath": "dist/jambotron-ui",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": [ "polyfills": [
"zone.js" "zone.js"
], ],
@@ -38,11 +41,10 @@
"@angular/material/prebuilt-themes/azure-blue.css", "@angular/material/prebuilt-themes/azure-blue.css",
"src/styles.scss" "src/styles.scss"
], ],
"server": "src/main.server.ts", "scripts": [
"outputMode": "server", "node_modules/viewerjs/dist/viewer.min.js"
"ssr": { ]
"entry": "src/server.ts"
}
}, },
"configurations": { "configurations": {
"production": { "production": {
@@ -50,7 +52,7 @@
{ {
"type": "initial", "type": "initial",
"maximumWarning": "500kB", "maximumWarning": "500kB",
"maximumError": "1MB" "maximumError": "5MB"
}, },
{ {
"type": "anyComponentStyle", "type": "anyComponentStyle",
@@ -69,19 +71,20 @@
"defaultConfiguration": "production" "defaultConfiguration": "production"
}, },
"serve": { "serve": {
"builder": "@angular/build:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"configurations": { "configurations": {
"production": { "production": {
"buildTarget": "jambotron-ui:build:production" "buildTarget": "jambotron-ui:build:production"
}, },
"development": { "development": {
"disableHostCheck": true,
"buildTarget": "jambotron-ui:build:development" "buildTarget": "jambotron-ui:build:development"
} }
}, },
"defaultConfiguration": "development" "defaultConfiguration": "development"
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular/build:extract-i18n" "builder": "@angular-devkit/build-angular:extract-i18n"
}, },
"test": { "test": {
"builder": "@angular/build:karma", "builder": "@angular/build:karma",
+5551 -132
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -23,6 +23,7 @@
"@angular/router": "^20.0.0", "@angular/router": "^20.0.0",
"@angular/ssr": "^20.0.2", "@angular/ssr": "^20.0.2",
"@ant-design/icons-angular": "19.0.0", "@ant-design/icons-angular": "19.0.0",
"@hreimer/angular-image-viewer": "^0.14.1",
"@ng-bootstrap/ng-bootstrap": "19.0.0", "@ng-bootstrap/ng-bootstrap": "19.0.0",
"@popperjs/core": "2.11.8", "@popperjs/core": "2.11.8",
"@primeng/themes": "^19.1.3", "@primeng/themes": "^19.1.3",
@@ -32,10 +33,11 @@
"primeng": "^19.1.3", "primeng": "^19.1.3",
"rxjs": "~7.8.0", "rxjs": "~7.8.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"viewerjs": "^1.11.7",
"zone.js": "~0.15.0" "zone.js": "~0.15.0"
}, },
"devDependencies": { "devDependencies": {
"@angular/build": "^20.0.2", "@angular-devkit/build-angular": "^20.0.2",
"@angular/cli": "^20.0.2", "@angular/cli": "^20.0.2",
"@angular/compiler-cli": "^20.0.0", "@angular/compiler-cli": "^20.0.0",
"@types/express": "^5.0.1", "@types/express": "^5.0.1",
Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

+9
View File
@@ -0,0 +1,9 @@
<svg width="113" height="40" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<text font-weight="bold" xml:space="preserve"
text-anchor="start" font-family="'JetBrains Mono'"
font-size="24" id="svg_1" y="27.49999" x="2.59999" stroke-width="0" stroke="#000" fill="#000000">jambotron</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 338 B

@@ -1 +1,27 @@
<p>settings.component works!</p> <p>settings.component works!</p>
<mat-card>
<mat-card-content>
<mat-divider></mat-divider>
<mat-tab-group>
<mat-tab label="Data Source properties">
<table mat-table
[dataSource]="properties" multiTemplateDataRows="true" class="mat-elevation-z8">
@for (column of displayedColumns; track column) {
<ng-container matColumnDef="{{column}}">
<th mat-header-cell *matHeaderCellDef>{{column}}</th>
<td mat-cell *matCellDef="let element ; let k = dataIndex;">{{element[column]}}</td>
</ng-container>
}
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let element; columns: displayedColumns;"
class="example-element-row"
>
</tr>
</table>
</mat-tab>
</mat-tab-group>
</mat-card-content>
</mat-card>
@@ -1,11 +1,66 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import {MatCard, MatCardContent} from '@angular/material/card';
import {MatDivider} from '@angular/material/divider';
import {MatTab, MatTabGroup} from '@angular/material/tabs';
import {
MatCell,
MatCellDef,
MatColumnDef,
MatHeaderCell, MatHeaderCellDef,
MatHeaderRow,
MatHeaderRowDef,
MatRow, MatRowDef, MatTable
} from '@angular/material/table';
import {MatIconButton} from '@angular/material/button';
import {MatList, MatListItem} from '@angular/material/list';
import {Bean} from '../../models/Bean';
import {SystemService} from '../../services/system.service';
import {NameValueItem} from '../../models/name-value-item';
@Component({ @Component({
selector: 'app-settings.component', selector: 'app-settings.component',
imports: [], imports: [
MatCard,
MatCardContent,
MatDivider,
MatTab,
MatTabGroup,
MatCell,
MatCellDef,
MatColumnDef,
MatHeaderCell,
MatTable,
MatHeaderCellDef,
MatHeaderRow,
MatHeaderRowDef,
MatRow,
MatRowDef
],
templateUrl: './settings.component.html', templateUrl: './settings.component.html',
styleUrl: './settings.component.scss' styleUrl: './settings.component.scss'
}) })
export class SettingsComponent { export class SettingsComponent {
properties: NameValueItem[] = [] ;
displayedColumns: string[] = ['name', 'value'];
constructor(private systemService: SystemService) {
this.retrieveProperties();
}
retrieveProperties(): void {
this.systemService.getDataSourceProperties()
.subscribe(
(data: NameValueItem[]) => {
this.properties = data;
console.log(data);
},
(error: any) => {
console.log(error);
}
);
}
} }
+2
View File
@@ -11,10 +11,12 @@ import { provideClientHydration, withEventReplay } from '@angular/platform-brows
import {AppModule} from './app.module'; import {AppModule} from './app.module';
import {providePrimeNG} from 'primeng/config'; import {providePrimeNG} from 'primeng/config';
import Aura from '@primeng/themes/aura'; import Aura from '@primeng/themes/aura';
import {provideAnimations} from '@angular/platform-browser/animations';
export const appConfig: ApplicationConfig = { export const appConfig: ApplicationConfig = {
providers: [ providers: [
provideBrowserGlobalErrorListeners(), provideBrowserGlobalErrorListeners(),
provideAnimations(),
provideZoneChangeDetection({ eventCoalescing: true }), provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes), provideClientHydration(withEventReplay()), provideRouter(routes), provideClientHydration(withEventReplay()),
+14 -5
View File
@@ -5,7 +5,7 @@ import { BrowserModule }
import { BrowserAnimationsModule } import { BrowserAnimationsModule }
from '@angular/platform-browser/animations'; from '@angular/platform-browser/animations';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import {provideHttpClient, withInterceptorsFromDi} from '@angular/common/http'; import {HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi} from '@angular/common/http';
import {MainComponent} from './main-module/main.component/main.component'; import {MainComponent} from './main-module/main.component/main.component';
import {authInterceptorProviders} from './helpers/auth.interceptor'; import {authInterceptorProviders} from './helpers/auth.interceptor';
@@ -13,15 +13,19 @@ import {AdminComponent} from './admin-module/admin.component/admin.component';
import {AdminWelcomeComponent} from './admin-module/admin-welcome.component/admin-welcome.component'; import {AdminWelcomeComponent} from './admin-module/admin-welcome.component/admin-welcome.component';
import {SettingsComponent} from './admin-module/settings.component/settings.component'; import {SettingsComponent} from './admin-module/settings.component/settings.component';
import {SystemComponent} from './admin-module/system.component/system.component'; import {SystemComponent} from './admin-module/system.component/system.component';
import {appRouting} from './app.routes'; import {AppRoutingModule} from './app.routes';
import {App} from './app'; import {App} from './app';
import {CustomHttpInterceptor} from './helpers/custom-http-interceptor';
import {AngularImageViewerModule} from '@hreimer/angular-image-viewer';
import {MainModule} from './main-module/main.module';
import {CommonModule} from '@angular/common';
@NgModule({ @NgModule({
declarations: [ declarations: [
], ],
imports: [ imports: [
appRouting, AppRoutingModule,
MainComponent, MainComponent,
BrowserModule, BrowserModule,
MatIconModule, MatIconModule,
@@ -29,10 +33,15 @@ import {App} from './app';
AdminComponent, AdminComponent,
AdminWelcomeComponent, AdminWelcomeComponent,
SettingsComponent, SettingsComponent,
SystemComponent SystemComponent,
], ],
providers: [ providers: [
authInterceptorProviders,provideHttpClient(withInterceptorsFromDi())], authInterceptorProviders,provideHttpClient(withInterceptorsFromDi()),{
provide: HTTP_INTERCEPTORS,
useClass: CustomHttpInterceptor,
multi: true
}],
bootstrap: [], bootstrap: [],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ] schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
+6 -2
View File
@@ -6,7 +6,7 @@ import {NgModule} from '@angular/core';
export const routes: Routes = [ export const routes: Routes = [
{ {
path: '', path: '',
redirectTo: 'main/home', redirectTo: 'main/generate-image',
pathMatch: 'full' pathMatch: 'full'
}, },
{ {
@@ -16,5 +16,9 @@ export const routes: Routes = [
} }
]; ];
export const appRouting = RouterModule.forRoot(routes); @NgModule({
imports: [RouterModule.forRoot(routes)],//, { useHash: true }
exports: [RouterModule],
})
export class AppRoutingModule {}
@@ -62,7 +62,7 @@ export class BreadcrumbComponent {
this.navigationList = breadcrumbList;//breadcrumbList.slice(breadcrumbList.length - 1, breadcrumbList.length); this.navigationList = breadcrumbList;//breadcrumbList.slice(breadcrumbList.length - 1, breadcrumbList.length);
const title = breadcrumbList[breadcrumbList.length - 1]?.title || 'Welcome'; const title = breadcrumbList[breadcrumbList.length - 1]?.title || 'Welcome';
this.titleService.setTitle(title + ' | Mantis Angular Admin Template'); this.titleService.setTitle(title );
} }
}); });
} }
@@ -0,0 +1,27 @@
<p>generate-image.component works!</p>
<mat-card appearance="outlined">
<mat-card-header>
<mat-card-title>Generate image</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-form-field class="example-full-width">
<mat-label>Query</mat-label>
<input matInput required
[(ngModel)]="query">
</mat-form-field>
</mat-card-content>
<mat-card-actions>
@if (spinnerService.visibility | async) {
<mat-spinner [diameter]="25" ></mat-spinner>
} @else {
<button matButton (click)="generateImage()" >Generate</button>
}
</mat-card-actions>
</mat-card>
<!--<button mat-raised-button (click)="zoomPlus()" >Generate</button>
<button mat-raised-button (click)="zoomMinus()" >Generate</button>-->
<img src={{image.url}} />
@@ -0,0 +1,3 @@
.example-full-width {
width: 100%;
}
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { GenerateImageComponent } from './generate-image.component';
describe('GenerateImageComponent', () => {
let component: GenerateImageComponent;
let fixture: ComponentFixture<GenerateImageComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [GenerateImageComponent]
})
.compileComponents();
fixture = TestBed.createComponent(GenerateImageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,89 @@
import {Component, CUSTOM_ELEMENTS_SCHEMA, Input, OnInit, Renderer2} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {MatButton} from '@angular/material/button';
import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card';
import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
import {AsyncPipe, NgIf, NgOptimizedImage} from '@angular/common';
import {Image} from '../../models/image';
import {ZhipuaiImageService} from '../../services/zhipuai-image.service';
import {MatProgressSpinner} from '@angular/material/progress-spinner';
import {SpinnerService} from '../../services/spinner.service';
import Viewer from 'viewerjs';
@Component({
selector: 'app-generate-image.component',
imports: [
FormsModule,
MatButton,
MatCard,
MatCardActions,
MatCardContent,
MatCardHeader,
MatFormField,
MatInput,
MatLabel,
MatProgressSpinner,
AsyncPipe,
],
templateUrl: './generate-image.component.html',
styleUrl: './generate-image.component.scss',
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class GenerateImageComponent implements OnInit {
isSpinnerVisible = false;
query : string = '';
images = [];
image: Image = {
url: ''
};
viewer: any;
constructor(private zhipuaiImageService: ZhipuaiImageService,public spinnerService: SpinnerService,
private renderer: Renderer2) {
}
ngOnInit(): void {
const img = this.renderer.selectRootElement('img');
this.viewer = new Viewer(img, {
inline: true,
});
this.viewer.zoomTo(1);
}
generateImage(){
this.zhipuaiImageService.generate(this.query).subscribe(
data => {
this.image = data;
// @ts-ignore
this.images = [this.image.url];
console.log(data);
},
error => {
console.log(error);
}
).add(() => {
//this.viewer.
this.viewer.update();
})
}
zoomPlus(){
this.viewer.zoomTo(5);
}
zoomMinus(){
this.viewer.zoomTo(-5);
}
}
@@ -1,51 +1,50 @@
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p><p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p><p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p> <p>dfsdgdsgsdg</p>
<p>home.component works!</p>
<p>home.component works!</p>
<p>home.component works!</p>
<p>home.component works!</p>
<p>home.component works!</p>
<p>home.component works!</p>
<p>home.component works!</p> <!--
<p>home.component works!</p> <mat-card appearance="outlined">
<p>home.component works!</p> <mat-card-header>
<p>home.component works!</p> <mat-card-title>Add tutorial</mat-card-title>
<p>home.component works!</p> </mat-card-header>
<p>home.component works!</p> <mat-card-content *ngIf="!submitted">
<p>home.component works!</p> <mat-form-field class="example-full-width">
<p>home.component works!</p> <mat-label>Title</mat-label>
<p>home.component works!</p> <input matInput [(ngModel)]="query">
<p>home.component works!</p> </mat-form-field>
<p>home.component works!</p> &lt;!&ndash; <kendo-editor [(ngModel)]="tutorial.description" ></kendo-editor>&ndash;&gt;
<p>home.component works!</p>
<p>home.component works!</p> </mat-card-content>
<p>home.component works!</p> <mat-card-actions>
<p>home.component works!</p> <button matButton (click)="generateImage()" >Save</button>
<p>home.component works!</p> <div>
<p>home.component works!</p> <h4>Tutorial was submitted successfully!</h4>
<p>home.component works!</p>
<p>home.component works!</p> </div>
<p>home.component works!</p> </mat-card-actions>
<p>home.component works!</p> </mat-card>
<p>home.component works!</p>
<p>home.component works!</p>
<p>home.component works!</p> <div>
<p>home.component works!</p> <angular-image-viewer [src]="images" [(config)]="config" [(index)]="imageIndexOne"
<p>home.component works!</p> [screenHeightOccupied]='0' (customImageEvent)="handleEvent($event)" >
<p>home.component works!</p> </angular-image-viewer>
<p>home.component works!</p> </div>
<p>home.component works!</p> -->
<p>home.component works!</p>
@@ -1,11 +1,76 @@
import { Component } from '@angular/core'; import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
import {AngularImageViewerModule, CustomImageEvent, ImageViewerConfig} from '@hreimer/angular-image-viewer';
import {ZhipuaiImageService} from '../../services/zhipuai-image.service';
import {MatButton} from '@angular/material/button';
import {FormsModule} from '@angular/forms';
import {CommonModule} from '@angular/common';
import {BrowserModule} from '@angular/platform-browser';
import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card';
import {Image} from '../../models/image';
@Component({ @Component({
selector: 'app-home.component', selector: 'app-home.component',
imports: [], imports: [
AngularImageViewerModule,
FormsModule
],
templateUrl: './home.component.html', templateUrl: './home.component.html',
styleUrl: './home.component.scss' styleUrl: './home.component.scss',
schemas :[CUSTOM_ELEMENTS_SCHEMA]
}) })
export class HomeComponent { export class HomeComponent {
query : string = '';
images = [];
image: Image = {
url: ''
};
imageIndexOne = 0;
config: ImageViewerConfig = { customBtns: [{ name: 'print', icon: {
classes: 'fas fa-paperclip',
text: 'link'
} }, { name: 'link', icon: {
classes: 'fas fa-paperclip',
text: 'link'
} }] };
submitted: boolean = false;
constructor(private zhipuaiImageService: ZhipuaiImageService) {
}
handleEvent(event: CustomImageEvent) {
console.log(`${event.name} has been click on img ${event.imageIndex + 1}`);
switch (event.name) {
case 'print':
console.log('run print logic');
break;
}
}
generateImage(){
this.zhipuaiImageService.generate(this.query).subscribe(
data => {
this.image = data;
// @ts-ignore
this.images = [this.image.url];
console.log(data);
},
error => {
console.log(error);
}
)
}
} }
@@ -0,0 +1,7 @@
import { CustomHttpInterceptor } from './custom-http-interceptor';
describe('CustomHttpInterceptor', () => {
it('should create an instance', () => {
expect(new CustomHttpInterceptor()).toBeTruthy();
});
});
@@ -0,0 +1,24 @@
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {Observable, tap} from 'rxjs';
import {SpinnerService} from '../services/spinner.service';
import {Injectable} from '@angular/core';
@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
constructor(private spinnerService: SpinnerService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.spinnerService.show();
return next.handle(req)
.pipe(tap((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
this.spinnerService.hide();
}
}, (error) => {
this.spinnerService.hide();
}));
}
}
@@ -104,7 +104,7 @@
<h6 class="mb-0">JWT User</h6> <h6 class="mb-0">JWT User</h6>
<span>UI/UX Designer</span> <span>UI/UX Designer</span>
</div> </div>
<a href="javascript:" class="bg-transparent"><i class="d-flex f-20" antIcon theme="outline" type="logout"></i></a> <a href="javascript:" class="bg-transparent"><i class="d-flex f-20" antIcon theme="outline" type="login"></i></a>
</div> </div>
</div> </div>
<ul ngbNav #nav="ngbNav" class="nav drp-tabs nav-fill nav-tabs"> <ul ngbNav #nav="ngbNav" class="nav drp-tabs nav-fill nav-tabs">
@@ -1,4 +1,4 @@
<li data-username="mantis dashboard" class="nav-item coded-hasmenu" [routerLinkActive]="['active']"> <li data-username="dashboard" class="nav-item coded-hasmenu" [routerLinkActive]="['active']">
<a [routerLinkActive]="['active']" (click)="navCollapse($event)"> <a [routerLinkActive]="['active']" (click)="navCollapse($event)">
@if (item.icon) { @if (item.icon) {
<span class="coded-micon"> <span class="coded-micon">
@@ -8,27 +8,5 @@
} }
} }
</ul> </ul>
<div class="m-4 mb-0">
<div class="card nav-card">
<div class="card-body">
<div class="d-flex flex-column align-items-center">
<img src="assets/images/avatar-group.png" alt="user" class="img-fluid" />
<div class="m-t-20 text-center">
<h5 class="mb-0">Mantis Pro</h5>
<span class="text-muted">Checkout pro features</span>
</div>
<div class="m-t-20 text-center">
<a
href="https://codedthemes.com/item/mantis-angular-admin-template/?utm_source=free_demo&utm_medium=codedthemes&utm_campaign=button_download_premium"
target="_blank"
class="btn btn-primary text-white"
>
Pro
</a>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</ng-scrollbar> </ng-scrollbar>
@@ -1,10 +1,14 @@
<!--<p>main.component works!</p>--> <!--<p>main.component works!</p>-->
<mat-toolbar class="fixed-top"> <mat-toolbar class="fixed-top">
<button mat-raised-button routerLink="/" href="#"> <button mat-raised-button routerLink="home">
<!-- <img ngSrc="jambotron_logo.svg" height="40" width="135">-->
My App My App
</button> </button>
<span class="menu-spacer"></span> <span class="menu-spacer"></span>
<button mat-raised-button routerLink="generate-image">
Generate Image
</button>
<button mat-raised-button routerLink="tutorials"> <button mat-raised-button routerLink="tutorials">
Tutorials Tutorials
</button> </button>
@@ -16,14 +20,14 @@
<span class="menu-spacer"></span> <span class="menu-spacer"></span>
@if (showAdminBoard) { @if (showAdminBoard) {
<button mat-raised-button routerLink="admin/welcome"> <button mat-raised-button routerLink="admin/welcome">
<mat-icon>manage_accounts</mat-icon> <!-- <mat-icon>manage_accounts</mat-icon>-->
Admin Bord Admin Bord
</button> </button>
} }
@if (showAdminBoard) { @if (showAdminBoard) {
<button mat-raised-button routerLink="system" > <button mat-raised-button routerLink="admin/system" >
<mat-icon>settings_applications</mat-icon> <!-- <mat-icon>settings_applications</mat-icon>-->
System System
</button> </button>
} }
@@ -31,7 +35,7 @@
<span class="menu-spacer"></span> <span class="menu-spacer"></span>
@if (isLoggedIn) { @if (isLoggedIn) {
<button mat-raised-button routerLink="register"> <button mat-raised-button routerLink="register">
<mat-icon>app_registration</mat-icon> <!-- <mat-icon>app_registration</mat-icon>-->
Register Register
</button> </button>
} }
@@ -39,16 +43,17 @@
<button mat-raised-button (click)="openDialog('100ms', '5ms')" > <button mat-raised-button (click)="openDialog('100ms', '5ms')" >
<!-- <i antIcon type="bell" theme="outline"></i>--> <!-- <i antIcon type="bell" theme="outline"></i>-->
<!-- <mat-icon>login</mat-icon>--> <!-- <mat-icon>login</mat-icon>-->
Login <!-- <i class="d- f-20" antIcon theme="outline" type="login">Login</i>-->
</button> </button>
} }
@if (isLoggedIn) { @if (isLoggedIn) {
<button mat-raised-button routerLink="profile" > <button mat-raised-button routerLink="profile" >
<mat-icon>account_circle</mat-icon> <!-- <mat-icon>account_circle</mat-icon>-->
{{ username }} {{ username }}
</button> </button>
<button mat-raised-button (click)="logout()"> <button mat-raised-button (click)="logout()">
<mat-icon>logout</mat-icon>
<!-- <i class="d-flex f-20" antIcon theme="outline" type="logout"></i>-->
Logout Logout
</button> </button>
@@ -13,3 +13,8 @@ mat-toolbar{
left: 0; left: 0;
z-index: 1000; // Ensure toolbar stays above other content z-index: 1000; // Ensure toolbar stays above other content
} }
.mat-mdc-raised-button:not(:disabled){
color: rgba(24, 255, 255, 0.96);
background-color: rgba(24,255,255,0.04);
}
@@ -1,35 +1,44 @@
import {Component, CUSTOM_ELEMENTS_SCHEMA, inject} from '@angular/core'; import {Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit} from '@angular/core';
//import {NavigationComponent} from '../navigation/navigation.component'; //import {NavigationComponent} from '../navigation/navigation.component';
import {NgClass} from '@angular/common';
import {NavigationComponent} from '../../layouts/admin-layout/navigation/navigation.component'; import {Router, RouterLink, RouterOutlet} from '@angular/router';
import {RouterLink, RouterOutlet} from '@angular/router';
import {BreadcrumbComponent} from '../../components/breadcrumb/breadcrumb.component';
import {NavBarComponent} from '../../layouts/admin-layout/nav-bar/nav-bar.component';
import {MatToolbar} from '@angular/material/toolbar'; import {MatToolbar} from '@angular/material/toolbar';
import {MatButton} from '@angular/material/button'; import {MatButton} from '@angular/material/button';
import {IconDirective} from '@ant-design/icons-angular'; import {IconDirective, IconService} from '@ant-design/icons-angular';
import {MatDialog} from '@angular/material/dialog'; import {MatDialog} from '@angular/material/dialog';
import {Subscription} from 'rxjs'; import {Subscription} from 'rxjs';
import {TokenStorageService} from '../../services/token-storage.service'; import {TokenStorageService} from '../../services/token-storage.service';
import {AuthService} from '../../services/auth.service'; import {AuthService} from '../../services/auth.service';
import {EventBusService} from '../../_shared/event-bus.service'; import {EventBusService} from '../../_shared/event-bus.service';
import {DialogComponent} from '../../components/dialog/dialog.component'; import {DialogComponent} from '../../components/dialog/dialog.component';
import {
ArrowRightOutline, BellOutline,
CheckCircleOutline, CommentOutline, EditOutline,
GiftOutline, GithubOutline, LockOutline, LogoutOutline,
MessageOutline,
PhoneOutline, ProfileOutline, QuestionCircleOutline,
SettingOutline, UnorderedListOutline, UserOutline, WalletOutline
} from '@ant-design/icons-angular/icons';
import {BrowserModule} from '@angular/platform-browser';
import {CommonModule} from '@angular/common';
@Component({ @Component({
selector: 'app-main.component', selector: 'app-main.component',
imports: [ imports: [
NavBarComponent,
MatToolbar, MatToolbar,
MatButton, MatButton,
RouterLink, RouterLink,
IconDirective, IconDirective,
RouterOutlet RouterOutlet,
CommonModule
], ],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
templateUrl: './main.component.html', templateUrl: './main.component.html',
styleUrl: './main.component.scss' styleUrl: './main.component.scss'
}) })
export class MainComponent { export class MainComponent implements OnInit{
// public props // public props
navCollapsed: boolean = false; navCollapsed: boolean = false;
navCollapsedMob: boolean = false; navCollapsedMob: boolean = false;
@@ -51,14 +60,48 @@ export class MainComponent {
private storageService: TokenStorageService = inject(TokenStorageService); private storageService: TokenStorageService = inject(TokenStorageService);
private authService: AuthService = inject(AuthService); private authService: AuthService = inject(AuthService);
private eventBusService: EventBusService = inject(EventBusService); private eventBusService: EventBusService = inject(EventBusService);
private iconService = inject(IconService);
constructor(
) {}
constructor(private router: Router) {
this.iconService.addIcon(
...[
CheckCircleOutline,
GiftOutline,
MessageOutline,
SettingOutline,
PhoneOutline,
LogoutOutline,
UserOutline,
EditOutline,
ProfileOutline,
QuestionCircleOutline,
LockOutline,
CommentOutline,
UnorderedListOutline,
ArrowRightOutline,
BellOutline,
GithubOutline,
WalletOutline
]
);
}
goToHome() {
this.router.navigate(['main/home']);
}
ngOnInit(): void { ngOnInit(): void {
this.isLoggedIn = this.storageService.isLoggedIn(); this.isLoggedIn = this.storageService.isLoggedIn();
this.refreshToolbar();
this.eventBusSub = this.eventBusService.on('logout', () => {
this.logout();
});
}
refreshToolbar() {
if (this.isLoggedIn) { if (this.isLoggedIn) {
const user = this.storageService.getUser(); const user = this.storageService.getUser();
this.roles = user.roles; this.roles = user.roles;
@@ -68,10 +111,12 @@ export class MainComponent {
this.username = user.username; this.username = user.username;
} }
}
this.eventBusSub = this.eventBusService.on('logout', () => { ngOnDestroy() {
this.logout(); if (this.eventBusSub) {
}); this.eventBusSub.unsubscribe();
}
} }
// public method // public method
@@ -142,7 +187,8 @@ export class MainComponent {
let user = this.storageService.getUser(); let user = this.storageService.getUser();
this.roles = user.roles; this.roles = user.roles;
//this.username = user.username; //this.username = user.username;
this.reloadPage(); //this.reloadPage();
this.refreshToolbar();
}, },
err => { err => {
this.errorMessage = err.error.message; this.errorMessage = err.error.message;
@@ -2,12 +2,30 @@ import {RouterModule} from '@angular/router';
import {MainComponent} from './main.component/main.component'; import {MainComponent} from './main.component/main.component';
import {mainRouting} from './main.routing'; import {mainRouting} from './main.routing';
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {HTTP_INTERCEPTORS} from '@angular/common/http';
import {CustomHttpInterceptor} from '../helpers/custom-http-interceptor';
import {AngularImageViewerModule} from '@hreimer/angular-image-viewer';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
@NgModule({ @NgModule({
declarations: [ declarations: [
], ],
imports: [mainRouting, MainComponent], imports: [
mainRouting,
MainComponent,
],
exports: [RouterModule], exports: [RouterModule],
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: CustomHttpInterceptor,
multi: true
}],
}) })
export class MainModule {} export class MainModule {}
@@ -6,6 +6,7 @@ import {TutorialsComponent} from '../components/tutorials.component/tutorials.co
import {AddTutorialComponent} from '../components/add-tutorial/add-tutorial.component'; import {AddTutorialComponent} from '../components/add-tutorial/add-tutorial.component';
import {RegisterComponent} from '../components/register/register.component'; import {RegisterComponent} from '../components/register/register.component';
import {ProfileComponent} from '../components/profile/profile.component'; import {ProfileComponent} from '../components/profile/profile.component';
import {GenerateImageComponent} from '../components/generate-image.component/generate-image.component';
const MAIN_ROUTES: Routes =[ const MAIN_ROUTES: Routes =[
{ {
@@ -21,6 +22,10 @@ const MAIN_ROUTES: Routes =[
path: 'home', path: 'home',
component: HomeComponent component: HomeComponent
}, },
{
path: 'generate-image',
component: GenerateImageComponent
},
{ {
path: 'tutorials', path: 'tutorials',
component: TutorialsComponent component: TutorialsComponent
+5
View File
@@ -0,0 +1,5 @@
export class Image {
url?:string;
b64Json?:boolean;
}
@@ -0,0 +1,4 @@
export class NameValueItem {
name?:string;
value?:string;
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { SpinnerService } from './spinner.service';
describe('SpinnerService', () => {
let service: SpinnerService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(SpinnerService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import {BehaviorSubject} from 'rxjs';
@Injectable({ providedIn: 'root'})
export class SpinnerService {
visibility: BehaviorSubject<boolean>;
constructor() {
this.visibility = new BehaviorSubject(false);
}
show() {
this.visibility.next(true);
}
hide() {
this.visibility.next(false);
}
}
@@ -3,6 +3,7 @@ import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import {Tutorial} from '../models/tutorial.model'; import {Tutorial} from '../models/tutorial.model';
import {Bean} from '../models/Bean'; import {Bean} from '../models/Bean';
import {NameValueItem} from '../models/name-value-item';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@@ -12,10 +13,18 @@ export class SystemService {
baseUrl : string = 'http://localhost:8080/api/system'; baseUrl : string = 'http://localhost:8080/api/system';
constructor(private http: HttpClient) { } constructor(private http: HttpClient) { }
getDataSourceProperties(): Observable<NameValueItem[]>{
return this.http.get<NameValueItem[]>(this.baseUrl + "/data-source-properties")
}
getAllBeans(): Observable<Bean[]> { getAllBeans(): Observable<Bean[]> {
return this.http.get<Bean[]>(this.baseUrl+"/beans"); return this.http.get<Bean[]>(this.baseUrl+"/beans");
} }
getImage(): Observable<Blob> {
return this.http.get(this.baseUrl+"/image", {responseType: 'blob'});
}
getCustomBeans(): Observable<Bean[]> { getCustomBeans(): Observable<Bean[]> {
return this.http.get<Bean[]>(this.baseUrl+"/beans/custom"); return this.http.get<Bean[]>(this.baseUrl+"/beans/custom");
} }
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ZhipuaiImageService } from './zhipuai-image.service';
describe('ZhipuaiImageService', () => {
let service: ZhipuaiImageService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ZhipuaiImageService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs';
import {Tutorial} from '../models/tutorial.model';
import {HttpClient} from '@angular/common/http';
import {Image} from '../models/image';
import {SpinnerService} from './spinner.service';
@Injectable({
providedIn: 'root'
})
export class ZhipuaiImageService {
baseUrl : string = 'http://localhost:8080/api/zhipuai';
constructor(private http: HttpClient,public spinnerService: SpinnerService) {
}
generate(query: String): Observable<Image> {
return this.http.get(`${(this.baseUrl)}/image/${query}`);
}
}
+1 -1
View File
@@ -40,7 +40,7 @@ File: style.css
html, body { height: 100%; } html, body { height: 100%; }
body { body {
background-image: url('../public/Firefly_jambo tron 118290.png'); background-image: url('../public/Firefly_jambo tron 118290.jpg');
background-attachment:fixed; background-attachment:fixed;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
@@ -0,0 +1,39 @@
package com.jambotronGroup.jambotron.ZhiPuAi;
import com.jambotronGroup.jambotron.model.NameValueItem;
import org.springframework.ai.image.Image;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.zhipuai.ZhiPuAiImageModel;
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, https://pony-sincere-chimp.ngrok-free.app/", maxAge = 3600, allowCredentials="true")
@RestController
@RequestMapping("/api/zhipuai")
public class ImageController {
@Autowired
ZhiPuAiImageService _zhiPuAiImageService;
@GetMapping("/image/{query}")
public ResponseEntity<Image> getImage(@PathVariable("query") String query) {
try {
Image returnValue = _zhiPuAiImageService.generateImage(query).getResult().getOutput();
//userRepository.findAll().forEach(users::add);
if (returnValue == null) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(returnValue, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
@@ -1,44 +1,45 @@
package com.jambotronGroup.jambotron.ZhiPuAi; package com.jambotronGroup.jambotron.ZhiPuAi;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.zhipuai.ZhiPuAiImageModel;
import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
//import org.springframework.web.reactive.function.client.WebClient; //import org.springframework.web.reactive.function.client.WebClient;
// //
//@Service @Service
//public class ZhiPuAiImageService { public class ZhiPuAiImageService {
//
// @Value("${spring.ai.zhipuai.base-url}") @Value("${spring.ai.zhipuai.base-url}")
// private String baseUrl; private String baseUrl;
//
// @Value("${spring.ai.zhipuai.api-key}") @Value("${spring.ai.zhipuai.api-key}")
// private String apiKey; private String apiKey;
//
// private final WebClient webClient;
// private ZhiPuAiImageApi _zhiPuAiImageApi;
// public ZhiPuAiImageService(WebClient.Builder webClientBuilder) {
// this.webClient = webClientBuilder.baseUrl(baseUrl).build(); private ZhiPuAiImageModel _zhiPuAiImageModel;
// }
// public ZhiPuAiImageService() {
// public String generateImage(String prompt) {
// return webClient.post() _zhiPuAiImageApi = new ZhiPuAiImageApi("628447c8c65845a48a7226391464a2ea.Dw8ci6TiW0BRF5LI");
// .uri("/image/generate")
// .header("Authorization", "Bearer " + apiKey) _zhiPuAiImageModel = new ZhiPuAiImageModel(_zhiPuAiImageApi);
// .bodyValue(new ImageRequest(prompt)) }
// .retrieve()
// .bodyToMono(String.class) public ImageResponse generateImage(String prompt) {
// .block(); // Create an ImagePrompt object with the desired prompt
// } ImagePrompt imagePrompt = new ImagePrompt(prompt);
//
// private static class ImageRequest { // Call the generate method to get the image response
// private final String prompt; ImageResponse imageResponse = _zhiPuAiImageModel.call(imagePrompt);
//
// public ImageRequest(String prompt) { // Return the image response
// this.prompt = prompt; return imageResponse;
// } }
//
// public String getPrompt() {
// return prompt; }
// }
// }
//}
@@ -2,10 +2,13 @@ package com.jambotronGroup.jambotron.configuretions;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/*
@Configuration @Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer { public class MvcConfig implements WebMvcConfigurer {
@Value("${spring.resources.static-locations}") @Value("${spring.resources.static-locations}")
String resourceLocations; String resourceLocations;
@@ -13,7 +16,10 @@ public class MvcConfig implements WebMvcConfigurer {
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
//registry.addResourceHandler("/public/**").addResourceLocations(resourceLocations); //registry.addResourceHandler("/public/**").addResourceLocations(resourceLocations);
// registry.addResourceHandler("/media/**").addResourceLocations("resources/main/public/media/"); registry.addResourceHandler("/**").addResourceLocations("classpath:/resources/");
//registry.
registry.addResourceHandler("/media/**").addResourceLocations("resources/main/public/media/");
} }
} }*/
@@ -15,7 +15,6 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
/* /*
@ControllerAdvice @ControllerAdvice
public class NotFoundHandler { public class NotFoundHandler {
@Value("${spa.default-file}") @Value("${spa.default-file}")
@@ -30,7 +30,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
//@CrossOrigin(origins = "*", maxAge = 3600) //@CrossOrigin(origins = "*", maxAge = 3600)
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600, allowCredentials="true") @CrossOrigin(origins = "http://localhost:4200,https://a576-5-248-149-207.ngrok-free.app, https://pony-sincere-chimp.ngrok-free.app", maxAge = 3600, allowCredentials="true")
@RestController @RestController
@RequestMapping("/api/auth") @RequestMapping("/api/auth")
public class AuthController { public class AuthController {
@@ -0,0 +1,12 @@
package com.jambotronGroup.jambotron.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/*@Controller
public class RedirectController {
@RequestMapping(value = "/{path:[^&#92;&#92;.]*}")
public String redirect() {
return "forward:/index.html";
}
}*/
@@ -1,9 +1,12 @@
package com.jambotronGroup.jambotron.controllers; package com.jambotronGroup.jambotron.controllers;
import com.jambotronGroup.jambotron.model.Bean; import com.jambotronGroup.jambotron.model.Bean;
import com.jambotronGroup.jambotron.model.NameValueItem;
import com.jambotronGroup.jambotron.model.Setting; import com.jambotronGroup.jambotron.model.Setting;
import com.jambotronGroup.jambotron.system.SystemService; import com.jambotronGroup.jambotron.system.SystemService;
import org.springframework.beans.factory.NamedBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -20,6 +23,26 @@ public class SystemController {
@GetMapping("/data-source-properties")
public ResponseEntity<List<NameValueItem>> getDataSourceProperties(@RequestParam(required = false) String title) {
try {
List<NameValueItem> properties = systemService.getDataSourceProperties();
//userRepository.findAll().forEach(users::add);
if (properties.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(properties, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/beans") @GetMapping("/beans")
public ResponseEntity<List<Bean>> getLoadedBeans(@RequestParam(required = false) String title) { public ResponseEntity<List<Bean>> getLoadedBeans(@RequestParam(required = false) String title) {
try { try {
@@ -1,15 +0,0 @@
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<String> generateImage(@RequestParam String prompt) {
// String imageUrl = zhiPuAiService.generateImage(prompt);
// return new ResponseEntity<>(imageUrl, HttpStatus.OK);
// }
}
@@ -32,6 +32,7 @@ public class Bean {
@Override @Override
public String toString() { public String toString() {
return String.format("name = %s type= %s", this.shortName, this.typeShortName); return String.format("name = %s type= %s", this.shortName, this.typeShortName);
} }
@@ -0,0 +1,40 @@
package com.jambotronGroup.jambotron.model;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class NameValueItem {
public NameValueItem(String name, String value){
_name = name;
_value = value;
}
@Id
private String _name;
private String _value;
public String getValue() {
return _value;
}
public void setValue(String _value) {
this._value = _value;
}
public String getName() {
return _name;
}
public void setName(String _name) {
this._name = _name;
}
@Override
public String toString() {
return String.format("name = %s value= %s", this._name, this._value);
}
}
@@ -16,6 +16,8 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
@EnableMethodSecurity @EnableMethodSecurity
@@ -24,7 +26,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
// securedEnabled = true, // securedEnabled = true,
// jsr250Enabled = true, // jsr250Enabled = true,
//prePostEnabled = true) //prePostEnabled = true)
public class WebSecurityConfig {// extends WebSecurityConfigurerAdapter { public class WebSecurityConfig implements WebMvcConfigurer {// extends WebSecurityConfigurerAdapter {
@Autowired @Autowired
UserDetailsServiceImpl userDetailsService; UserDetailsServiceImpl userDetailsService;
@@ -41,6 +43,11 @@ public class WebSecurityConfig {// extends WebSecurityConfigurerAdapter {
// authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); // authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
// } // }
@Override
public void addCorsMappings(CorsRegistry registry) {
// Do not add any mappings to enable complete disabling of CORS.
}
@Bean @Bean
public DaoAuthenticationProvider authenticationProvider() { public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
@@ -106,10 +113,15 @@ public class WebSecurityConfig {// extends WebSecurityConfigurerAdapter {
auth.requestMatchers("/api/auth/**").permitAll() auth.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/*", "/home", "/resources/**").permitAll() .requestMatchers("/*", "/home", "/resources/**").permitAll()
.requestMatchers("/resources/public/media/**").permitAll() .requestMatchers("/resources/public/media/**").permitAll()
.requestMatchers("/resources/public/browser/**").permitAll()
.requestMatchers("/media/**").permitAll() .requestMatchers("/media/**").permitAll()
.requestMatchers("/main/**").permitAll()
.requestMatchers("/api/test/**").permitAll() .requestMatchers("/api/test/**").permitAll()
.requestMatchers("/api/tutorials").permitAll() .requestMatchers("/api/tutorials").permitAll()
.requestMatchers("/api/zhipuai/image/**").permitAll()
.requestMatchers("/api/users").permitAll() .requestMatchers("/api/users").permitAll()
.requestMatchers("/api/users/**").permitAll() .requestMatchers("/api/users/**").permitAll()
@@ -1,6 +1,7 @@
package com.jambotronGroup.jambotron.system; package com.jambotronGroup.jambotron.system;
import com.jambotronGroup.jambotron.model.Bean; import com.jambotronGroup.jambotron.model.Bean;
import com.jambotronGroup.jambotron.model.NameValueItem;
import java.util.List; import java.util.List;
@@ -9,4 +10,8 @@ public interface SystemService {
List<Bean> getLodedCustomBeans(); List<Bean> getLodedCustomBeans();
List<NameValueItem> getDataSourceProperties();
List<NameValueItem> getImage();
} }
@@ -1,17 +1,24 @@
package com.jambotronGroup.jambotron.system; package com.jambotronGroup.jambotron.system;
import com.jambotronGroup.jambotron.JambotronApplication; import com.jambotronGroup.jambotron.JambotronApplication;
import com.jambotronGroup.jambotron.controllers.SystemController;
import com.jambotronGroup.jambotron.model.Bean; import com.jambotronGroup.jambotron.model.Bean;
import com.jambotronGroup.jambotron.model.NameValueItem;
import com.jambotronGroup.jambotron.utils.EntityLoggingConsumer; import com.jambotronGroup.jambotron.utils.EntityLoggingConsumer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.zhipuai.ZhiPuAiImageModel;
import org.springframework.ai.zhipuai.api.ZhiPuAiImageApi;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.data.web.config.SpringDataWebSettings;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays; import java.util.*;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -23,9 +30,50 @@ public class SystemServiceImpl implements SystemService {
@Autowired @Autowired
private Environment environment; private Environment environment;
@Autowired
DataSourceProperties _dataSourceProperties;
@Autowired
ZhiPuAiImageModel imageClient;
private static final Logger logger = LoggerFactory.getLogger(SystemServiceImpl.class); private static final Logger logger = LoggerFactory.getLogger(SystemServiceImpl.class);
@Override
public List<NameValueItem> getDataSourceProperties(){
List<NameValueItem> returnValue = new ArrayList<NameValueItem>();
returnValue.add(new NameValueItem("Username", _dataSourceProperties.getUsername()));
returnValue.add(new NameValueItem("Password", _dataSourceProperties.getPassword()));
returnValue.add(new NameValueItem("Url", _dataSourceProperties.getUrl()));
return returnValue;
}
@Override
public List<NameValueItem> getImage(){
List<NameValueItem> returnValue = new ArrayList<NameValueItem>();
ZhiPuAiImageApi api = new ZhiPuAiImageApi("628447c8c65845a48a7226391464a2ea.Dw8ci6TiW0BRF5LI");
ZhiPuAiImageModel imageClient = new ZhiPuAiImageModel(api);
//imageClient.
//imageClient.getDefaultOptions().setUser("44621746535994937");
ImageResponse imageResponse = imageClient.call(new ImagePrompt("Ukr zaliznicya station in the style cubisme"));
returnValue.add(new NameValueItem("response", "imageResponse."));
return returnValue;
}
@Override @Override
public List<Bean> getLodedBeans() { public List<Bean> getLodedBeans() {
// Get all bean names from the application context and map them to Bean objects // Get all bean names from the application context and map them to Bean objects
+9 -5
View File
@@ -29,10 +29,12 @@ spring.mvc.throw-exception-if-no-handler-found=true
# Disable the default mappings # Disable the default mappings
#spring.resources.add-mappings=false #spring.resources.add-mappings=false
spring.resources.static-locations=classpath:/public # UI(index.html) location
spring.resources.cache.period=31557600s # 1 year if you want #spring.resources.static-locations=classpath:/public/browser/
spa.default-file=classpath:/public/browser/index.html #
#spring.resources.cache.period=31557600s # 1 year if you want
#spa.default-file=classpath:/public/browser/index.html
#
spring.docker.compose.file=../Docker/docker-compose.yml spring.docker.compose.file=../Docker/docker-compose.yml
@@ -44,5 +46,7 @@ spring.flyway.password=postgrespw
spring.flyway.url=jdbc:postgresql://localhost:5432/jambotronDB spring.flyway.url=jdbc:postgresql://localhost:5432/jambotronDB
spring.ai.zhipuai.base-url=https://open.bigmodel.cn/api/paas/v3
spring.ai.zhipuai.base-url=https://open.bigmodel.cn/api/paas/v4/images/generations
spring.ai.zhipuai.api-key = 628447c8c65845a48a7226391464a2ea.Dw8ci6TiW0BRF5LI spring.ai.zhipuai.api-key = 628447c8c65845a48a7226391464a2ea.Dw8ci6TiW0BRF5LI
@@ -0,0 +1,6 @@
-- Column: public.tutorials.
ALTER TABLE IF EXISTS public.tutorials DROP COLUMN IF EXISTS id;
ALTER TABLE IF EXISTS public.tutorials
ADD COLUMN id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 );