XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

STHApplication

【MAUI】寄当家——安卓端交易管理系统

公开
关注 0 Fork 0 Star 0
UTF-8
using JiDangJia.Services;
using JiDangJia.Core;

namespace JiDangJia.Views;

public sealed class UnlockPage : PrivatePage
{
    private readonly Label message=Ui.Text("",13,Ui.Red);
    private readonly Label dots=Ui.Text("○  ○  ○  ○  ○  ○",27,Ui.Bronze,true);
    private string pin="";
    private bool busy,appeared,visible;
    public UnlockPage()
    {
        Title="账户已锁定";NavigationPage.SetHasNavigationBar(this,false);
        var body=Ui.Stack(Ui.Icon("shield",Ui.Gold,46),Ui.Text(AppProduct.Name+"已锁定",25,bold:true),Ui.Text(AuthClient.Current.Name,14,Ui.Muted));
        if(AppLock.UsesPin)
        {
            dots.HorizontalTextAlignment=TextAlignment.Center;body.Add(Ui.Text("输入 6 位数字密码,输满自动解锁",13,Ui.Muted));body.Add(dots);body.Add(message);
            var keys=new Grid{ColumnDefinitions=[new(GridLength.Star),new(GridLength.Star),new(GridLength.Star)],RowDefinitions=[new(GridLength.Auto),new(GridLength.Auto),new(GridLength.Auto),new(GridLength.Auto)],ColumnSpacing=10,RowSpacing=10};
            string[] labels=["1","2","3","4","5","6","7","8","9","清空","0","删除"];
            for(int i=0;i<labels.Length;i++)
            {
                var key=labels[i];var button=Ui.Button(key,async()=>
                {
                    if(busy)return;if(key=="清空")pin="";else if(key=="删除")pin=pin.Length>0?pin[..^1]:"";else if(pin.Length<6)pin+=key;
                    Draw();if(pin.Length==6)await TryUnlock(pin,false);
                },false);button.HeightRequest=58;button.FontSize=key.Length==1?26:16;SemanticProperties.SetDescription(button,key);keys.Add(button,i%3,i/3);
            }
            body.Add(keys);
        }
        else
        {
            var password=new Entry{IsPassword=true,Placeholder="输入原解锁密码",MaxLength=128};body.Add(password);body.Add(message);body.Add(Ui.Button("密码解锁",()=>TryUnlock(password.Text,false)));
            body.Add(Ui.Text("原解锁密码继续有效,可在设置中改为 6 位数字密码。",11,Ui.Muted));
        }
        if(AppLock.Fingerprint)body.Add(Ui.Button("指纹解锁",()=>TryUnlock(null,true),false));
        body.Add(Ui.Button("忘记解锁密码",async()=>{if(busy)return;var secret=await PasswordDialog.Ask(this,"重置本机解锁","联网验证登录密码后,关闭本账户的本机解锁设置");if(secret is not null)await AppLock.Forgot(secret);},false));
        body.Add(Ui.Button("退出 / 切换账户",async()=>{if(busy)return;AppLock.Abandon();await AuthClient.Current.Logout();LoginPage.ShowLogin();},false));body.Padding=new Thickness(25,35,25,25);Content=new ScrollView{Content=body};
    }
    private void Draw()=>dots.Text=string.Join("  ",Enumerable.Range(0,6).Select(i=>i<pin.Length?"●":"○"));
    private async Task TryUnlock(string? value,bool biometric)
    {
        if(busy)return;busy=true;message.Text="";
        try{await AppLock.Unlock(value,biometric);}
        catch(Exception ex){if(visible){message.Text=biometric?"指纹未验证成功,请输入解锁密码。":ex.Message;pin="";Draw();}}
        finally{busy=false;}
    }
    protected override bool OnBackButtonPressed()=>true;
    protected override async void OnAppearing(){base.OnAppearing();visible=true;if(AuthClient.Current.AccountId.Length==0){AppLock.Abandon();LoginPage.ShowLogin();return;}if(!appeared&&AppLock.Fingerprint){appeared=true;await TryUnlock(null,true);}}
    protected override void OnDisappearing(){visible=false;BiometricUnlock.Cancel();base.OnDisappearing();}
}
public sealed class SecurityPage : PrivatePage
{
    private readonly Action? retire;
    private readonly Label status=Ui.Text("",14,Ui.Bronze);
#if COMMUNITY_APP
    private const string ClearScope="清除此设备本账户的社群草稿、照片缓存和本人可见的服务器聊天记录。方方聊天记录、账号、卡密授权、认证与已发布内容保留。";
    public SecurityPage():this((Action?)null){}
#else
    private const string ClearScope="清除此设备本账户的账目、经营记录、照片、本机自动备份、草稿与缓存。账号与卡密授权保留。外部导出文件需自行删除。";
    public SecurityPage(Database database):this(database.Retire){}
#endif
    private SecurityPage(Action? retire)
    {
        this.retire=retire;Title="密码 / 指纹与数据清除";var first=new Entry{IsPassword=true,Placeholder="设置 6 位数字解锁密码",Keyboard=Keyboard.Numeric,MaxLength=6};var second=new Entry{IsPassword=true,Placeholder="再次输入 6 位数字密码",Keyboard=Keyboard.Numeric,MaxLength=6};var finger=new Switch{OnColor=Ui.Bronze};
        foreach(var entry in new[]{first,second})entry.TextChanged+=(_,_)=>{var digits=new string((entry.Text??"").Where(c=>c is >='0' and <='9').ToArray());if(entry.Text!=digits)entry.Text=digits;};
        var body=Ui.Stack(Ui.Card(Ui.Stack(Ui.Section("本账户的本机解锁"),status,Ui.Text("可自行开启。解锁密码独立于登录密码;退出到后台或重新启动时验证。指纹不可用时使用密码。",12,Ui.Muted),first,second,Ui.Spread(Ui.Text("同时开启指纹 / 设备生物识别"),finger),Ui.Button("开启 / 更新解锁设置",async()=>{await AppLock.Set(first.Text??"",second.Text??"",finger.IsToggled);first.Text=second.Text="";Refresh();}),Ui.Button("关闭解锁设置",async()=>{var password=await PasswordDialog.Ask(this,"关闭本机解锁","输入当前解锁密码");if(password is not null){await AppLock.Disable(password);Refresh();}},false))),Ui.Card(Ui.Stack(Ui.Section("一键清除当前账户数据"),Ui.Text(ClearScope,13,Ui.Muted),Ui.Button("清除所有数据",Clear,false))));body.Padding=18;Content=new ScrollView{Content=body};
    }
    protected override async void OnAppearing(){base.OnAppearing();await AppLock.Load();Refresh();}
    private void Refresh()=>status.Text=AppLock.Enabled?"已开启密码解锁"+(AppLock.Fingerprint?"与指纹解锁":""):"未开启,可自行设置";
    private async Task Clear()
    {
        if(!await DisplayAlertAsync("清除本账户数据",ClearScope+" 清除后无法恢复,继续需两次输入登录密码。","继续","取消"))return;
        var first=await PasswordDialog.Ask(this,"确认清除(1 / 2)","输入登录密码");if(first is null)return;var second=await PasswordDialog.Ask(this,"确认清除(2 / 2)","再次输入登录密码");if(second is null)return;
        await AccountDataClear.Clear(first,second,retire);
    }
}