我正在 JHipster 上制作一个网络应用程序,该网络应用程序是一个房间预订网络应用程序,允许用户预订房间。我面临的问题是关于我正在实施的签入功能。我创建了一个包含必要实体的 jdl(见下文)。
entity Booking {
Title String required
StartTime ZonedDateTime required
EndTime ZonedDateTime required
AttendeesNum Integer required
GoogleId String
CheckedIn Boolean required
}
entity Room {
Location String required
Name String required
FloorNum Integer required
Capacity Integer required
HasScreen Boolean required
HasWhiteBoard Boolean required
CanVideoCall Boolean required
CanAudioCall Boolean required
Status RoomStatus required
}
问题出在后端java代码和我无法使其与我的前端通信。我将在下面附上代码,但我也会解释我的确切含义。我在 jhipster 模板中创建/编辑了 2 个 java 文件,其中一个是我创建的文件,名为:
BookingService.java 这是一个服务类,负责处理与预订相关的业务逻辑。目前,它只有一个方法 checkIn,用于登记预订。登记入住时,它会将预订的 checkedIn 属性设置为 true,并将房间状态更新为 IN_USE。
package aryan.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import aryan.domain.Booking;
import aryan.domain.Room;
import aryan.domain.enumeration.RoomStatus;
import aryan.repository.BookingRepository;
import aryan.repository.RoomRepository;
import aryant.web.rest.errors.ResourceNotFoundException;
@Service
@Transactional
public class BookingService {
private final BookingRepository bookingRepository;
private final RoomRepository roomRepository;
public BookingService(BookingRepository bookingRepository, RoomRepository roomRepository) {
this.bookingRepository = bookingRepository;
this.roomRepository = roomRepository;
}
public Booking checkIn(Long bookingId) {
Booking booking = bookingRepository.findById(bookingId).orElseThrow(() -> new ResourceNotFoundException("Booking not found"));
booking.setCheckedIn(true);
Room room = booking.getRoom();
room.setStatus(RoomStatus.IN_USE);
roomRepository.save(room);
return bookingRepository.save(booking);
}
}
另一个是默认配置中已有的文件,名为 BookingResource.java,它是一个 REST 控制器,用于管理 Web 应用程序中的预订。此类有多种方法来处理不同的 REST API 端点,例如创建新预订、更新现有预订、部分更新预订、获取所有预订或特定预订、删除预订以及登记预订。它还包括一个辅助方法 buildLocation,用于根据预订创建位置字符串。关于分享这段代码,我只会分享相关的部分和它的一大段代码
@RestController
@RequestMapping("/api")
@Transactional
public class BookingResource {
private final UserService userService;
private final BookingService bookingService;
private final Logger log = LoggerFactory.getLogger(BookingResource.class);
private static final String ENTITY_NAME = "booking";
@Value("${jhipster.clientApp.name}")
private String applicationName;
private final BookingRepository bookingRepository;
@Autowired
public BookingResource(BookingRepository bookingRepository, UserService userService, BookingService bookingService) {
this.bookingRepository = bookingRepository;
this.userService = userService;
this.bookingService = bookingService;
}
@PostMapping("/bookings/{id}/check-in")
public ResponseEntity<Booking> checkIn(@PathVariable Long id) {
Booking result = bookingService.checkIn(id);
return ResponseEntity.ok().body(result);
}
现在前端代码对我自己来说更容易理解了,我在 html 中实现了我必须创建一个按钮并在单击时将其链接到一个方法(onClick),该方法将在打字稿中并被调用,该方法是我苦苦挣扎的问题,这就是我将后端和前端连接在一起的意思。我该怎么做才能在单击签入按钮时与后端通信并更新数据库。我还将提供 html 和 ts 文件的相关部分。注意:签入按钮将处于模态状态。
HTML:
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title">Booking Details</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- Add the booking details content from booking-detail.component.html here -->
<div class="d-flex justify-content-center">
<div class="col-8">
<div *ngIf="booking">
<h2 data-cy="bookingDetailsHeading"><span jhiTranslate="aryan.booking.detail.title">Booking</span></h2>
<hr />
<jhi-alert-error></jhi-alert-error>
<jhi-alert></jhi-alert>
<dl class="row-md jh-entity-details">
<dt><span jhiTranslate="global.field.id">ID</span></dt>
<dd>
<span>{{ booking.id }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.title">Title</span></dt>
<dd>
<span>{{ booking.title }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.startTime">Start Time</span></dt>
<dd>
<span>{{ booking.startTime | formatMediumDatetime }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.endTime">End Time</span></dt>
<dd>
<span>{{ booking.endTime | formatMediumDatetime }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.attendeesNum">Attendees Num</span></dt>
<dd>
<span>{{ booking.attendeesNum }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.googleId">Google ID</span></dt>
<dd>
<span>{{ booking.googleId }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.checkedIn">Checked In</span></dt>
<dd>
<span>{{ booking.checkedIn }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.room">Room</span></dt>
<dd>
<div *ngIf="booking.room">
<a [routerLink]="['/room', booking.room.id, 'view']">{{ booking.room.id }}</a>
</div>
</dd>
<dt><span jhiTranslate="aryan.booking.user">User</span></dt>
<dd>
<span>{{ booking.user?.id }}</span>
</dd>
<dt><span jhiTranslate="aryan.booking.attendee">Attendee</span></dt>
<dd>
<span *ngFor="let attendee of booking.attendees; let last = last"> {{ attendee.login }}{{ last ? '' : ', ' }} </span>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" (click)=someMethod">Check In </button>
<button type="button" class="btn btn-secondary" (click)="modal.close('Close click')">Close</button>
</div>
</ng-template>
TS:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Data, ParamMap, Router } from '@angular/router';
import { combineLatest, filter, Observable, switchMap, tap } from 'rxjs';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { IBooking } from '../booking.model';
import { ASC, DESC, SORT, ITEM_DELETED_EVENT, DEFAULT_SORT_DATA } from 'app/config/navigation.constants';
import { EntityArrayResponseType, BookingService } from '../service/booking.service';
import { BookingDeleteDialogComponent } from '../delete/booking-delete-dialog.component';
import { SortService } from 'app/shared/sort/sort.service';
@Component({
selector: 'jhi-booking',
templateUrl: './booking.component.html',
})
export class BookingComponent implements OnInit {
bookings?: IBooking[];
isLoading = false;
predicate = 'id';
ascending = true;
constructor(
protected bookingService: BookingService,
protected activatedRoute: ActivatedRoute,
public router: Router,
protected sortService: SortService,
protected modalService: NgbModal
) {}
trackId = (_index: number, item: IBooking): number => this.bookingService.getBookingIdentifier(item);
booking: IBooking | null = null;
ngOnInit(): void {
this.load();
}
delete(booking: IBooking): void {
const modalRef = this.modalService.open(BookingDeleteDialogComponent, { size: 'lg', backdrop: 'static' });
modalRef.componentInstance.booking = booking;
// unsubscribe not needed because closed completes on modal close
modalRef.closed
.pipe(
filter(reason => reason === ITEM_DELETED_EVENT),
switchMap(() => this.loadFromBackendWithRouteInformations())
)
.subscribe({
next: (res: EntityArrayResponseType) => {
this.onResponseSuccess(res);
},
});
}
load(): void {
this.loadFromBackendWithRouteInformations().subscribe({
next: (res: EntityArrayResponseType) => {
this.onResponseSuccess(res);
},
});
}
navigateToWithComponentValues(): void {
this.handleNavigation(this.predicate, this.ascending);
}
protected loadFromBackendWithRouteInformations(): Observable<EntityArrayResponseType> {
return combineLatest([this.activatedRoute.queryParamMap, this.activatedRoute.data]).pipe(
tap(([params, data]) => this.fillComponentAttributeFromRoute(params, data)),
switchMap(() => this.queryBackend(this.predicate, this.ascending))
);
}
protected fillComponentAttributeFromRoute(params: ParamMap, data: Data): void {
const sort = (params.get(SORT) ?? data[DEFAULT_SORT_DATA]).split(',');
this.predicate = sort[0];
this.ascending = sort[1] === ASC;
}
protected onResponseSuccess(response: EntityArrayResponseType): void {
const dataFromBody = this.fillComponentAttributesFromResponseBody(response.body);
this.bookings = this.refineData(dataFromBody);
}
protected refineData(data: IBooking[]): IBooking[] {
return data.sort(this.sortService.startSort(this.predicate, this.ascending ? 1 : -1));
}
protected fillComponentAttributesFromResponseBody(data: IBooking[] | null): IBooking[] {
return data ?? [];
}
protected queryBackend(predicate?: string, ascending?: boolean): Observable<EntityArrayResponseType> {
this.isLoading = true;
const queryObject = {
eagerload: true,
sort: this.getSortQueryParam(predicate, ascending),
};
return this.bookingService.query(queryObject).pipe(tap(() => (this.isLoading = false)));
}
protected handleNavigation(predicate?: string, ascending?: boolean): void {
const queryParamsObj = {
sort: this.getSortQueryParam(predicate, ascending),
};
this.router.navigate(['./'], {
relativeTo: this.activatedRoute,
queryParams: queryParamsObj,
});
}
protected getSortQueryParam(predicate = this.predicate, ascending = this.ascending): string[] {
const ascendingQueryParam = ascending ? ASC : DESC;
if (predicate === '') {
return [];
} else {
return [predicate + ',' + ascendingQueryParam];
}
}
open(content: any, booking: IBooking): void {
this.booking = booking;
this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title' }).result.then(
result => {
// Handle the result here
},
reason => {
// Handle the reason for dismissal here
}
);
}
previousState(): void {
window.history.back();
}
}
我已经尝试创建我的多个方法,其中涉及调用 BookingService.java 中的方法,但我仍然遇到错误。这是我的第一个项目,所以我对这一切还很陌生。我期望发生的事情是当我运行 ./mvnw 时,代码将编译它所做的并转到签入按钮并单击该按钮,签入字段将从假变为真。实际发生的是代码构建成功,但是当我点击签入时,我会在 intelliJ 终端中收到一堆错误,说它失败了