完善登陆

This commit is contained in:
muqing 2024-08-16 13:15:18 +08:00
parent 91659543fa
commit acb2ed64d0
15 changed files with 475 additions and 86 deletions

36
RustTools/ApiFox/user.cs Normal file
View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using RustTools.muqing;
namespace RustTools.ApiFox;
public class user
{
public static async Task<string> loginPc(string account, string passWord)
{
var pattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
var v = Regex.IsMatch(account, pattern);
//gj.sc(account + " " + v); //这里不知道为什么会出现 True 而不是 true 导致识别邮箱失败
var task = await wl.postAsync("/php/user.php?action=loginPc", new string[][]
{
new string[]{ "account",account},
new string[]{ "passWord", passWord },
new string[]{ "isEmail", v.ToString().ToLower() }
});
return task;
}
public static async Task<string> SpaceInfo(string account)
{
var pattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
var v = Regex.IsMatch(account, pattern);
var task = await wl.postAsync("/php/user.php?action=getSpaceInfo", new string[][]
{
new string[]{ "account",account}
});
return task;
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RustTools.DataList;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable IDE1006 // 命名样式
public class Message
{
public int code{get; set;}
public string message { get; set;}
public Data? data { get; set;}
public class Data
{
public string token
{
get; set;
}
public string account
{
get;set;
}
public string a
{
get;set;
}
}
}

View File

@ -0,0 +1,126 @@

using System.Runtime.CompilerServices;
using Newtonsoft.Json;
namespace RustTools.DataList;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable IDE1006 // 命名样式
public class UserSpaceInfo
{
[JsonProperty("code")]
public int Code
{
get; set;
}
[JsonProperty("message")]
public string Message
{
get; set;
}
[JsonProperty("data")]
public UserData Data
{
get; set;
}
public class UserData
{
[JsonProperty("account")]
public string Account
{
get; set;
}
[JsonProperty("userName")]
public string UserName
{
get; set;
}
[JsonProperty("headIcon")]
public string HeadIcon
{
get; set;
}
[JsonProperty("email")]
public string Email
{
get; set;
}
[JsonProperty("permission")]
public string Permission
{
get; set;
}
[JsonProperty("loginTime")]
public DateTime LoginTime
{
get; set;
}
[JsonProperty("gender")]
public string Gender
{
get; set;
}
[JsonProperty("enable")]
public bool Enable
{
get; set;
}
[JsonProperty("expirationTime")]
public string ExpirationTime
{
get; set;
}
[JsonProperty("dynamicColor")]
public string DynamicColor
{
get; set;
}
[JsonProperty("cover")]
public string Cover
{
get; set;
}
[JsonProperty("introduce")]
public string Introduce
{
get; set;
}
[JsonProperty("fans")]
public string Fans
{
get; set;
}
[JsonProperty("follower")]
public string Follower
{
get; set;
}
[JsonProperty("praise")]
public string Praise
{
get; set;
}
[JsonProperty("location")]
public string Location
{
get; set;
}
}
}

View File

@ -52,3 +52,10 @@ WinUI还是比较冷门的一个技术,代码和例子都不多 关于编译器
font-size: 16px;
color: #333;">薄荷</p>
</div>
## 开源协议
虽然没什么用但还是要写一写
如果你用到本项目中的源码的话请务必表明出处@铁锈助手
如果你也是开源软件可以把这个标记在注释中
如果不是则务必在你软件的窗口关于中标注上

View File

@ -61,27 +61,4 @@
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<None Remove="Themes\ButtonIcon.xaml" />
<None Remove="Themes\LoginPage.xaml" />
<None Remove="Themes\NullPage.xaml" />
</ItemGroup>
<ItemGroup>
<Page Update="Themes\LoginPage.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Themes\NullPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<CustomAdditionalCompileInputs Remove="Themes\ButtonIcon.xaml" />
</ItemGroup>
<ItemGroup>
<Resource Remove="Themes\ButtonIcon.xaml" />
</ItemGroup>
</Project>

View File

@ -12,8 +12,14 @@
Padding="3"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Text="{TemplateBinding TitleText}" />
<TextBlock Style="{StaticResource BodyStrongTextBlockStyle}" Text="{TemplateBinding SubtitleText}" />
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{TemplateBinding TitleText}" />
<TextBlock
HorizontalAlignment="Center"
Style="{StaticResource BodyStrongTextBlockStyle}"
Text="{TemplateBinding SubtitleText}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>

View File

@ -6,6 +6,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:RustTools.Themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodels="using:RustTools.ViewModels"
mc:Ignorable="d">
@ -14,29 +15,35 @@
Padding="26"
Background="{StaticResource CardStrokeColorDefault}"
CornerRadius="13">
<Grid MinWidth="350" HorizontalAlignment="Center">
<Grid MinWidth="290" HorizontalAlignment="Center">
<StackPanel x:Name="login_view">
<TextBlock HorizontalAlignment="Center" Text="登陆" />
<StackPanel>
<TextBox
x:Name="accountBox"
Margin="0,16,0,16"
InputScope="AlphanumericPin"
PlaceholderText="账号" />
<PasswordBox Margin="0,0,0,16" PlaceholderText="密码" />
<PasswordBox
x:Name="passwordBox"
Margin="0,0,0,16"
PlaceholderText="密码" />
</StackPanel>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
Name="loginButton"
Width="100"
Margin="16"
Click="login_Click"
Content="登陆"
IsEnabled="False"
Style="{StaticResource AccentButtonStyle}" />
<Button
Margin="0,0,0,0"
Click="enroll_Click"
Content="注册" />
</StackPanel>
<CheckBox>
<CheckBox x:Name="agreementCheck">
<CheckBox.Content>
<StackPanel Orientation="Horizontal" ToolTipService.ToolTip="虽然没什么用但是这是常规的">
<TextBlock VerticalAlignment="Center" Text="我同意" />
@ -54,31 +61,45 @@
</CheckBox>
</StackPanel>
<StackPanel x:Name="enroll_view" Visibility="Collapsed">
<local:ButtonIcon
x:Name="Back_Button"
Click="Back_Click"
Glyph="&#xE72B;" />
<local:ButtonIcon Click="Back_Click" Glyph="&#xE72B;" />
<TextBlock HorizontalAlignment="Center" Text="注册" />
<StackPanel>
<TextBox
Name="ZaccountBox"
Margin="0,16,0,16"
InputScope="AlphanumericPin"
PlaceholderText="账号" />
<TextBox
Name="ZnameBox"
Margin="0,0,0,16"
InputScope="NameOrPhoneNumber"
InputScope="Hanja"
PlaceholderText="用户名/昵称" />
<PasswordBox Margin="0,0,0,16" PlaceholderText="密码" />
<PasswordBox Margin="0,0,0,16" PlaceholderText="确认密码" />
<TextBox
<PasswordBox
Name="ZpasswordBox"
Margin="0,0,0,16"
InputScope="EmailNameOrAddress"
PlaceholderText="密码" />
<PasswordBox
Name="ZpasswordyesBox"
Margin="0,0,0,16"
PlaceholderText="确认密码" />
<TextBox
Name="ZemialBox"
Margin="0,0,0,16"
InputScope="EmailSmtpAddress"
PlaceholderText="邮箱" />
</StackPanel>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button Margin="0,0,0,0" Content="注册" />
</StackPanel>
<Button
Name="ZenrollButton"
Margin="0,0,0,0"
Click="ZenrollButton_Click"
Content="注册"
IsEnabled="False" />
</StackPanel>
<TeachingTip
x:Name="Toast"
Title="警告"
CloseButtonContent="关闭"
Subtitle="信息" />
</Grid>
</Border>
</UserControl>

View File

@ -1,15 +1,56 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
using Newtonsoft.Json;
using RustTools.ApiFox;
using RustTools.DataList;
using RustTools.muqing;
namespace RustTools.Themes;
public sealed partial class LoginPage : UserControl
{
public delegate void LoginSucceededEventHandler(object sender, string e);
public event LoginSucceededEventHandler LoginSucceeded;
public LoginPage()
{
InitializeComponent();
DefaultStyleKey = typeof(LoginPage);
accountBox.TextChanged += AccountBox_TextChanged;
passwordBox.PasswordChanged += PasswordBox_PasswordChanged;
agreementCheck.Checked += AgreementCheck_Checked;
ZaccountBox.TextChanged += ZAgreementCheck_Checked;
ZnameBox.TextChanged += ZAgreementCheck_Checked;
ZemialBox.TextChanged += ZAgreementCheck_Checked;
ZpasswordBox.PasswordChanged += ZPasswordBox_PasswordChanged;
ZpasswordyesBox.PasswordChanged += ZPasswordBox_PasswordChanged;
}
private void AgreementCheck_Checked(object sender, RoutedEventArgs e)
{
loginButton.IsEnabled = loginButtonIsEnabled;
}
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
loginButton.IsEnabled = loginButtonIsEnabled;
}
private void ZAgreementCheck_Checked(object sender, RoutedEventArgs e)
{
ZenrollButton.IsEnabled = ZenrollButtonIsEnabled;
}
private void ZPasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
ZenrollButton.IsEnabled = ZenrollButtonIsEnabled;
}
private void AccountBox_TextChanged(object sender, TextChangedEventArgs e){
loginButton.IsEnabled = loginButtonIsEnabled;
}
/// <summary>
/// ·µ»Øµ½µÇ½
/// </summary>
@ -31,22 +72,6 @@ public sealed partial class LoginPage : UserControl
storyboard.Begin();
}
private void FadeOutStoryboard_Completed(object? sender, object e)
{
// 确保动画完成后执行切换
if (login_view.Visibility == Visibility.Visible)
{
login_view.Visibility = Visibility.Collapsed;
enroll_view.Visibility = Visibility.Visible;
}
else
{
enroll_view.Visibility = Visibility.Collapsed;
login_view.Visibility = Visibility.Visible;
}
}
private Storyboard CreateFadeTransitionStoryboard(FrameworkElement fromElement, FrameworkElement toElement)
{
var storyboard = new Storyboard();
@ -78,14 +103,69 @@ public sealed partial class LoginPage : UserControl
storyboard1.Children.Add(fadeInAnimation);
storyboard1.Begin();
};
return storyboard;
}
private void login_Click(object sender, RoutedEventArgs e)
public bool loginButtonIsEnabled => !string.IsNullOrEmpty(accountBox.Text) && !string.IsNullOrEmpty(passwordBox.Password) && agreementCheck.IsChecked==true;
public bool ZenrollButtonIsEnabled =>
!string.IsNullOrEmpty(ZaccountBox.Text) &&
!string.IsNullOrEmpty(ZnameBox.Text) &&
!string.IsNullOrEmpty(ZpasswordBox.Password) &&
!string.IsNullOrEmpty(ZpasswordyesBox.Password) &&
!string.IsNullOrEmpty(ZemialBox.Text);
/// <summary>
/// 登陆
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void login_Click(object sender, RoutedEventArgs e)
{
var v = await user.loginPc(accountBox.Text, passwordBox.Password);
var message = JsonConvert.DeserializeObject<Message>(v);
if (message != null)
{
if (message.code == 0)
{
Toast.Title = "提示";
Toast.Subtitle = message.message;
Toast.IsOpen = true;
if (message.data != null)
{
// 登录成功,触发事件
var iniHelper = new IniHelper();
iniHelper.Load(IniHelper.FILE.User);
iniHelper.SetValue(IniHelper.CODE.User, IniHelper.KEY.token, message.data.token);
iniHelper.SetValue(IniHelper.CODE.User, IniHelper.KEY.account, message.data.account);
iniHelper.Save();
LoginSucceeded?.Invoke(this, message.data.account);
}
}
else
{
Toast.Title = "警告";
Toast.Subtitle = message.message;
Toast.IsOpen = true;
}
}
gj.sc(v);
}
public void login()
{
}
private void ZenrollButton_Click(object sender, RoutedEventArgs e)
{
if (ZpasswordBox.Password != ZpasswordyesBox.Password)
{
Toast.Title = "警告";
Toast.Subtitle = "密码不一致";
Toast.IsOpen = true;
return;
}
}
}

