Login, NFCWaiter

This commit is contained in:
2025-03-24 14:02:25 +01:00
parent d55dee91e9
commit ebe33abf69
11 changed files with 308 additions and 62 deletions
@@ -3,26 +3,34 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WorkFlowCheck.MAUI.Pages.BaseStock.CheckPointsPage" x:Class="WorkFlowCheck.MAUI.Pages.BaseStock.CheckPointsPage"
Title="Ellenőrzési pontok"> Title="Ellenőrzési pontok">
<RefreshView x:Name="refreshView" Command="{Binding RefreshCommand}" IsRefreshing="{Binding IsRefreshing}"> <StackLayout>
<CollectionView x:Name="CheckPointsList"> <Button
<CollectionView.ItemTemplate> x:Name="ButtonSync" Margin="5"
<DataTemplate> Text="Adatok szinkronizálása"
<Frame BorderColor="Gray" Padding="10" Margin="5" HasShadow="True" BackgroundColor="WhiteSmoke"> SemanticProperties.Hint="Adatok szinkronizálása"
<StackLayout> Clicked="OnButtonSync"
<Label Text="{Binding ShortName}" FontSize="16" FontAttributes="Bold" /> HorizontalOptions="Fill" />
<Label Text="{Binding Code}" FontSize="14" /> <RefreshView x:Name="refreshView" Command="{Binding RefreshCommand}" IsRefreshing="{Binding IsRefreshing}">
<HorizontalStackLayout HorizontalOptions="End"> <CollectionView x:Name="CheckPointsList">
<Button Text="Edit" Margin="5,0,0,0" <CollectionView.ItemTemplate>
<DataTemplate>
<Frame BorderColor="Gray" Padding="10" Margin="5" HasShadow="True" BackgroundColor="WhiteSmoke">
<StackLayout>
<Label Text="{Binding ShortName}" FontSize="16" FontAttributes="Bold" />
<Label Text="{Binding Code}" FontSize="14" />
<HorizontalStackLayout HorizontalOptions="End">
<Button Text="Edit" Margin="5,0,0,0"
Command="{Binding BindingContext.EditCommand, Source={x:Reference CheckPointsList}}" Command="{Binding BindingContext.EditCommand, Source={x:Reference CheckPointsList}}"
CommandParameter="{Binding .}" /> CommandParameter="{Binding .}" />
<Button Text="Pair" Margin="5,0,0,0" <Button Text="Pair" Margin="5,0,0,0"
Command="{Binding BindingContext.PairCommand, Source={x:Reference CheckPointsList}}" Command="{Binding BindingContext.PairCommand, Source={x:Reference CheckPointsList}}"
CommandParameter="{Binding .}" /> CommandParameter="{Binding .}" />
</HorizontalStackLayout> </HorizontalStackLayout>
</StackLayout> </StackLayout>
</Frame> </Frame>
</DataTemplate> </DataTemplate>
</CollectionView.ItemTemplate> </CollectionView.ItemTemplate>
</CollectionView> </CollectionView>
</RefreshView> </RefreshView>
</StackLayout>
</ContentPage> </ContentPage>
@@ -59,7 +59,10 @@ public partial class CheckPointsPage : ContentPage
Shell.Current.GoToAsync("//BaseStockPage"); Shell.Current.GoToAsync("//BaseStockPage");
return true; return true;
} }
private void OnButtonSync(object sender, EventArgs e)
{
_syncService.SyncCheckPointsUp();
}
#region NFC #region NFC
bool _eventsAlreadySubscribed = false; bool _eventsAlreadySubscribed = false;
CheckPointDTO _checkPointDTO = null; CheckPointDTO _checkPointDTO = null;
@@ -1,5 +1,7 @@
using System.Diagnostics;
using System.Windows.Input; using System.Windows.Input;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
using WorkFlowCheck.MAUI.Pages.NFC;
using WorkFlowCheck.MAUI.Services.Interfaces; using WorkFlowCheck.MAUI.Services.Interfaces;
namespace WorkFlowCheck.MAUI.Pages.CheckList; namespace WorkFlowCheck.MAUI.Pages.CheckList;
@@ -13,8 +15,8 @@ public partial class CheckListPage : ContentPage
public ICommand ContinueCommand { get; set; } public ICommand ContinueCommand { get; set; }
public CheckListPage() public CheckListPage()
{ {
InitializeComponent(); InitializeComponent();
_checkListService = MauiProgram.ServiceProvider.GetRequiredService<ICheckListService>(); _checkListService = MauiProgram.ServiceProvider.GetRequiredService<ICheckListService>();
_userService = MauiProgram.ServiceProvider.GetRequiredService<IUserService>(); _userService = MauiProgram.ServiceProvider.GetRequiredService<IUserService>();
@@ -29,6 +31,7 @@ public partial class CheckListPage : ContentPage
base.OnAppearing(); base.OnAppearing();
NewCommand = new Command<CheckListTemplateHeaderDTO>(OnNewItem); NewCommand = new Command<CheckListTemplateHeaderDTO>(OnNewItem);
ContinueCommand = new Command<CheckListHeaderDTO>(OnContinueItem); ContinueCommand = new Command<CheckListHeaderDTO>(OnContinueItem);
BindingContext = this;
await LoadCheckListTemplate(); await LoadCheckListTemplate();
await LoadCheckList(); await LoadCheckList();
} }
@@ -37,10 +40,14 @@ public partial class CheckListPage : ContentPage
//await Navigation.PushAsync(new CheckPointEditPage(checkPointDTO)); //await Navigation.PushAsync(new CheckPointEditPage(checkPointDTO));
} }
private async void OnContinueItem(CheckListHeaderDTO checkListTemplateHeaderDTO) private async void OnContinueItem(CheckListHeaderDTO checkListHeaderDTO)
{ {
var taskCompletionSource = new TaskCompletionSource<string>();
await Navigation.PushAsync(new NFCWaiter(taskCompletionSource));
var result = await taskCompletionSource.Task;
//await Navigation.PushAsync(new CheckPointEditPage(checkPointDTO));
} }
private async Task LoadCheckListTemplate() private async Task LoadCheckListTemplate()
{ {
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WorkFlowCheck.MAUI.Pages.NFC.NFCWaiter"
Title="NFCWaiter">
<VerticalStackLayout>
<Label
Text="Várakozás az NFC beolvasásra ..."
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
@@ -0,0 +1,117 @@
using Plugin.NFC;
using System.Collections.ObjectModel;
namespace WorkFlowCheck.MAUI.Pages.NFC;
public partial class NFCWaiter : ContentPage
{
private bool _eventsAlreadySubscribed = false;
private bool _onReceiveing = false;
private TaskCompletionSource<string> _taskCompletionSource;
public NFCWaiter(TaskCompletionSource<string> taskCompletionSource)
{
InitializeComponent();
_taskCompletionSource = taskCompletionSource;
}
protected override async void OnAppearing()
{
base.OnAppearing();
CrossNFC.Legacy = false;
if (CrossNFC.IsSupported)
{
if (!CrossNFC.Current.IsAvailable)
await ShowAlert("NFC is not available");
if (!CrossNFC.Current.IsEnabled)
await ShowAlert("NFC is disabled");
await AutoStartAsync().ConfigureAwait(false);
}
else
{
await ShowAlert("NFC is not available");
}
}
async Task AutoStartAsync()
{
// Some delay to prevent Java.Lang.IllegalStateException "Foreground dispatch can only be enabled when your activity is resumed" on Android
await Task.Delay(500);
await StartListeningIfNotiOS();
}
async Task StartListeningIfNotiOS()
{
await BeginListening();
}
async Task BeginListening()
{
try
{
MainThread.BeginInvokeOnMainThread(() =>
{
SubscribeEvents();
CrossNFC.Current.StartListening();
});
}
catch (Exception ex)
{
await ShowAlert(ex.Message);
}
}
async Task EndListening()
{
try
{
MainThread.BeginInvokeOnMainThread(() =>
{
UnsubscribeEvents();
CrossNFC.Current.StopPublishing();
CrossNFC.Current.StopListening();
});
}
catch (Exception ex)
{
await ShowAlert(ex.Message);
}
}
void SubscribeEvents()
{
if (_eventsAlreadySubscribed)
UnsubscribeEvents();
_eventsAlreadySubscribed = true;
CrossNFC.Current.OnMessageReceived += Current_OnMessageReceived_NFCData;
}
void UnsubscribeEvents()
{
CrossNFC.Current.OnMessageReceived -= Current_OnMessageReceived_NFCData;
_eventsAlreadySubscribed = false;
}
async void Current_OnMessageReceived_NFCData(ITagInfo tagInfo)
{
_onReceiveing = true;
if (tagInfo == null)
{
await ShowAlert("No tag found");
_onReceiveing = false;
return;
}
// Customized serial number
var identifier = tagInfo.Identifier;
var serialNumber = NFCUtils.ByteArrayToHexString(identifier, ":");
_taskCompletionSource.TrySetResult(serialNumber);
await EndListening();
await Navigation.PopAsync();
_onReceiveing = false;
}
Task ShowAlert(string message, string title = null) => DisplayAlert(string.IsNullOrWhiteSpace(title) ? "NFC olvasás" : title, message, "OK");
}
@@ -1,27 +1,69 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:dx="http://schemas.devexpress.com/maui"
x:Class="WorkFlowCheck.MAUI.Pages.Security.LoginPage" x:Class="WorkFlowCheck.MAUI.Pages.Security.LoginPage"
Title="Bejelentkezés" Title="Bejelentkezés"
> BackgroundColor="#f0f0f0">
<StackLayout Padding="20" VerticalOptions="Center">
<Entry x:Name="UsernameEntry" Placeholder="Felhasználói név" /> <ScrollView>
<Entry x:Name="PasswordEntry" Placeholder="PIN kód" IsPassword="True" Keyboard="Numeric"/> <Grid>
<!--<dx:PasswordEdit <Grid.RowDefinitions>
Text="{Binding Password, Mode=TwoWay}" <RowDefinition Height="*" />
HasError="{Binding PasswordHasError}" <RowDefinition Height="Auto" />
LabelText="Password" <RowDefinition Height="*" />
HelpText="*Required" </Grid.RowDefinitions>
Keyboard="Numeric"
ErrorText="The password should contain more than 5 characters, <!-- Középen lévő kártya, ami mobilon is jól mutat, tableten pedig középen marad -->
have at least one uppercase and one lowercase letter, and one number." <Frame Grid.Row="1"
PlaceholderText="Enter password"/>--> BackgroundColor="White"
<Button x:Name="LoginBtn" Text="Bejelentkezés" Clicked="OnLoginClicked" /> BorderColor="#cccccc"
<ActivityIndicator x:Name="LoadingIndicator" CornerRadius="20"
IsRunning="False" Padding="30"
IsVisible="False" HasShadow="True"
VerticalOptions="Center" HorizontalOptions="Center"
HorizontalOptions="Center" /> VerticalOptions="Center"
</StackLayout> WidthRequest="{OnPlatform Android=350, iOS=350, WinUI=400, MacCatalyst=400}"
MaximumWidthRequest="500">
<VerticalStackLayout Spacing="20">
<Label Text="Bejelentkezés"
FontSize="24"
FontAttributes="Bold"
HorizontalOptions="Center"
TextColor="#333" />
<Entry x:Name="UsernameEntry"
Placeholder="Felhasználói név"
FontSize="18"
BackgroundColor="#f9f9f9"
HeightRequest="50"
Margin="0" />
<Entry x:Name="PasswordEntry"
Placeholder="PIN kód"
IsPassword="True"
Keyboard="Numeric"
FontSize="18"
BackgroundColor="#f9f9f9"
HeightRequest="50"
Margin="0" />
<Button x:Name="LoginBtn"
Text="Bejelentkezés"
FontSize="18"
HeightRequest="50"
CornerRadius="10"
BackgroundColor="#007aff"
TextColor="White"
Clicked="OnLoginClicked" />
<ActivityIndicator x:Name="LoadingIndicator"
IsRunning="False"
IsVisible="False"
HorizontalOptions="Center" />
</VerticalStackLayout>
</Frame>
</Grid>
</ScrollView>
</ContentPage> </ContentPage>
@@ -5,10 +5,12 @@ namespace WorkFlowCheck.MAUI.Pages.Security;
public partial class LoginPage : ContentPage public partial class LoginPage : ContentPage
{ {
private IUserService _userService; private IUserService _userService;
private ISyncService _syncService;
public LoginPage() public LoginPage()
{ {
InitializeComponent(); InitializeComponent();
_userService = MauiProgram.ServiceProvider.GetRequiredService<IUserService>(); _userService = MauiProgram.ServiceProvider.GetRequiredService<IUserService>();
_syncService = MauiProgram.ServiceProvider.GetRequiredService<ISyncService>();
} }
private async void OnLoginClicked(object sender, EventArgs e) private async void OnLoginClicked(object sender, EventArgs e)
{ {
@@ -24,6 +26,7 @@ public partial class LoginPage : ContentPage
if (response != null && response.IsSuccess) if (response != null && response.IsSuccess)
{ {
_userService.SetCurrentUser(response.Data); _userService.SetCurrentUser(response.Data);
await _syncService.SyncDatas();
var wFCUser = Newtonsoft.Json.JsonConvert.SerializeObject(response.Data); var wFCUser = Newtonsoft.Json.JsonConvert.SerializeObject(response.Data);
await SecureStorage.Default.SetAsync("WFCUser", "wFCUser"); await SecureStorage.Default.SetAsync("WFCUser", "wFCUser");
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="300" height="300" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"> <text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle"
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" /> font-size="24" fill="white" font-family="Arial">
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" /> Workflow Check Application
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" /> </text>
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 330 B

@@ -9,6 +9,11 @@ namespace WorkFlowCheck.MAUI.Services.Interfaces
public interface ISyncService public interface ISyncService
{ {
Task SyncDatas(); Task SyncDatas();
Task SyncCheckPointsDown();
Task SyncCheckPointsUp();
Task SyncLocations();
Task SyncEquipments();
} }
} }
+49 -2
View File
@@ -1,6 +1,7 @@
using AutoMapper; using AutoMapper;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System.Net.Http.Json; using System.Net.Http.Json;
using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.DTO;
using WorkFlowCheck.MAUI.DataLayer; using WorkFlowCheck.MAUI.DataLayer;
@@ -19,13 +20,13 @@ namespace WorkFlowCheck.MAUI.Services
} }
public async Task SyncDatas() public async Task SyncDatas()
{ {
await SyncCheckPoints(); await SyncCheckPointsDown();
await SyncLocations(); await SyncLocations();
await SyncEquipments(); await SyncEquipments();
await SyncCheckListTemplates(); await SyncCheckListTemplates();
await SyncCheckList(); await SyncCheckList();
} }
public async Task SyncCheckPoints() public async Task SyncCheckPointsDown()
{ {
try try
{ {
@@ -55,6 +56,52 @@ namespace WorkFlowCheck.MAUI.Services
} }
} }
public async Task SyncCheckPointsUp()
{
try
{
await PrepareAuthenticatedRequestAsync();
// Az API végpont meghatározása
string endpoint = $"{_httpClient.BaseAddress}api/Sync/GetAllCheckPoints";
// HTTP GET kérés küldése
var response = await _httpClient.GetFromJsonAsync<ApiResponseDTO<List<CheckPointDTO>>>(endpoint);
if (response != null)
{
if (response.IsSuccess)
{
var entityList = await _dbContext.CheckPoints.ToListAsync();
var missingItems = response.Data.Where(f => !entityList.Any(s => s.Id == f.Id & s.Code == f.Code)).ToList();
var checkPointListDTO = _mapper.Map<List<CheckPointDTO>>(missingItems);
foreach (var item in checkPointListDTO)
{
var entity = await _dbContext.CheckPoints.Where(w => w.Id == item.Id).FirstOrDefaultAsync();
if (entity != null)
{
item.ShortName = entity.ShortName;
item.Code = entity.Code;
}
}
endpoint = $"{_httpClient.BaseAddress}api/Sync/UpdateAllCheckPoint";
using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsJsonAsync(endpoint, checkPointListDTO))
{
httpResponseMessage.EnsureSuccessStatusCode();
var jsonString = await httpResponseMessage.Content.ReadAsStringAsync();
response = JsonConvert.DeserializeObject<ApiResponseDTO<List<CheckPointDTO>>>(jsonString);
}
}
}
}
catch (Exception ex)
{
// Hiba visszaadása
}
}
public async Task SyncLocations() public async Task SyncLocations()
{ {
try try
@@ -43,7 +43,7 @@
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" /> <MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<!-- Splash Screen --> <!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" /> <MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="400,400" />
<!-- Images --> <!-- Images -->
<MauiImage Include="Resources\Images\*" /> <MauiImage Include="Resources\Images\*" />
@@ -115,6 +115,9 @@
<MauiXaml Update="Pages\NFC\NFCTestPage.xaml"> <MauiXaml Update="Pages\NFC\NFCTestPage.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>
<MauiXaml Update="Pages\NFC\NFCWaiter.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="Pages\Security\LoginPage.xaml"> <MauiXaml Update="Pages\Security\LoginPage.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</MauiXaml> </MauiXaml>