2025-02-20-15-57

This commit is contained in:
mister 2025-02-20 15:57:59 +03:00
parent 2c4c6ecd0d
commit 9327fd73a7
23 changed files with 202 additions and 91 deletions

View File

@ -1,5 +1,5 @@
package ru.myitschool.work.core
// БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ
object Constants {
const val SERVER_ADDRESS = "http://192.168.0.75:8080"
const val SERVER_ADDRESS = "http://192.168.56.1"
}

View File

@ -1,34 +0,0 @@
package ru.myitschool.work.data.dto;
public class Employee {
private long id;
private String login;
private String name;
private String photo;
private String position;
private String lastVisit;
public long getId() {
return id;
}
public String getLogin() {
return login;
}
public String getName() {
return name;
}
public String getPhoto() {
return photo;
}
public String getPosition() {
return position;
}
public String getLastVisit() {
return lastVisit;
}
}

View File

@ -4,6 +4,7 @@ import static ru.myitschool.work.core.Constants.SERVER_ADDRESS;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import ru.myitschool.work.data.network.api.AdminApi;
import ru.myitschool.work.data.network.api.EmployeeApi;
public class RetrofitFactory {
@ -28,4 +29,8 @@ public class RetrofitFactory {
public EmployeeApi getEmployeeApi() {
return retrofit.create(EmployeeApi.class);
}
public AdminApi getAdminApi() {
return retrofit.create(AdminApi.class);
}
}

View File

@ -1,19 +1,27 @@
package ru.myitschool.work.data.network.api;
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Query;
import ru.myitschool.work.data.dto.Code;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.data.dto.EmployeeDataDto;
import ru.myitschool.work.data.dto.EntryDto;
public interface AdminApi {
@POST("/api/admin/am-i-admin")
Call<Void> amIAdmin(@Header("Authorization") String auth);
@POST("/api/admin/panel/get-employee-info")
Call<Void> getEmployeeInfo(@Header("Authorization") String auth, @Query("employee-login") String login);
Call<EmployeeDataDto> getEmployeeInfo(@Header("Authorization") String auth, @Query("employee-login") String login);
@POST("/api/admin/panel/set-block-condition")
Call<Void> setBlockCondition(@Header("Authorization") String auth, @Query("employee-login") String login, @Query("block-condition") Boolean condition);
@POST("/api/admin/panel/get-employee-entry-list")
Call<List<EntryDto>> getEmployeeEntry(@Header("Authorization") String auth, @Query("employee-login") String login);
@POST("/api/admin/panel/is-employee-blocked")
Call<Boolean> isEmployeeBlock(@Header("Authorization") String auth, @Query("employee-login") String login);
}

View File

@ -2,20 +2,17 @@ package ru.myitschool.work.data.network.api;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.PATCH;
import retrofit2.http.POST;
import retrofit2.http.Path;
import ru.myitschool.work.data.dto.Code;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.data.dto.EmployeeDataDto;
public interface EmployeeApi {
@POST("/api/employee/auth")
Call<Void> auth(@Header("Authorization") String auth);
@POST("/api/employee/info")
Call<Employee> info(@Header("Authorization") String auth);
Call<EmployeeDataDto> info(@Header("Authorization") String auth);
@POST("/api/employee/open")
Call<Void> open(@Header("Authorization") String auth, @Body Code code);

View File

@ -0,0 +1,104 @@
package ru.myitschool.work.data.repository;
import androidx.annotation.NonNull;
import java.util.List;
import java.util.function.Consumer;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import ru.myitschool.work.data.dto.EmployeeDataDto;
import ru.myitschool.work.data.dto.EntryDto;
import ru.myitschool.work.data.network.RetrofitFactory;
import ru.myitschool.work.data.network.api.AdminApi;
import ru.myitschool.work.domain.admin.AdminRepository;
import ru.myitschool.work.domain.entities.Status;
public class AdminRepositoryImpl implements AdminRepository {
private static AdminRepositoryImpl INSTANCE;
public static AdminRepositoryImpl getInstance() {
if (INSTANCE == null) {
INSTANCE = new AdminRepositoryImpl();
}
return INSTANCE;
}
private AdminApi adminApi = RetrofitFactory.getInstance().getAdminApi();
@Override
public void amIAdmin(@NonNull String auth, @NonNull Consumer<Status<Void>> callback) {
adminApi.amIAdmin(auth).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
callback.accept(new Status<>(response.code(), response.body(), null));
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
callback.accept(new Status<>(-1, null, t));
}
});
}
@Override
public void getEmployeeInfo(@NonNull String auth, @NonNull String login, @NonNull Consumer<Status<EmployeeDataDto>> callback) {
adminApi.getEmployeeInfo(auth, login).enqueue(new Callback<EmployeeDataDto>() {
@Override
public void onResponse(Call<EmployeeDataDto> call, Response<EmployeeDataDto> response) {
callback.accept(new Status<>(response.code(), response.body(), null));
}
@Override
public void onFailure(Call<EmployeeDataDto> call, Throwable t) {
callback.accept(new Status<>(-1, null, t));
}
});
}
@Override
public void setBlockCondition(@NonNull String auth, @NonNull String login, @NonNull Boolean condition, @NonNull Consumer<Status<Void>> callback) {
adminApi.setBlockCondition(auth, login, condition).enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
callback.accept(new Status<>(response.code(), response.body(), null));
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
callback.accept(new Status<>(-1, null, t));
}
});
}
@Override
public void getEmployeeEntryList(@NonNull String auth, @NonNull String login, @NonNull Consumer<Status<List<EntryDto>>> callback) {
adminApi.getEmployeeEntry(auth, login).enqueue(new Callback<List<EntryDto>>() {
@Override
public void onResponse(Call<List<EntryDto>> call, Response<List<EntryDto>> response) {
callback.accept(new Status<>(response.code(), response.body(), null));
}
@Override
public void onFailure(Call<List<EntryDto>> call, Throwable t) {
callback.accept(new Status<>(-1, null, t));
}
});
}
@Override
public void isEmployeeBlock(@NonNull String auth, @NonNull String login, @NonNull Consumer<Status<Boolean>> callback) {
adminApi.isEmployeeBlock(auth, login).enqueue(new Callback<Boolean>() {
@Override
public void onResponse(Call<Boolean> call, Response<Boolean> response) {
callback.accept(new Status<>(response.code(), response.body(), null));
}
@Override
public void onFailure(Call<Boolean> call, Throwable t) {
callback.accept(new Status<>(-1, null, t));
}
});
}
}