View File

@ -21,14 +21,7 @@ public partial class HomePageViewModel : ObservableRecipient
foreach (var item in modListResponse.Data)
{
//https://rust.coldmint.top
if (item.Icon.Equals(""))
{
item.Icon = "/Assets/image/image.svg";
}
else
{
item.Icon = item.Icon.Replace("..", "https://rust.coldmint.top");
}
item.Icon = item.Icon.Equals("") ? "/Assets/image/image.svg" : item.Icon.Replace("..", "https://rust.coldmint.top");
randomList.Add(item);
}
}

View File

@ -1,4 +1,5 @@
using CommunityToolkit.Mvvm.ComponentModel;
using RustTools.DataList;
namespace RustTools.ViewModels;

View File

@ -6,6 +6,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:RustTools.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:themes="using:RustTools.Themes"
mc:Ignorable="d">
<Page.Resources>
@ -25,13 +26,11 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="/Assets/image/rwmod.svg" />
<Button
<themes:ButtonIcon
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="Transparent"
Click="Button_Click">
<FontIcon Glyph="&#xE712;" />
</Button>
Click="Button_Click"
Glyph="&#xE712;" />
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom">
<TextBlock
HorizontalAlignment="Center"

View File

@ -8,10 +8,11 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:styles="using:RustTools.Styles"
xmlns:themes="using:RustTools.Themes"
xmlns:viewmodels="using:RustTools.Views"
d:DataContext="{d:DesignInstance Type=viewmodels:UserPage}"
mc:Ignorable="d">
<Grid>
<themes:LoginPage x:Name="loginpage" />
<Grid Name="view">
<Grid Name="gridview" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="110" />
@ -28,6 +29,13 @@
Padding="9,9,26,9"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
CornerRadius="10">
<Border.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Click="MenuFlyoutItemLogout_Click" Text="退出登陆" />
</MenuFlyout>
</Border.ContextFlyout>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
@ -40,19 +48,21 @@
Height="86"
Background="BlanchedAlmond"
CornerRadius="16">
<Image Source="http://q1.qlogo.cn/g?b=qq&amp;nk=2923268971&amp;s=100" />
<Image Name="headIcon" Source="{Binding userInfo.HeadIcon}" />
</Border>
<StackPanel Grid.Column="1" Margin="16,0,0,0">
<TextBlock
Name="userName"
Margin="0,9,0,0"
Style="{StaticResource TitleTextBlockStyle}"
Text="Muqing" />
Text="{Binding userInfo.UserName}" />
<TextBlock
Name="introduce"
Margin="0,6,0,0"
Style="{StaticResource BodyTextBlockStyle}"
Text="测试员,开发者,这里是签名哦" />
Text="{Binding userInfo.Introduce}" />
</StackPanel>
<FontIcon Grid.Column="2" Glyph="&#xE70F;" />
<themes:ButtonIcon Grid.Column="2" Glyph="&#xE70F;" />
</Grid>
</Border>
<Border
@ -64,9 +74,10 @@
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<styles:TitleSubtitleControl
x:Name="followerText"
Style="{StaticResource TitleSubtitleControlStyle}"
SubtitleText="关注"
TitleText="99" />
TitleText="{Binding userInfo.Follower}" />
<Rectangle
Width="1"
Height="10"
@ -75,9 +86,10 @@
Fill="Gray" />
<styles:TitleSubtitleControl
Name="fansText"
Style="{StaticResource TitleSubtitleControlStyle}"
SubtitleText="粉丝"
TitleText="99" />
TitleText="{Binding userInfo.Fans}" />
<Rectangle
Width="1"
Height="10 "
@ -85,9 +97,10 @@
VerticalAlignment="Center"
Fill="Gray" />
<styles:TitleSubtitleControl
Name="praiseText"
Style="{StaticResource TitleSubtitleControlStyle}"
SubtitleText="获赞"
TitleText="99" />
TitleText="{Binding userInfo.Praise}" />
</StackPanel>
</Border>

