Compare commits

..

No commits in common. "f67c6d76befdefde32f59c813f45c50fb09b4e1b" and "02b3e891a683f9213a04074971647657b532b5c5" have entirely different histories.

17 changed files with 99 additions and 160 deletions

View File

@ -1,7 +1,6 @@
package ru.ulstu.`is`.airticketrentservice package ru.ulstu.`is`.airticketrentservice
import android.app.Application import android.app.Application
import ru.ulstu.`is`.airticketrentservice.api.AppService
import ru.ulstu.`is`.airticketrentservice.database.AppContainer import ru.ulstu.`is`.airticketrentservice.database.AppContainer
import ru.ulstu.`is`.airticketrentservice.database.AppDataContainer import ru.ulstu.`is`.airticketrentservice.database.AppDataContainer

View File

@ -28,19 +28,14 @@ interface AppService {
@Query("_page") page: Int, @Query("_page") page: Int,
@Query("_limit") limit: Int, @Query("_limit") limit: Int,
): List<RentRemote> ): List<RentRemote>
@GET("searchFlights") @GET("findFlights/{direction_from}-{direction_to}-{departure_date}")
suspend fun foundFlights( suspend fun findFlights(
@Path("direction_from") from: String,
@Path("direction_to") to: String,
@Path("departure_date") departureDate: String
): List<FlightRemote> ): List<FlightRemote>
// suspend fun findFlights(
// @Path("direction_from") from: String,
// @Path("direction_to") to: String,
// @Path("departure_date") departureDate: String
// ): List<FlightRemote>
@GET("tickets") @GET("tickets")
suspend fun getAllTickets(): List<TicketRemote> suspend fun getAllTickets(): List<TicketRemote>
@GET("foundFlights")
suspend fun getAllFlights(): List<FlightRemote>
@GET("tickets") @GET("tickets")
suspend fun getTickets( suspend fun getTickets(
@Query("_page") page: Int, @Query("_page") page: Int,
@ -131,7 +126,7 @@ interface AppService {
@Path("id") id: Int, @Path("id") id: Int,
): TicketRemote ): TicketRemote
companion object : AppService { companion object {
private const val BASE_URL = "http://192.168.1.100:8079/" private const val BASE_URL = "http://192.168.1.100:8079/"
@Volatile @Volatile

View File

@ -1,9 +1,7 @@
package ru.ulstu.`is`.airticketrentservice.api.model package ru.ulstu.`is`.airticketrentservice.api.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import ru.ulstu.`is`.airticketrentservice.database.models.Flight import ru.ulstu.`is`.airticketrentservice.database.models.Flight
import java.io.File
@Serializable @Serializable
data class FlightRemote( data class FlightRemote(
@ -35,21 +33,3 @@ fun Flight.toFlightRemote(): FlightRemote = FlightRemote(
tickets_count, tickets_count,
one_ticket_cost one_ticket_cost
) )
fun foundFlights(
from: String,
to: String,
departureDate: String
): List<Flight> {
val json = File("C:\\Users\\User\\AndroidStudioProjects\\AirTicketRentService\\server").readText()
val flights = Json.decodeFromString<List<Flight>>(json)
val matchingFlights = flights.filter { flight ->
flight.direction_from == from ||
flight.direction_to == to ||
flight.departure_date == departureDate
}
return matchingFlights
}

View File

@ -14,7 +14,6 @@ import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import kotlinx.serialization.json.Json
import ru.ulstu.`is`.airticketrentservice.api.AppService import ru.ulstu.`is`.airticketrentservice.api.AppService
import ru.ulstu.`is`.airticketrentservice.api.model.toFlight import ru.ulstu.`is`.airticketrentservice.api.model.toFlight
import ru.ulstu.`is`.airticketrentservice.api.model.toFlightRemote import ru.ulstu.`is`.airticketrentservice.api.model.toFlightRemote
@ -26,7 +25,6 @@ import ru.ulstu.`is`.airticketrentservice.database.repository.FlightRepository
import ru.ulstu.`is`.airticketrentservice.database.repository.OfflineRemoteKeyRepository import ru.ulstu.`is`.airticketrentservice.database.repository.OfflineRemoteKeyRepository
import ru.ulstu.`is`.airticketrentservice.api.mediator.FlightRemoteMediator import ru.ulstu.`is`.airticketrentservice.api.mediator.FlightRemoteMediator
import ru.ulstu.`is`.airticketrentservice.api.model.FlightRemote import ru.ulstu.`is`.airticketrentservice.api.model.FlightRemote
import java.io.File
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
@ -61,45 +59,50 @@ class RestFlightRepository(
override suspend fun getFlightById(flightId: Int): Flight = override suspend fun getFlightById(flightId: Int): Flight =
service.getFlight(flightId).toFlight() service.getFlight(flightId).toFlight()
override suspend fun foundFlights(
from: String,
to: String,
departureDate: String
): List<Flight> {
val existFlights = dbFlightRepository.getAllFlights().associateBy { it.id }.toMutableMap()
service.foundFlights()
.map { it.toFlight() }
.forEach { flight ->
flight.direction_from == from ||
flight.direction_to == to ||
flight.departure_date == departureDate
existFlights[flight.id] = flight
}
return existFlights.map { it.value }.sortedBy { it.id }
}
// override suspend fun findFlights( // override suspend fun findFlights(
// from: String, // from: String,
// to: String, // to: String,
// departureDate: String // departureDate: String
// ): List<Flight> { // ): List<Flight> = suspendCancellableCoroutine { continuation ->
// Log.d(RestFlightRepository::class.simpleName, "Find flights") // val call = service.findFlights(from, to, departureDate)
// // call.enqueue(object: Callback<List<FlightRemote>> {
// // override fun onResponse(call: Call<List<FlightRemote>>, response: Response<List<FlightRemote>>) {
// val existFlights = dbFlightRepository.findFlights(from, to, departureDate).associateBy { it.id }.toMutableMap() // if (response.isSuccessful) {
// // val flightRemoteList = response.body() ?: emptyList()
// service.findFlights(from, to, departureDate) // val flightList = flightRemoteList.map { it.toFlight() }
// .map { it.toFlight() } // continuation.resume(flightList)
// .forEach { flight -> // } else {
// existFlights[flight.id] = flight // continuation.resumeWithException(Exception("Server error: ${response.code()}"))
// }
// } // }
// //
// return existFlights.map { it.value }.sortedBy { it.id } // override fun onFailure(call: Call<List<FlightRemote>>, t: Throwable) {
// continuation.resumeWithException(t)
// } // }
// })
//
// continuation.invokeOnCancellation {
// call.cancel()
// }
// }
override suspend fun findFlights(
from: String,
to: String,
departureDate: String
): List<Flight> {
Log.d(RestFlightRepository::class.simpleName, "Find flights")
val existFlights = dbFlightRepository.findFlights(from, to, departureDate).associateBy { it.id }.toMutableMap()
service.findFlights(from, to, departureDate)
.map { it.toFlight() }
.forEach { flight ->
existFlights[flight.id] = flight
}
return existFlights.map { it.value }.sortedBy { it.id }
}
override suspend fun insertFlight(flight: Flight) { override suspend fun insertFlight(flight: Flight) {
service.createFlight(flight.toFlightRemote()).toFlight() service.createFlight(flight.toFlightRemote()).toFlight()

View File

@ -9,6 +9,6 @@ interface FlightRepository {
suspend fun updateFlight(flight: Flight) suspend fun updateFlight(flight: Flight)
suspend fun deleteFlight(flight: Flight) suspend fun deleteFlight(flight: Flight)
suspend fun getFlightById(flightId: Int): Flight suspend fun getFlightById(flightId: Int): Flight
suspend fun foundFlights(from: String, to: String, departureDate: String): List<Flight> suspend fun findFlights(from: String, to: String, departureDate: String): List<Flight>
fun getFlights(): Flow<PagingData<Flight>> fun getFlights(): Flow<PagingData<Flight>>
} }

View File

@ -11,7 +11,6 @@ import ru.ulstu.`is`.airticketrentservice.database.models.Flight
import ru.ulstu.`is`.airticketrentservice.database.models.Rent import ru.ulstu.`is`.airticketrentservice.database.models.Rent
class OfflineFlightRepository(private val flightDao: FlightDao) : FlightRepository{ class OfflineFlightRepository(private val flightDao: FlightDao) : FlightRepository{
suspend fun getAllFlights(): List<Flight> = flightDao.getAll()
override suspend fun insertFlight(flight: Flight) = flightDao.insert(flight) override suspend fun insertFlight(flight: Flight) = flightDao.insert(flight)
override suspend fun updateFlight(flight: Flight) = flightDao.update(flight) override suspend fun updateFlight(flight: Flight) = flightDao.update(flight)
override suspend fun deleteFlight(flight: Flight) = flightDao.delete(flight) override suspend fun deleteFlight(flight: Flight) = flightDao.delete(flight)
@ -25,7 +24,7 @@ class OfflineFlightRepository(private val flightDao: FlightDao) : FlightReposito
).flow ).flow
fun getAllFlightsPagingSource(): PagingSource<Int, Flight> = flightDao.getFlights() fun getAllFlightsPagingSource(): PagingSource<Int, Flight> = flightDao.getFlights()
override suspend fun foundFlights(from: String, to: String, departureDate: String): List<Flight> = flightDao.findFlights(from, to, departureDate) override suspend fun findFlights(from: String, to: String, departureDate: String): List<Flight> = flightDao.findFlights(from, to, departureDate)
suspend fun clearFlights() = flightDao.deleteAll() suspend fun clearFlights() = flightDao.deleteAll()
suspend fun insertFlights(flights: List<Flight>) = suspend fun insertFlights(flights: List<Flight>) =
flightDao.insert(*flights.toTypedArray()) flightDao.insert(*flights.toTypedArray())

View File

@ -45,23 +45,6 @@ fun Admin (
) { ) {
Text("Рейсы") Text("Рейсы")
} }
Button(
onClick = { navController.navigate(BottomBarScreen.UserList.route)},
colors = ButtonDefaults.buttonColors(
containerColor = (colorResource(id = R.color.lightBlue)),
contentColor = Color.White
),
elevation = ButtonDefaults.buttonElevation(
defaultElevation = 10.dp,
pressedElevation = 6.dp
),
shape = RoundedCornerShape(15.dp),
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
) {
Text("Пользователи")
}
Button( Button(
onClick = { navController.navigate(BottomBarScreen.RentList.route)}, onClick = { navController.navigate(BottomBarScreen.RentList.route)},
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
@ -79,5 +62,22 @@ fun Admin (
) { ) {
Text("Бронирования") Text("Бронирования")
} }
Button(
onClick = { navController.navigate(BottomBarScreen.UserList.route)},
colors = ButtonDefaults.buttonColors(
containerColor = (colorResource(id = R.color.lightBlue)),
contentColor = Color.White
),
elevation = ButtonDefaults.buttonElevation(
defaultElevation = 10.dp,
pressedElevation = 6.dp
),
shape = RoundedCornerShape(15.dp),
modifier = Modifier
.fillMaxWidth()
.padding(all = 10.dp),
) {
Text("Пользователи")
}
} }
} }

View File

@ -40,13 +40,14 @@ import ru.ulstu.`is`.airticketrentservice.database.models.Flight
import ru.ulstu.`is`.airticketrentservice.navigation.BottomBarScreen import ru.ulstu.`is`.airticketrentservice.navigation.BottomBarScreen
import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider import ru.ulstu.`is`.airticketrentservice.viewModel.AppViewModelProvider
import ru.ulstu.`is`.airticketrentservice.viewModel.FindFlightsViewModel import ru.ulstu.`is`.airticketrentservice.viewModel.FindFlightsViewModel
import ru.ulstu.`is`.airticketrentservice.viewModel.FoundFlightsUiState
@Composable @Composable
fun FoundFlights( fun FoundFlights(
navController: NavController, navController: NavController,
viewModel: FindFlightsViewModel = viewModel(factory = AppViewModelProvider.Factory) viewModel: FindFlightsViewModel = viewModel(factory = AppViewModelProvider.Factory)
) { ) {
val foundFlightsUiState = viewModel.foundFlightsList val foundFlightsUiState = viewModel.foundFlightsUiState
Scaffold( Scaffold(
topBar = {} topBar = {}
@ -55,7 +56,7 @@ fun FoundFlights(
modifier = Modifier modifier = Modifier
.padding(innerPadding) .padding(innerPadding)
.fillMaxSize(), .fillMaxSize(),
flightList = foundFlightsUiState, flightList = foundFlightsUiState.flightList,
onClick = { uid: Int -> onClick = { uid: Int ->
val route = BottomBarScreen.FlightInfo.passId(uid.toString()) val route = BottomBarScreen.FlightInfo.passId(uid.toString())
navController.navigate(route) navController.navigate(route)

View File

@ -6,7 +6,6 @@ import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory import androidx.lifecycle.viewmodel.viewModelFactory
import ru.ulstu.`is`.airticketrentservice.TicketApplication import ru.ulstu.`is`.airticketrentservice.TicketApplication
import ru.ulstu.`is`.airticketrentservice.api.AppService
object AppViewModelProvider { object AppViewModelProvider {
val Factory = viewModelFactory { val Factory = viewModelFactory {
@ -53,7 +52,8 @@ object AppViewModelProvider {
initializer { initializer {
FindFlightsViewModel( FindFlightsViewModel(
this.createSavedStateHandle(), this.createSavedStateHandle(),
ticketApplication().container.flightRestRepository) ticketApplication().container.flightRestRepository
)
} }
initializer { initializer {
UserEditViewModel( UserEditViewModel(

View File

@ -11,36 +11,24 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ru.ulstu.`is`.airticketrentservice.api.AppService
import ru.ulstu.`is`.airticketrentservice.api.model.toFlight
import ru.ulstu.`is`.airticketrentservice.database.AppContainer import ru.ulstu.`is`.airticketrentservice.database.AppContainer
import ru.ulstu.`is`.airticketrentservice.database.models.Flight import ru.ulstu.`is`.airticketrentservice.database.models.Flight
import ru.ulstu.`is`.airticketrentservice.database.repository.FlightRepository import ru.ulstu.`is`.airticketrentservice.database.repository.FlightRepository
class FindFlightsViewModel( class FindFlightsViewModel(
savedStateHandle: SavedStateHandle, savedStateHandle: SavedStateHandle,
private val flightRepository: FlightRepository, private val flightRepository: FlightRepository
) : ViewModel() { ) : ViewModel() {
private val from: String = checkNotNull(savedStateHandle["direction_from"]) private val from: String = checkNotNull(savedStateHandle["direction_from"])
private val to: String = checkNotNull(savedStateHandle["direction_to"]) private val to: String = checkNotNull(savedStateHandle["direction_to"])
private val departureDate: String = checkNotNull(savedStateHandle["departure_date"]) private val departureDate: String = checkNotNull(savedStateHandle["departure_date"])
// private val appService: AppService
// get() {
// return AppService
// }
var foundFlightsList: List<Flight> by mutableStateOf(emptyList())
private set
var foundFlightsUiState by mutableStateOf(FoundFlightsUiState()) var foundFlightsUiState by mutableStateOf(FoundFlightsUiState())
private set private set
init { init {
viewModelScope.launch { viewModelScope.launch {
//foundFlightsList = appService.foundFlights().map { it.toFlight() } foundFlightsUiState = FoundFlightsUiState(flightRepository.findFlights(from, to, departureDate))
foundFlightsUiState = FoundFlightsUiState(flightRepository.foundFlights(from, to, departureDate))
} }
} }
} }

View File

@ -7,7 +7,7 @@
"flightId": 2 "flightId": 2
} }
], ],
"searchFlights": [ "flights": [
{ {
"id": 2, "id": 2,
"direction_from": "a", "direction_from": "a",
@ -17,6 +17,15 @@
"tickets_count": 100, "tickets_count": 100,
"one_ticket_cost": 1000 "one_ticket_cost": 1000
}, },
{
"direction_from": "ульск",
"direction_to": "мск",
"departure_date": "24-12-2023",
"arrival_date": "24-12-2023",
"tickets_count": 20,
"one_ticket_cost": 2000,
"id": 3
},
{ {
"direction_from": "Санкт-Петербург ", "direction_from": "Санкт-Петербург ",
"direction_to": "Сочи", "direction_to": "Сочи",
@ -27,16 +36,14 @@
"id": 5 "id": 5
}, },
{ {
"id": 6,
"direction_from": "Ульяновск ", "direction_from": "Ульяновск ",
"direction_to": "Москва ", "direction_to": "Москва ",
"departure_date": "26-12-2023", "departure_date": "26-12-2023",
"arrival_date": "26-12-2023", "arrival_date": "26-12-2023",
"tickets_count": 50, "tickets_count": 40,
"one_ticket_cost": 2680 "one_ticket_cost": 2680,
} "id": 6
], },
"flights": [
{ {
"direction_from": "Хабаровск ", "direction_from": "Хабаровск ",
"direction_to": "Кострома ", "direction_to": "Кострома ",
@ -114,26 +121,6 @@
"password": "aaa", "password": "aaa",
"role": "user", "role": "user",
"id": 5 "id": 5
},
{
"surname": "фффф",
"name": "ффф",
"patronymic": "ффф",
"date_of_birth": "7-5-2005",
"email": "userff@mail.ru",
"password": "password",
"role": "user",
"id": 6
},
{
"surname": "ккк",
"name": "ккк",
"patronymic": "ккк",
"date_of_birth": "23-12-2011",
"email": "kkk@mail.ru",
"password": "kkk",
"role": "user",
"id": 7
} }
], ],
"rents": [ "rents": [

View File

@ -7,7 +7,7 @@
"flightId": 2 "flightId": 2
} }
], ],
"foundFlights": [ "flights": [
{ {
"id": 2, "id": 2,
"direction_from": "a", "direction_from": "a",
@ -17,6 +17,15 @@
"tickets_count": 100, "tickets_count": 100,
"one_ticket_cost": 1000 "one_ticket_cost": 1000
}, },
{
"direction_from": "ульск",
"direction_to": "мск",
"departure_date": "24-12-2023",
"arrival_date": "24-12-2023",
"tickets_count": 20,
"one_ticket_cost": 2000,
"id": 3
},
{ {
"direction_from": "Санкт-Петербург ", "direction_from": "Санкт-Петербург ",
"direction_to": "Сочи", "direction_to": "Сочи",
@ -27,16 +36,14 @@
"id": 5 "id": 5
}, },
{ {
"id": 6,
"direction_from": "Ульяновск ", "direction_from": "Ульяновск ",
"direction_to": "Москва ", "direction_to": "Москва ",
"departure_date": "26-12-2023", "departure_date": "26-12-2023",
"arrival_date": "26-12-2023", "arrival_date": "26-12-2023",
"tickets_count": 50, "tickets_count": 40,
"one_ticket_cost": 2680 "one_ticket_cost": 2680,
} "id": 6
], },
"flights": [
{ {
"direction_from": "Хабаровск ", "direction_from": "Хабаровск ",
"direction_to": "Кострома ", "direction_to": "Кострома ",
@ -110,30 +117,10 @@
"name": "шчшчгч", "name": "шчшчгч",
"patronymic": "шчшчшч", "patronymic": "шчшчшч",
"date_of_birth": "10-12-2015", "date_of_birth": "10-12-2015",
"email": "aa@mail.ru", "email": "aaa@mail.ru",
"password": "aaa", "password": "aaa",
"role": "user", "role": "user",
"id": 5 "id": 5
},
{
"surname": "фффф",
"name": "ффф",
"patronymic": "ффф",
"date_of_birth": "7-5-2005",
"email": "userff@mail.ru",
"password": "password",
"role": "user",
"id": 6
},
{
"surname": "ккк",
"name": "ккк",
"patronymic": "ккк",
"date_of_birth": "23-12-2011",
"email": "kkk@mail.ru",
"password": "kkk",
"role": "user",
"id": 7
} }
], ],
"rents": [ "rents": [