View File

@ -7,7 +7,7 @@ import java.util.function.Consumer;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.data.dto.EmployeeDataDto;
import ru.myitschool.work.data.network.RetrofitFactory;
import ru.myitschool.work.data.network.api.EmployeeApi;
import ru.myitschool.work.domain.entities.Status;
@ -27,15 +27,15 @@ public class InfoRepositoryImpl implements InfoRepository {
@Override
public void info(@NonNull String login, @NonNull Consumer<Status<Employee>> callback) {
employeeApi.info(login).enqueue(new Callback<Employee>() {
public void info(@NonNull String login, @NonNull Consumer<Status<EmployeeDataDto>> callback) {
employeeApi.info(login).enqueue(new Callback<EmployeeDataDto>() {
@Override
public void onResponse(Call<Employee> call, Response<Employee> response) {
public void onResponse(Call<EmployeeDataDto> call, Response<EmployeeDataDto> response) {
callback.accept(new Status<>(response.code(), response.body(), null));
}
@Override
public void onFailure(Call<Employee> call, Throwable t) {
public void onFailure(Call<EmployeeDataDto> call, Throwable t) {
callback.accept(new Status<>(-1, null, t));
}
});

View File

@ -4,7 +4,6 @@ import androidx.annotation.NonNull;
import java.util.function.Consumer;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.domain.entities.Status;
public class AmIAdminUseCase {

View File

@ -2,6 +2,8 @@ package ru.myitschool.work.domain.entities;
import androidx.annotation.Nullable;
import ru.myitschool.work.data.dto.EmployeeDataDto;
public class Status<T> {
private final int statusCode;
@Nullable

View File

@ -4,9 +4,9 @@ import androidx.annotation.NonNull;
import java.util.function.Consumer;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.data.dto.EmployeeDataDto;
import ru.myitschool.work.domain.entities.Status;
public interface InfoRepository {
void info(@NonNull String login, @NonNull Consumer<Status<Employee>> callback);
void info(@NonNull String login, @NonNull Consumer<Status<EmployeeDataDto>> callback);
}

View File

@ -4,7 +4,7 @@ import androidx.annotation.NonNull;
import java.util.function.Consumer;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.data.dto.EmployeeDataDto;
import ru.myitschool.work.domain.entities.Status;
public class InfoUseCase {
@ -14,7 +14,7 @@ public class InfoUseCase {
this.repository = repository;
}
public void execute(@NonNull String login, @NonNull Consumer<Status<Employee>> callback) {
public void execute(@NonNull String login, @NonNull Consumer<Status<EmployeeDataDto>> callback) {
repository.info(login, callback);
}
}

View File

@ -16,7 +16,7 @@ import androidx.navigation.Navigation;
import com.squareup.picasso.Picasso;
import ru.myitschool.work.R;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.data.dto.EmployeeDataDto;
import ru.myitschool.work.databinding.FragmentEmployeeBinding;
import ru.myitschool.work.ui.qr.scan.QrScanDestination;
@ -119,13 +119,20 @@ public class EmployeeFragment extends Fragment {
}
});
viewModel.employeeLiveData.observe(getViewLifecycleOwner(), new Observer<Employee>() {
viewModel.employeeLiveData.observe(getViewLifecycleOwner(), new Observer<EmployeeDataDto>() {
@Override
public void onChanged(Employee value) {
public void onChanged(EmployeeDataDto value) {
binding.fullname.setText(value.getName());
Picasso.get().load(value.getPhoto()).into(binding.photo);
binding.position.setText(value.getPosition());
binding.lastEntry.setText(value.getLastVisit());
binding.position.setText(value.getEmployeePosition());
binding.lastEntry.setText(value.getLastVisit().toString());
}
});
viewModel.amIAdminLiveData.observe(getViewLifecycleOwner(), new Observer<Boolean>() {
@Override
public void onChanged(Boolean value) {
binding.adminPanel.setVisibility(value ? View.VISIBLE : View.GONE);
}
});
}

View File

@ -4,18 +4,24 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import ru.myitschool.work.data.dto.Employee;
import ru.myitschool.work.data.dto.EmployeeDataDto;
import ru.myitschool.work.data.repository.AdminRepositoryImpl;
import ru.myitschool.work.data.repository.InfoRepositoryImpl;
import ru.myitschool.work.domain.admin.AmIAdminUseCase;
import ru.myitschool.work.domain.info.InfoUseCase;
public class EmployeeViewModel extends ViewModel {
private final MutableLiveData<Boolean> mutableIsSuccessfulReceiptLiveData = new MutableLiveData<>();
public final LiveData<Boolean> isSuccessfulReceiptLiveData = mutableIsSuccessfulReceiptLiveData;
private final MutableLiveData<Employee> mutableEmployeeLiveData = new MutableLiveData<>();
public final LiveData<Employee> employeeLiveData = mutableEmployeeLiveData;
private final MutableLiveData<EmployeeDataDto> mutableEmployeeLiveData = new MutableLiveData<>();
public final LiveData<EmployeeDataDto> employeeLiveData = mutableEmployeeLiveData;
private final MutableLiveData<Boolean> mutableAmIAdminLiveData = new MutableLiveData<>();
public final LiveData<Boolean> amIAdminLiveData = mutableAmIAdminLiveData;
private final InfoUseCase infoUseCase = new InfoUseCase(InfoRepositoryImpl.getInstance());
private final AmIAdminUseCase amIAdminUseCase = new AmIAdminUseCase(AdminRepositoryImpl.getInstance());
public void startQuery(String currentLogin) {
infoUseCase.execute(currentLogin, status -> {
@ -27,4 +33,14 @@ public class EmployeeViewModel extends ViewModel {
}
});
}
public void checkAmIAdmin(String auth) {
amIAdminUseCase.execute(auth, status -> {
if (status.getStatusCode() == 200) {
mutableAmIAdminLiveData.setValue(true);
} else {
mutableIsSuccessfulReceiptLiveData.setValue(false);
}
});
}
}

View File

@ -84,9 +84,9 @@ public class LoginFragment extends Fragment {
public void onClick(View v) {
binding.username.setText("");
binding.password.setText("");
Navigation.findNavController(getView()).navigate(
/*Navigation.findNavController(getView()).navigate(
R.id.action_login_fragment_to_employee_fragment
);
);*/
binding.error.setVisibility(View.GONE);
}
});

View File

@ -2,5 +2,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="16dp" />
<solid android:color="#03A9F4" />
<solid android:color="@color/light_blue" />
</shape>

View File

@ -27,8 +27,8 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@color/white"
android:hint="Еnter the employee's username" />
android:hint="Еnter the employee's username"
android:textSize="18sp"/>
</com.google.android.material.textfield.TextInputLayout>
@ -39,7 +39,8 @@
android:layout_height="48dp"
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Viewing employee information"
android:text="OK"
android:textSize="24sp"
android:textColor="#FFFFFF"
android:layout_marginBottom="16dp"/>

View File

@ -55,11 +55,12 @@
android:layout_marginBottom="16dp"/>
<TextView
android:id="@+id/isLog"
android:id="@+id/isBlock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
tools:text="Is Log"
tools:text="Is Block"
android:textSize="12sp"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
@ -74,19 +75,6 @@
android:layout_marginEnd="25dp"
android:paddingBottom="16dp" />
<TextView
android:id="@+id/isAdmin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
tools:text="Is Admin"
android:visibility="invisible"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:layout_marginBottom="1dp"/>
<TextView
android:id="@+id/error"
android:layout_width="wrap_content"
@ -107,6 +95,7 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Admin Panel"
android:textSize="24sp"
android:layout_marginBottom="16dp"
android:visibility="invisible"
android:textColor="#FFFFFF" />
@ -118,6 +107,7 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Logout"
android:textSize="24sp"
android:layout_marginBottom="8dp"
android:textColor="#FFFFFF" />
@ -128,6 +118,7 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Refresh"
android:textSize="24sp"
android:layout_marginBottom="8dp"
android:textColor="#FFFFFF" />
@ -138,6 +129,7 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Scan"
android:textSize="24sp"
android:layout_marginBottom="8dp"
android:textColor="#FFFFFF" />

View File

@ -27,6 +27,7 @@
android:layout_marginEnd="25dp"
android:layout_marginBottom="16dp"
android:src="@drawable/user_image"/>
<TextView
android:id="@+id/position"
android:layout_width="wrap_content"
@ -59,11 +60,12 @@
android:textColor="@android:color/holo_red_dark"
android:textStyle="bold"
android:text="Error"
android:textSize="16sp"
android:visibility="invisible"
android:layout_gravity="center"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:layout_marginBottom="200dp"/>
android:layout_marginBottom="150dp"/>
<Button
android:id="@+id/block_pass"
@ -72,6 +74,7 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Block pass"
android:textSize="24sp"
android:textColor="#FFFFFF"
android:layout_marginBottom="16dp"/>
@ -82,6 +85,7 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Unlock pass"
android:textSize="24sp"
android:textColor="#FFFFFF" />

View File

@ -6,11 +6,10 @@
android:padding="20dp">
<ImageView
android:layout_marginTop="100dp"
android:layout_marginTop="80dp"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_gravity="center"
android:layout_marginBottom="50dp"
android:src="@drawable/login_image"/>
<com.google.android.material.textfield.TextInputLayout
@ -27,7 +26,8 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@color/white"
android:hint="Enter your username" />
android:hint="Enter your username"
android:textSize="18sp"/>
</com.google.android.material.textfield.TextInputLayout>
@ -45,6 +45,7 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@color/white"
android:textSize="18sp"
android:hint="Enter your password" />
</com.google.android.material.textfield.TextInputLayout>
@ -57,13 +58,19 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Login"
android:textColor="#FFFFFF" />
android:textColor="#FFFFFF"
android:textSize="24sp"
android:layout_marginBottom="16dp"/>
<TextView
android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
android:textStyle="bold"
android:textColor="@android:color/holo_red_dark"
android:visibility="invisible"
android:text="Error"
android:textSize="16sp"/>
</LinearLayout>

View File

@ -22,6 +22,7 @@
android:layout_gravity="center"
android:background="@drawable/rounded_button"
android:text="Close"
android:textSize="24sp"
android:textColor="#FFFFFF" />
</LinearLayout>

View File

@ -7,4 +7,5 @@
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="light_blue">#03A9F4</color>
</resources>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="close_button">Close</string>
<!-- Other strings -->
</resources>

View File

@ -2,7 +2,7 @@
<!-- Base application theme. -->
<style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimary">@color/light_blue</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->