View File

@ -1,4 +1,13 @@
using System.Net.Http.Json;
using System.Security.Principal;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RustTools.DataList;
using RustTools.muqing;
using RustTools.Themes;
using RustTools.ViewModels;
// To learn more about WinUI, the WinUI project structure,
@ -11,6 +20,7 @@ namespace RustTools.Views;
/// </summary>
public sealed partial class UserPage : Page
{
public UserSpaceInfo.UserData userInfo { get; set; } = new();
public UserViewModel UserViewModel
{
get; set;
@ -19,5 +29,76 @@ public sealed partial class UserPage : Page
{
UserViewModel = App.GetService<UserViewModel>();
InitializeComponent();
Init();
}
private async void Init()
{
var iniHelper = new IniHelper();
iniHelper.Load(IniHelper.FILE.User);
var account = iniHelper.GetValue(IniHelper.CODE.User, IniHelper.KEY.account);
var token = iniHelper.GetValue(IniHelper.CODE.User, IniHelper.KEY.token);
try
{
var v = await ApiFox.user.loginPc(account, token);
var userSpaceInfo = JsonConvert.DeserializeObject<UserSpaceInfo>(v);
//未登录
if (userSpaceInfo.Code == 0)
{
nulllogin();
}
else
{
await login(account);
}
}
catch (Exception ex)
{
nulllogin();
gj.sc(ex);
}
}
private void nulllogin()
{
gridview.Visibility = Microsoft.UI.Xaml.Visibility.Collapsed;
var loginPage = new LoginPage();
loginPage.LoginSucceeded += LoginPage_LoginSucceeded;
view.Children.Add(loginPage);
}
private async void LoginPage_LoginSucceeded(object sender, string account)
{
// 登录成功后,从 Grid 中移除 LoginPage
view.Children.Remove((LoginPage)sender);
await login(account);
}
public string aaa { get; set; } = "aaa";
private async Task login(string account)
{
var v = await ApiFox.user.SpaceInfo(account);
var userSpaceInfo = JsonConvert.DeserializeObject<UserSpaceInfo>(v);
if (userSpaceInfo != null && userSpaceInfo.Code == 0)
{
var data = userSpaceInfo.Data;
if (data == null) { return; }
data.HeadIcon=data.HeadIcon == string.Empty ? "/Assets/tool.png" : data.HeadIcon.Replace("..", wl.api);
gj.sc(data.HeadIcon);
userInfo = data;
DataContext = this;
}
gridview.Visibility = Microsoft.UI.Xaml.Visibility.Visible;
}
private void MenuFlyoutItemLogout_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
var iniHelper = new IniHelper(IniHelper.FILE.User);
iniHelper.Clean();
iniHelper.Save();
nulllogin();
}
}

