Zadania 1, 2, 9
This commit is contained in:
@@ -78,10 +78,17 @@ public class SchemaFixer {
|
||||
"ALTER TABLE IF EXISTS user_reports ADD COLUMN IF NOT EXISTS reported_user_deleted BOOLEAN NOT NULL DEFAULT FALSE"
|
||||
);
|
||||
|
||||
// Blokowanie konta ze zgloszenia zostalo usuniete - encja nie mapuje juz tej kolumny,
|
||||
// wiec stare wiersze zostaja, a nowe wpisy wypelnia wartosc domyslna.
|
||||
// Blokowanie konta ze zgloszenia zostalo usuniete - encja nie mapuje juz tej kolumny.
|
||||
// W starych bazach kolumna zostaje, wiec nadajemy jej wartosc domyslna; w nowych jej nie ma,
|
||||
// a ALTER COLUMN nie przyjmuje IF EXISTS - stad sprawdzenie w bloku DO.
|
||||
jdbcTemplate.execute(
|
||||
"ALTER TABLE IF EXISTS user_reports ALTER COLUMN reported_user_blocked SET DEFAULT FALSE"
|
||||
"DO $$ "
|
||||
+ "BEGIN "
|
||||
+ " IF EXISTS (SELECT 1 FROM information_schema.columns "
|
||||
+ " WHERE table_name = 'user_reports' AND column_name = 'reported_user_blocked') THEN "
|
||||
+ " ALTER TABLE user_reports ALTER COLUMN reported_user_blocked SET DEFAULT FALSE; "
|
||||
+ " END IF; "
|
||||
+ "END $$"
|
||||
);
|
||||
|
||||
// Widocznosc profilu ma juz tylko dwie wartosci - wariant "tylko kontakty" zostal usuniety.
|
||||
|
||||
@@ -43,6 +43,8 @@ public record ListingCreateRequest(
|
||||
List<String> media,
|
||||
List<String> amenities,
|
||||
List<String> photos,
|
||||
String virtualTourUrl
|
||||
String virtualTourUrl,
|
||||
// true = publikujemy tylko przyblizona lokalizacje (mapa rysuje obszar zamiast punktu)
|
||||
Boolean approximateLocation
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -54,9 +54,30 @@ public record ListingDetailResponse(
|
||||
ListingStatus status,
|
||||
Instant createdAt,
|
||||
Long viewsCount,
|
||||
Instant promotedUntil
|
||||
Instant promotedUntil,
|
||||
// true = wlasciciel nie publikuje dokladnego adresu; mapa rysuje obszar zamiast punktu
|
||||
boolean approximateLocation
|
||||
) {
|
||||
// Promien obszaru, w ktorym mieszcza sie przesuniete wspolrzedne - mapa rysuje kolo tej wielkosci.
|
||||
private static final double APPROXIMATE_RADIUS_M = 300d;
|
||||
private static final double METERS_PER_DEGREE = 111_320d;
|
||||
|
||||
public static ListingDetailResponse from(PropertyListing listing, Long ownerId, String ownerAvatar) {
|
||||
return from(listing, ownerId, ownerAvatar, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gdy {@code masked} jest true (ogloszenie z ukryta lokalizacja ogladane przez kogos innego niz
|
||||
* wlasciciel i administracja), z odpowiedzi znikaja ulica oraz numer budynku, a wspolrzedne sa
|
||||
* przesuwane w obrebie obszaru. Przesuniecie liczymy z identyfikatora ogloszenia, wiec dla danej
|
||||
* oferty jest zawsze takie samo - inaczej kolo skakaloby po mapie przy kazdym odswiezeniu.
|
||||
*/
|
||||
public static ListingDetailResponse from(PropertyListing listing, Long ownerId, String ownerAvatar, boolean masked) {
|
||||
String street = masked ? null : listing.getStreet();
|
||||
String building = masked ? null : listing.getBuilding();
|
||||
String address = masked ? approximateAddress(listing) : listing.getAddress();
|
||||
Double lat = masked ? blurLat(listing) : listing.getLat();
|
||||
Double lng = masked ? blurLng(listing) : listing.getLng();
|
||||
return new ListingDetailResponse(
|
||||
listing.getId(),
|
||||
listing.getTitle(),
|
||||
@@ -65,9 +86,9 @@ public record ListingDetailResponse(
|
||||
listing.getPropertyType(),
|
||||
listing.getCity(),
|
||||
listing.getDistrict(),
|
||||
listing.getStreet(),
|
||||
listing.getBuilding(),
|
||||
listing.getAddress(),
|
||||
street,
|
||||
building,
|
||||
address,
|
||||
listing.getPrice(),
|
||||
listing.getArea(),
|
||||
listing.getRooms(),
|
||||
@@ -88,8 +109,8 @@ public record ListingDetailResponse(
|
||||
listing.getWindows(),
|
||||
listing.getExposure(),
|
||||
listing.getRoomHeight(),
|
||||
listing.getLat(),
|
||||
listing.getLng(),
|
||||
lat,
|
||||
lng,
|
||||
List.copyOf(listing.getMedia()),
|
||||
List.copyOf(listing.getAmenities()),
|
||||
List.copyOf(listing.getPhotos()),
|
||||
@@ -100,7 +121,42 @@ public record ListingDetailResponse(
|
||||
listing.getStatus(),
|
||||
listing.getCreatedAt(),
|
||||
listing.getViewsCount(),
|
||||
listing.getPromotedUntil()
|
||||
listing.getPromotedUntil(),
|
||||
listing.isApproximateLocation()
|
||||
);
|
||||
}
|
||||
|
||||
// Bez ulicy i numeru zostaje sama okolica - dzielnica i miasto.
|
||||
private static String approximateAddress(PropertyListing listing) {
|
||||
String district = listing.getDistrict();
|
||||
return district == null || district.isBlank() ? listing.getCity() : district + ", " + listing.getCity();
|
||||
}
|
||||
|
||||
private static Double blurLat(PropertyListing listing) {
|
||||
if (listing.getLat() == null) {
|
||||
return null;
|
||||
}
|
||||
return listing.getLat() + (offsetMeters(listing) * Math.cos(offsetAngle(listing))) / METERS_PER_DEGREE;
|
||||
}
|
||||
|
||||
private static Double blurLng(PropertyListing listing) {
|
||||
if (listing.getLng() == null || listing.getLat() == null) {
|
||||
return null;
|
||||
}
|
||||
double parallel = METERS_PER_DEGREE * Math.cos(Math.toRadians(listing.getLat()));
|
||||
if (parallel == 0) {
|
||||
return listing.getLng();
|
||||
}
|
||||
return listing.getLng() + (offsetMeters(listing) * Math.sin(offsetAngle(listing))) / parallel;
|
||||
}
|
||||
|
||||
// Kierunek i dlugosc przesuniecia sa stale dla ogloszenia, a punkt zostaje w polowie promienia,
|
||||
// wiec rzeczywisty adres zawsze miesci sie wewnatrz rysowanego kola.
|
||||
private static double offsetAngle(PropertyListing listing) {
|
||||
return Math.toRadians((listing.getId() * 137L) % 360);
|
||||
}
|
||||
|
||||
private static double offsetMeters(PropertyListing listing) {
|
||||
return (listing.getId() * 53L) % (long) (APPROXIMATE_RADIUS_M / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,18 @@ public record ListingResponse(
|
||||
Instant createdAt
|
||||
) {
|
||||
public static ListingResponse from(PropertyListing listing) {
|
||||
return from(listing, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param masked pokaz sama okolice zamiast adresu - dla ogloszen z ukryta dokladna lokalizacja
|
||||
* ogladanych spoza panelu wlasciciela i administracji.
|
||||
*/
|
||||
public static ListingResponse from(PropertyListing listing, boolean masked) {
|
||||
String district = listing.getDistrict();
|
||||
String address = masked
|
||||
? (district == null || district.isBlank() ? listing.getCity() : district + ", " + listing.getCity())
|
||||
: listing.getAddress();
|
||||
return new ListingResponse(
|
||||
listing.getId(),
|
||||
listing.getTitle(),
|
||||
@@ -38,8 +50,8 @@ public record ListingResponse(
|
||||
listing.getOfferType(),
|
||||
listing.getPropertyType(),
|
||||
listing.getCity(),
|
||||
listing.getDistrict(),
|
||||
listing.getAddress(),
|
||||
district,
|
||||
address,
|
||||
listing.getPrice(),
|
||||
listing.getArea(),
|
||||
listing.getRooms(),
|
||||
|
||||
@@ -51,11 +51,19 @@ public class ListingService {
|
||||
* Ogloszenia demonstracyjne nie maja konta w serwisie - wtedy oba pola sa puste.
|
||||
*/
|
||||
private ListingDetailResponse detailOf(PropertyListing listing) {
|
||||
return detailOf(listing, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param masked ukryj dokladny adres (ulica, numer, wspolrzedne) - dla ogloszen, ktorych
|
||||
* wlasciciel wybral publikowanie samej przyblizonej lokalizacji.
|
||||
*/
|
||||
private ListingDetailResponse detailOf(PropertyListing listing, boolean masked) {
|
||||
AppUser owner = ownerOf(listing);
|
||||
if (owner == null) {
|
||||
return ListingDetailResponse.from(listing, null, null);
|
||||
return ListingDetailResponse.from(listing, null, null, masked);
|
||||
}
|
||||
return ListingDetailResponse.from(listing, owner.getId(), userSettingsService.avatarFor(owner.getId()));
|
||||
return ListingDetailResponse.from(listing, owner.getId(), userSettingsService.avatarFor(owner.getId()), masked);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +93,7 @@ public class ListingService {
|
||||
.filter(listing -> offerType == null || listing.getOfferType() == offerType)
|
||||
.filter(listing -> propertyType == null || listing.getPropertyType() == propertyType)
|
||||
.sorted(promotedFirst())
|
||||
.map(ListingResponse::from)
|
||||
.map(listing -> ListingResponse.from(listing, listing.isApproximateLocation()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -110,7 +118,8 @@ public class ListingService {
|
||||
listing = listingRepository.save(listing);
|
||||
}
|
||||
|
||||
return detailOf(listing);
|
||||
// Wlasciciel i administracja widza pelny adres - reszta tylko przyblizona lokalizacje.
|
||||
return detailOf(listing, listing.isApproximateLocation() && !isOwner && !viewerIsAdmin);
|
||||
}
|
||||
|
||||
public List<ListingResponse> findMine(String ownerEmail) {
|
||||
@@ -222,6 +231,7 @@ public class ListingService {
|
||||
listing.setRoomHeight(trimToNull(request.roomHeight()));
|
||||
listing.setLat(request.lat());
|
||||
listing.setLng(request.lng());
|
||||
listing.setApproximateLocation(Boolean.TRUE.equals(request.approximateLocation()));
|
||||
|
||||
listing.setMedia(cleanList(request.media()));
|
||||
listing.setAmenities(cleanList(request.amenities()));
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
|
||||
@Entity
|
||||
@Table(name = "property_listings")
|
||||
@@ -121,6 +122,12 @@ public class PropertyListing {
|
||||
|
||||
private Double lng;
|
||||
|
||||
// Wlasciciel nie chce publikowac dokladnego adresu - mapa pokazuje wtedy przyblizony obszar,
|
||||
// a odpowiedzi publiczne nie zawieraja ulicy ani numeru budynku.
|
||||
@Column(nullable = false)
|
||||
@ColumnDefault("false")
|
||||
private boolean approximateLocation = false;
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "listing_media", joinColumns = @JoinColumn(name = "listing_id"))
|
||||
@Column(name = "value", length = 60)
|
||||
@@ -420,6 +427,14 @@ public class PropertyListing {
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
public boolean isApproximateLocation() {
|
||||
return approximateLocation;
|
||||
}
|
||||
|
||||
public void setApproximateLocation(boolean approximateLocation) {
|
||||
this.approximateLocation = approximateLocation;
|
||||
}
|
||||
|
||||
public List<String> getMedia() {
|
||||
return media;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user