Revize 00466dc7
Přidáno uživatelem Ondřej Váně před téměř 5 roky(ů)
be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/IndexController.java | ||
---|---|---|
2 | 2 |
|
3 | 3 |
import cz.zcu.kiv.aswi.fulltextsearch.model.Query; |
4 | 4 |
import cz.zcu.kiv.aswi.fulltextsearch.model.QueryResponse; |
5 |
import cz.zcu.kiv.aswi.fulltextsearch.model.ResponseMessage; |
|
5 | 6 |
import org.apache.solr.client.solrj.SolrServerException; |
7 |
import org.springframework.http.HttpStatus; |
|
8 |
import org.springframework.http.ResponseEntity; |
|
6 | 9 |
import org.springframework.web.bind.annotation.*; |
10 |
import org.springframework.web.multipart.MultipartFile; |
|
7 | 11 |
|
8 | 12 |
import javax.xml.bind.JAXBException; |
9 | 13 |
import java.io.IOException; |
14 |
import java.util.List; |
|
10 | 15 |
|
11 | 16 |
@CrossOrigin(origins = "*", allowedHeaders = "*") |
12 | 17 |
@RestController |
... | ... | |
31 | 36 |
return new QueryResponse(response); |
32 | 37 |
} |
33 | 38 |
|
39 |
|
|
40 |
@PostMapping("/upload") |
|
41 |
public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") List<MultipartFile> files) { |
|
42 |
String message = ""; |
|
43 |
try { |
|
44 |
// TODO: Převést MultipartFile na normální file a pak ho dále zpracovat |
|
45 |
|
|
46 |
message = "Successfully uploaded " + files.size() + " files"; |
|
47 |
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message)); |
|
48 |
} catch (Exception e) { |
|
49 |
message = "Could not upload the files! " + e.toString(); |
|
50 |
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message)); |
|
51 |
} |
|
52 |
} |
|
53 |
|
|
34 | 54 |
@GetMapping("/add") |
35 | 55 |
public String add() { |
36 | 56 |
String response; |
be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/model/ResponseMessage.java | ||
---|---|---|
1 |
package cz.zcu.kiv.aswi.fulltextsearch.model; |
|
2 |
|
|
3 |
public class ResponseMessage { |
|
4 |
private String message; |
|
5 |
|
|
6 |
public ResponseMessage(String message) { |
|
7 |
this.message = message; |
|
8 |
} |
|
9 |
|
|
10 |
public String getMessage() { |
|
11 |
return message; |
|
12 |
} |
|
13 |
|
|
14 |
public void setMessage(String message) { |
|
15 |
this.message = message; |
|
16 |
} |
|
17 |
} |
fe/fulltextsearch/src/app/app.module.ts | ||
---|---|---|
17 | 17 |
import { HelpComponent } from './components/pages/help/help.component'; |
18 | 18 |
import { MatSelectModule } from '@angular/material/select'; |
19 | 19 |
import { SearchBoxComponent } from './components/shared-components/search-box/search-box.component'; |
20 |
import { MatProgressBarModule } from '@angular/material/progress-bar'; |
|
20 | 21 |
|
21 | 22 |
@NgModule({ |
22 | 23 |
declarations: [ |
... | ... | |
38 | 39 |
MatToolbarModule, |
39 | 40 |
MatButtonModule, |
40 | 41 |
MatIconModule, |
41 |
MatSelectModule |
|
42 |
MatSelectModule, |
|
43 |
MatProgressBarModule |
|
42 | 44 |
], |
43 | 45 |
providers: [], |
44 | 46 |
bootstrap: [AppComponent] |
fe/fulltextsearch/src/app/components/pages/upload/upload.component.css | ||
---|---|---|
1 |
h1 { |
|
2 |
font-size: xx-large; |
|
3 |
} |
|
4 |
|
|
5 |
.text-box { |
|
6 |
margin: auto; |
|
7 |
width: 80%; |
|
8 |
padding: 10px; |
|
9 |
} |
|
10 |
|
|
11 |
input { |
|
12 |
display: none; |
|
13 |
} |
|
14 |
|
|
15 |
button { |
|
16 |
font-weight: bold; |
|
17 |
font-size: large; |
|
18 |
background-color: var(--primary-color); |
|
19 |
color: var(--search-text-color); |
|
20 |
border-style: none; |
|
21 |
min-width: 80pt; |
|
22 |
margin: 10px; |
|
23 |
} |
|
24 |
|
|
25 |
button:hover { |
|
26 |
background-color: var(--primary-color-dark); |
|
27 |
} |
|
28 |
|
|
29 |
.center { |
|
30 |
margin: auto; |
|
31 |
width: 35%; |
|
32 |
} |
|
33 |
|
|
34 |
.center h2 { |
|
35 |
|
|
36 |
} |
fe/fulltextsearch/src/app/components/pages/upload/upload.component.html | ||
---|---|---|
1 |
<p>upload works!</p> |
|
1 |
<div class="text-box"> |
|
2 |
<div class="card"> |
|
3 |
<h1 class="card-header">Upload files</h1> |
|
4 |
<div class="card-body"> |
|
5 |
<div class="row justify-content-center align-items-center"> |
|
6 |
<input type="file" (change)="onFilesSelected($event)" multiple #fileInput> |
|
7 |
<button class="btn btn-outline-secondary" type="button" (click)="fileInput.click()">Pick files</button> |
|
8 |
<button class="btn btn-outline-secondary" type="button" (click)="onUpload()">Upload</button> |
|
9 |
</div> |
|
10 |
<mat-progress-bar mode="determinate" [value]="progress" color="warn"></mat-progress-bar> |
|
11 |
<div class="row justify-content-center align-items-center"> |
|
12 |
<h2>{{progress + '%'}}</h2> |
|
13 |
</div> |
|
14 |
<ul class="list-group"> |
|
15 |
<li class="list-group-item" *ngFor="let file of selectedFiles"> |
|
16 |
{{ file.name }} |
|
17 |
</li> |
|
18 |
</ul> |
|
19 |
<div class="row justify-content-center align-items-center"> |
|
20 |
<h2>{{resultMessage}}</h2> |
|
21 |
</div> |
|
22 |
</div> |
|
23 |
</div> |
|
24 |
</div> |
fe/fulltextsearch/src/app/components/pages/upload/upload.component.ts | ||
---|---|---|
1 | 1 |
import { Component, OnInit } from '@angular/core'; |
2 |
import {QueryService} from '../../../services/query.service'; |
|
3 |
import {HttpEventType} from '@angular/common/http'; |
|
2 | 4 |
|
3 | 5 |
@Component({ |
4 | 6 |
selector: 'app-upload', |
... | ... | |
6 | 8 |
styleUrls: ['./upload.component.css'] |
7 | 9 |
}) |
8 | 10 |
export class UploadComponent implements OnInit { |
11 |
selectedFiles: File[] = null; |
|
12 |
resultMessage: string = null; |
|
13 |
progress = 0; |
|
9 | 14 |
|
10 |
constructor() { } |
|
15 |
constructor( private queryService: QueryService ) { }
|
|
11 | 16 |
|
12 | 17 |
ngOnInit(): void { |
13 | 18 |
} |
14 | 19 |
|
20 |
onFilesSelected(event) { |
|
21 |
this.selectedFiles = event.target.files; |
|
22 |
this.progress = 0; |
|
23 |
this.resultMessage = null; |
|
24 |
} |
|
25 |
|
|
26 |
onUpload() { |
|
27 |
console.log(this.selectedFiles); |
|
28 |
if (this.selectedFiles === null) { |
|
29 |
this.resultMessage = 'Select files first'; |
|
30 |
return; |
|
31 |
} |
|
32 |
this.queryService.uploadFile(this.selectedFiles).subscribe( event => { |
|
33 |
if (event.type === HttpEventType.UploadProgress) { |
|
34 |
this.progress = Math.round(event.loaded / event.total * 100); |
|
35 |
} else if (event.type === HttpEventType.Response ) { |
|
36 |
this.resultMessage = 'Successfully uploaded ' + this.selectedFiles.length + ' files'; |
|
37 |
this.selectedFiles = null; |
|
38 |
} |
|
39 |
}); |
|
40 |
} |
|
15 | 41 |
} |
fe/fulltextsearch/src/app/components/shared-components/search-box/search-box.component.css | ||
---|---|---|
27 | 27 |
input:focus { |
28 | 28 |
box-shadow: none; |
29 | 29 |
} |
30 |
|
|
31 |
.clickable { |
|
32 |
cursor: pointer; |
|
33 |
} |
fe/fulltextsearch/src/app/components/shared-components/search-box/search-box.component.html | ||
---|---|---|
7 | 7 |
</div> |
8 | 8 |
<input type="text" class="form-control" [(ngModel)]="expression" placeholder="Enter text to search..." aria-label="Search" aria-describedby="basic-addon2"> |
9 | 9 |
<div class="input-group-append"> |
10 |
<span class="input-group-text"> |
|
10 |
<span class="input-group-text clickable">
|
|
11 | 11 |
<mat-icon *ngIf="expression" matSuffix aria-label="Clear" (click)="expression=''">clear</mat-icon> |
12 | 12 |
</span> |
13 | 13 |
<button class="btn btn-outline-secondary" type="button" (click)="onSubmit()">Search</button> |
fe/fulltextsearch/src/app/model/DocumentRequest.ts | ||
---|---|---|
1 |
export class DocumentRequest { |
|
2 |
public xmlFile: string; |
|
3 |
public imgFile: string; |
|
4 |
} |
fe/fulltextsearch/src/app/services/query.service.ts | ||
---|---|---|
1 |
import { Injectable } from '@angular/core';
|
|
2 |
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
3 |
import { Observable } from 'rxjs';
|
|
4 |
import { QueryResponse } from '../model/QueryResponse';
|
|
5 |
import { Query } from '../model/Query';
|
|
1 |
import {Injectable} from '@angular/core';
|
|
2 |
import {HttpClient, HttpEventType, HttpHeaders} from '@angular/common/http';
|
|
3 |
import {Observable} from 'rxjs';
|
|
4 |
import {QueryResponse} from '../model/QueryResponse';
|
|
5 |
import {Query} from '../model/Query';
|
|
6 | 6 |
|
7 | 7 |
const httpOptions = { |
8 | 8 |
headers: new HttpHeaders( { |
... | ... | |
15 | 15 |
}) |
16 | 16 |
export class QueryService { |
17 | 17 |
|
18 |
backendUrl: string = 'http://localhost:8080/'; |
|
18 |
backendUrl = 'http://localhost:8080/'; |
|
19 |
uploadFileUrl = 'upload'; |
|
19 | 20 |
|
20 | 21 |
constructor(private httpClient: HttpClient) {} |
21 | 22 |
|
22 | 23 |
sendQuery(query: Query): Observable<QueryResponse> { |
23 | 24 |
return this.httpClient.post<QueryResponse>(this.backendUrl, query, httpOptions); |
24 | 25 |
} |
26 |
|
|
27 |
|
|
28 |
uploadFile(files: File[]): Observable<any> { |
|
29 |
const formDate = new FormData(); |
|
30 |
for (const file of files) { |
|
31 |
formDate.append('file', file); |
|
32 |
} |
|
33 |
return this.httpClient.post(this.backendUrl + this.uploadFileUrl, formDate, { |
|
34 |
reportProgress: true, |
|
35 |
observe: 'events' |
|
36 |
}); |
|
37 |
} |
|
25 | 38 |
} |
Také k dispozici: Unified diff
Re #7726: Implementace architektury FE
- implementace stránky pro nahrávání obrázků
- přidána metoda do BE pro přijímání obrázku