View File

@ -10,6 +10,7 @@ public class IniHelper
public class FILE
{
public const string Config = "config.ini";
public const string User = "user.ini";
}
/// <summary>
/// 节
@ -18,6 +19,7 @@ public class IniHelper
{
public const string Settings = "Settings";
public const string Rust = "Rust";
public const string User = "User";
}
public class KEY
@ -25,6 +27,10 @@ public class IniHelper
public const string SystemBackdrop = "SystemBackdrop";
public const string ModFileUrl = "ModFileUrl";//模组路径
public const string MapsFileUrl = "MapsFileUrl";
public const string token = "token";
public const string account = "account";
}
private string filePath = string.Empty;
@ -48,6 +54,17 @@ public class IniHelper
Console.WriteLine($"Loaded value: {value}");
*/
}
public IniHelper(string filePath)
{
Load(filePath);
}
/// <summary>
/// 清空数据
/// </summary>
public void Clean()
{
_sections.Clear();
}
/// <summary>

View File

@ -16,7 +16,7 @@ class wl
/// <para>参数</para>
/// </param>
/// <returns></returns>
public static async Task<string?> postAsync(string url, string[][] parameters)
public static async Task<string> postAsync(string url, string[][] parameters)
{
var client = new RestClient(api);
var request = new RestRequest(url, Method.Post);
@ -30,7 +30,7 @@ class wl
var str = response.Content;
return str;
}
return null;
return string.Empty;
}
/// <summary>