C# Avalonia 程式啟動顯示LOGO視窗(Splash Screen 啟動畫面)

C# Avalonia 程式啟動顯示LOGO視窗(Splash Screen 啟動畫面)

C# Avalonia 程式啟動顯示LOGO視窗(Splash Screen 啟動畫面)


資料來源:https://share.gemini.google/IxlstWADaM02

https://share.gemini.google/9U4vigmzEdLM


SplashScreenWindow.cs

using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;

namespace VPOS_Avalonia;

public partial class SplashScreenWindow : Window
{
    public SplashScreenWindow()
    {
        InitializeComponent();
        // 在視窗初始化時,強制計算並定位到第一螢幕
        MoveToPrimaryScreen();
    }
    private void MoveToPrimaryScreen()
    {
        // 1. 強制關閉自動置中,改由手動座標控制
        this.WindowStartupLocation = WindowStartupLocation.Manual;

        // 2. 取得主螢幕
        var primaryScreen = this.Screens.Primary;
        if (primaryScreen != null)
        {
            var workingArea = primaryScreen.WorkingArea;

            // 3. 取得你在 AXAML 中設定的寬高(若未設定則給預設值)
            double width = double.IsNaN(this.Width) ? 400 : this.Width;
            double height = double.IsNaN(this.Height) ? 250 : this.Height;

            // 4. 考量高 DPI 縮放比例轉換
            int pixelWidth = (int)(width * primaryScreen.Scaling);
            int pixelHeight = (int)(height * primaryScreen.Scaling);

            // 5. 計算置中座標
            int centerX = workingArea.X + (workingArea.Width - pixelWidth) / 2;
            int centerY = workingArea.Y + (workingArea.Height - pixelHeight) / 2;

            this.Position = new PixelPoint(centerX, centerY);
        }
    }
}


SplashScreenWindow.axaml ~ 圓形視窗

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:anim="https://github.com/whistyun/AnimatedImage.Avalonia"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
        x:Class="VPOS_Avalonia.SplashScreenWindow"
        Title="SplashScreenWindow"
        Width="250" Height="250"
        CanResize="False"
        WindowStartupLocation="CenterScreen"
        SystemDecorations="None"
        TransparencyLevelHint="Transparent"
        Background="Transparent">

        <Border Background="#CC2c3e50" CornerRadius="150" ClipToBounds="True">
            <Grid RowDefinitions="*" Margin="10">
                <Image Source="/Assets/vteam_logo.png" HorizontalAlignment="Center" VerticalAlignment="Center"/>
	            <!-- 
		            使用GIF備註 
		            ▲ 在專案目錄(有 .csproj檔案) 開啟『命令提示字元』; dotnet add package AnimatedImage.Avalonia ~~version 1.0.7 (實際執行 把~ 換成 -)
		            ▲ Window 標籤; xmlns:anim="https://github.com/whistyun/AnimatedImage.Avalonia"
		            ▲ 元件使用; <Image Grid.Row="1" Grid.Column="0" Width="95" anim:ImageBehavior.AnimatedSource="avares://VPOS/Assets/wait00.gif"/>
	            -->
	            <Image Width="70" Height="70" anim:ImageBehavior.AnimatedSource="avares://VPOS/Assets/wait00.gif" HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
            </Grid>
        </Border>
</Window>


App.axaml.cs ~ 重點 [public override void OnFrameworkInitializationCompleted()]

using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Primitives;
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Remote.Protocol.Input;
using Avalonia.Styling;
using Avalonia.Themes.Fluent;
using Avalonia.Threading;
using Avalonia.VisualTree;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Tmds.DBus.Protocol;
using VPOS;
using VPOS_Avalonia.ViewModels;
using VPOS_Avalonia.Views;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace VPOS_Avalonia
{
    public partial class App : Application
    {
        //---
        //條件編譯常數宣告區,本區常數設定只要為TRUE 就是跳過該區域的程式碼
#if DEBUG
        //Debug 區看除錯需求進行設定
        public const bool m_blnSkipVerify = false;//是否跳過設備驗證流程
        public const bool m_blnSkipSyncDBData = false;//是否跳過同步資料流程
        public const bool m_blnSkipUpdata = false;//是否跳過上傳資料流程

#else   
        //Release 區一定是FALSE
        public const bool m_blnSkipVerify = false;//是否跳過設備驗證流程
        public const bool m_blnSkipSyncDBData = false;//是否跳過同步資料流程(包含設備註冊流程)直接進入登入畫面,僅供開發測試使用
        public const bool m_blnSkipUpdata = false;//是否跳過上傳資料流程
#endif
        //---條件編譯常數宣告區

        public static SolidColorBrush Background { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush Foreground { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush Selectground { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush Disableground { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush DisableText { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush ActiveTabPageColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush OrderButtonColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush NumberButtonColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush ForegroundReverse { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush ProductButtonColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush CondimentButtonColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush HighlightButtonColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush InformationColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush DevicesTextColor { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush CartTextColor01 { get; private set; } = new(Colors.Transparent);
        public static SolidColorBrush CartTextColor02 { get; private set; } = new(Colors.Transparent);
        public void UpdateExtendedColor(ThemeVariant variant, Color newColor)
        {
            //https://gemini.google.com/share/3be0ccfbd3d1
            // 1. 取得 ThemeDictionaries 集合
            var dictionaries = Application.Current!.Resources.ThemeDictionaries;

            // 2. 嘗試取得對應主題的字典並轉型為 ResourceDictionary
            if (dictionaries.TryGetValue(variant, out var provider) &&
                provider is ResourceDictionary themeDict)
            {
                // 3. 這樣就能使用索引器了
                themeDict["MyExtendedColor"] = new SolidColorBrush(newColor);
            }

            //UpdateExtendedColor(ThemeVariant.Dark, Colors.Green);
            //UpdateExtendedColor(ThemeVariant.Light, Colors.Green);
        }

        public static void SetThemeColor()
        {

            // 1. 定位到特定的主題字典 (以 Dark 模式為例)
            if (Application.Current!.Resources.ThemeDictionaries.TryGetValue(ThemeVariant.Light, out var provider)
                && provider is ResourceDictionary themeDict)
            {
                if (themeDict.TryGetValue("VPOS_Background", out var obj) && obj is ISolidColorBrush s)
                    Background = new SolidColorBrush(s.Color);
                if (themeDict.TryGetValue("VPOS_Foreground", out obj) && obj is ISolidColorBrush s1)
                    Foreground = new SolidColorBrush(s1.Color);
                if (themeDict.TryGetValue("VPOS_Selectground", out obj) && obj is ISolidColorBrush s2)
                    Selectground = new SolidColorBrush(s2.Color);
                if (themeDict.TryGetValue("VPOS_Disableground", out obj) && obj is ISolidColorBrush s3)
                    Disableground = new SolidColorBrush(s3.Color);
                if (themeDict.TryGetValue("VPOS_DisableText", out obj) && obj is ISolidColorBrush s4)
                    DisableText = new SolidColorBrush(s4.Color);
                if (themeDict.TryGetValue("VPOS_ActiveTabPageColor", out obj) && obj is ISolidColorBrush s5)
                    ActiveTabPageColor = new SolidColorBrush(s5.Color);
                if (themeDict.TryGetValue("VPOS_OrderButtonColor", out obj) && obj is ISolidColorBrush s6)
                    OrderButtonColor = new SolidColorBrush(s6.Color);
                if (themeDict.TryGetValue("VPOS_NumberButtonColor", out obj) && obj is ISolidColorBrush s7)
                    NumberButtonColor = new SolidColorBrush(s7.Color);
                if (themeDict.TryGetValue("VPOS_ForegroundReverse", out obj) && obj is ISolidColorBrush s8)
                    ForegroundReverse = new SolidColorBrush(s8.Color);
                if (themeDict.TryGetValue("VPOS_ProductButtonColor", out obj) && obj is ISolidColorBrush s9)
                    ProductButtonColor = new SolidColorBrush(s9.Color);
                if (themeDict.TryGetValue("VPOS_CondimentButtonColor", out obj) && obj is ISolidColorBrush s10)
                    CondimentButtonColor = new SolidColorBrush(s10.Color);
                if (themeDict.TryGetValue("VPOS_HighlightButtonColor", out obj) && obj is ISolidColorBrush s11)
                    HighlightButtonColor = new SolidColorBrush(s11.Color);
                if (themeDict.TryGetValue("VPOS_InformationColor", out obj) && obj is ISolidColorBrush s12)
                    InformationColor = new SolidColorBrush(s12.Color);
                if (themeDict.TryGetValue("VPOS_DevicesTextColor", out obj) && obj is ISolidColorBrush s13)
                    DevicesTextColor = new SolidColorBrush(s13.Color);
                if (themeDict.TryGetValue("VPOS_CartTextColor01", out obj) && obj is ISolidColorBrush s14)
                    CartTextColor01 = new SolidColorBrush(s14.Color);
                if (themeDict.TryGetValue("VPOS_CartTextColor02", out obj) && obj is ISolidColorBrush s15)
                    CartTextColor02 = new SolidColorBrush(s15.Color);

            }
            /*
            var fluentTheme = Application.Current.Styles.OfType<FluentTheme>().FirstOrDefault();

            if (fluentTheme != null)
            {
                // 取得 Light 變體的 Palette
                if (fluentTheme.Palettes.TryGetValue(ThemeVariant.Light, out var palette))
                {
                    // 直接從 Palette 資源中抓取顏色
                    // 注意:這裡拿到的 res 是 Color 結構
                    if (palette is ColorPaletteResources cpr)
                    {
                        var regionColor = cpr.RegionColor;
                        Background = new SolidColorBrush(regionColor);

                        regionColor = cpr.Accent;
                        Selectground = new SolidColorBrush(regionColor);

                        regionColor = cpr.BaseMediumLow;
                        Foreground = new SolidColorBrush(regionColor);

                        regionColor = cpr.BaseLow;
                        Disableground = new SolidColorBrush(regionColor);

                        regionColor = cpr.ErrorText;
                        DisableText = new SolidColorBrush(regionColor);

                        regionColor = cpr.AltMedium;
                        ActiveTabPageColor = new SolidColorBrush(regionColor);

                        regionColor = cpr.ChromeHigh;
                        OrderButtonColor = new SolidColorBrush(regionColor);

                        regionColor = cpr.AltMediumHigh;
                        NumberButtonColor = new SolidColorBrush(regionColor);

                        regionColor = cpr.BaseHigh;
                        ForegroundReverse = new SolidColorBrush(regionColor);

                        regionColor = cpr.ChromeMediumLow;
                        ProductButtonColor = new SolidColorBrush(regionColor);

                        regionColor = cpr.ChromeLow;
                        CondimentButtonColor = new SolidColorBrush(regionColor);

                        regionColor = cpr.ChromeWhite;
                        HighlightButtonColor = new SolidColorBrush(regionColor);
                    }
                }
            }
            */
        }

        public static void ScaleAllFonts(Control parent, double factor,double increment)//遞迴調整所有子控制項的字體大小
        {
            foreach (var child in parent.GetVisualDescendants())
            {
                if (child is Control control)
                {
                    // 嘗試取得該控制項的 FontSize 屬性
                    // 這裡要注意:Avalonia 控制項多數繼承自 TemplatedControl 或 TextBlock
                    if (control is TextBlock tb)
                    {
                        tb.FontSize = tb.FontSize * factor + increment;
                    }
                    else if (control is TemplatedControl tc)
                    {
                        tc.FontSize = tc.FontSize * factor + increment;
                    }
                    else if(control.GetType().GetProperty("FontSize") != null)
                    {
                        // 使用反射來動態調整 FontSize
                        var fontSizeProp = control.GetType().GetProperty("FontSize");
                        if (fontSizeProp != null && fontSizeProp.PropertyType == typeof(double))
                        {
                            double currentSize = (double)fontSizeProp.GetValue(control);
                            fontSizeProp.SetValue(control, currentSize * factor + increment);
                        }
                    }
                }
            }
        }
        public const bool m_blnParentDir = false;//指定系統檔案所在路徑 true:上層目錄 false:同層目錄
        public void DBFilesInit(bool blnInit)//DB實體檔案初始化
        {
            LogFile.CleanLog();
            if (m_blnParentDir)
            {
                FileLib.DeleteFile("..\\vpos.db-shm");
                FileLib.DeleteFile("..\\vpos.db-wal");
                FileLib.DeleteFile("..\\vtcloud_sync.db-shm");
                FileLib.DeleteFile("..\\vtcloud_sync.db-wal");
                FileLib.DeleteFile("..\\takeaways.db-shm");
                FileLib.DeleteFile("..\\takeaways.db-wal");
            }
            else
            {
                FileLib.DeleteFile("vpos.db-shm");
                FileLib.DeleteFile("vpos.db-wal");
                FileLib.DeleteFile("vtcloud_sync.db-shm");
                FileLib.DeleteFile("vtcloud_sync.db-wal");
                FileLib.DeleteFile("takeaways.db-shm");
                FileLib.DeleteFile("takeaways.db-wal");
            }


            if (blnInit)
            {
                //---
                //SQLITE資料庫使用動態產生
                string StrPath = (m_blnParentDir) ? Directory.GetParent(LogFile.m_StrSysPath.Substring(0, LogFile.m_StrSysPath.Length - 1)).FullName + "\\" : LogFile.m_StrSysPath;
                string StrFileNameBuf00 = StrPath + "vpos_def.db";
                string StrFileNameBuf01 = StrPath + "vpos.db";
                if ((File.Exists(StrFileNameBuf00)) && (!File.Exists(StrFileNameBuf01)))
                {
                    File.Copy(StrFileNameBuf00, StrFileNameBuf01, true);
                    LogFile.Write("SystemNormal ; vpos.db Init");
                }
                else
                {
                    if (!File.Exists(StrFileNameBuf00))
                    {
                        LogFile.Write("SystemError ; vpos_def.db missing");
                    }

                    if (!File.Exists(StrFileNameBuf01))
                    {
                        LogFile.Write("SystemError ; vpos.db missing");
                    }
                }

                StrFileNameBuf00 = StrPath + "vtcloud_sync.db";
                if (!File.Exists(StrFileNameBuf00))
                {
                    SQLDataTableModel.CreateSQLiteDatabase(StrFileNameBuf00);
                }

                string strTableName = "upload_data";
                SQLDataTableModel.CreateSQLiteTable(StrFileNameBuf00, strTableName);//建立資料表程式
                LogFile.Write("SystemNormal ; vtcloud_sync.db Init");
                //---SQLITE資料庫使用動態產生

                SyncDBData.DBStructRegulating();//資料庫(DB) 新增資料表 / 新增(補)欄位 / 調整欄位資料型
            }
        }
        //---
        //設備註冊 & 同步資料流程
        public static bool VerifyVLCS(string terminal_sid, string api_token)//驗證設備是否為合法設備
        {
            bool blnResult = false;

            if(m_blnSkipVerify)//條件編譯常數設定為TRUE 就是跳過該區域的程式碼
            {
                blnResult = true;
                return blnResult;
            }

            string StrResult = terminal_dataGet(terminal_sid, api_token);//呼叫 /api/terminal/data API
            StrResult = StrResult.Replace("\"reg_accept_unix_time\":null", "\"reg_accept_unix_time\":0");//防堵WEB輸出JSON的BUG
            get_terminal_data get_terminal_dataBuf = JsonClassConvert.get_terminal_data2Class(StrResult);

            if ((get_terminal_dataBuf != null) && (get_terminal_dataBuf.status == "ACCEPTED") && (get_terminal_dataBuf.data.del_flag == "N") && (get_terminal_dataBuf.data.reg_state == "Y"))
            {
                blnResult = true;
                //---
                //營業日對應運算&判斷機制:
                string Strbusiness_day = ((get_terminal_dataBuf.data.descript != null) && (get_terminal_dataBuf.data.descript.business_day > 0)) ? TimeConvert.UnixTimeStampToDateTime(get_terminal_dataBuf.data.descript.business_day).ToString("yyyy-MM-dd") : DateTime.Now.ToString("yyyy-MM-dd");
                if (SqliteDataAccess.m_terminal_data.Count > 0)
                {
                    DateTime dt1 = VP_Convert.ToDateTime(Strbusiness_day);
                    DateTime dt2 = VP_Convert.ToDateTime(SqliteDataAccess.m_terminal_data[0].business_day);
                    //TimeSpan ts = dt1 - dt2;
                    Strbusiness_day = (string.Compare(dt1.ToString("yyyyMMdd"), dt2.ToString("yyyyMMdd")) == 1) ? Strbusiness_day : SqliteDataAccess.m_terminal_data[0].business_day;
                }
                //---營業日對應運算&判斷機制:

                //---
                //同步terminal_data
                string SQL = string.Format("UPDATE terminal_data SET company_sid='{0}',terminal_name='{1}',app_version='{2}',invoice_active_state='{3}',pos_no='{4}',pid='{5}',rid='{6}',reg_submit_time='{7}',keyhook_enable='{8}',last_order_no='{9}',last_class_report_no='{10}',last_daily_report_no='{11}',client_id='{12}',client_secret='{13}',business_day='{14}',api_token_id='{15}',params='{16}',use_call_num_date='{17}',panel_styles='{18}' WHERE SID='{19}'",
                    get_terminal_dataBuf.data.company_sid,
                    get_terminal_dataBuf.data.terminal_name,
                    get_terminal_dataBuf.data.app_version,
                    get_terminal_dataBuf.data.invoice_active_state,
                    get_terminal_dataBuf.data.pos_no,
                    get_terminal_dataBuf.data.pid,
                    get_terminal_dataBuf.data.rid,
                    get_terminal_dataBuf.data.reg_submit_time,
                    get_terminal_dataBuf.data.keyhook_enable,
                    get_terminal_dataBuf.data.last_order_no,
                    get_terminal_dataBuf.data.last_class_report_no,
                    get_terminal_dataBuf.data.last_daily_report_no,
                    get_terminal_dataBuf.data.client_id,
                    get_terminal_dataBuf.data.client_secret,
                    Strbusiness_day,
                    get_terminal_dataBuf.data.api_token,
                    get_terminal_dataBuf.data.@params,//新增 終端設備資料表 params at 20221020
                    get_terminal_dataBuf.data.use_call_num_date,
                    get_terminal_dataBuf.data.panel_styles,
                    get_terminal_dataBuf.data.terminal_sid);
                SQLDataTableModel.SQLiteInsertUpdateDelete(SQL);
                //MainWindow.m_terminal_panel_styles = JsonClassConvert.terminal_panel_styles2Class(get_terminal_dataBuf.data.panel_styles);
                //---同步terminal_data

                //---
                //更新vpos.vlcs
                VLCS VLCSBuf = new VLCS();
                VLCSBuf.terminal_sid = terminal_sid;
                VLCSBuf.api_token = api_token;
                VLCSBuf.machine_code = MainWindow.m_StrDeviceCode;
                VLCSBuf.check_license_time = TimeConvert.DateTimeToUnixTimeStamp(DateTime.Now);
                VLCSFileUpdate(VLCSBuf);
                //---更新vpos.vlcs

            }

            return blnResult;
        }

        public static void VLCSFileUpdate(VLCS VLCSBuf)
        {
            string StrPath = (m_blnParentDir) ? Directory.GetParent(FileLib.path.Substring(0, FileLib.path.Length - 1)).FullName + "\\" : FileLib.path;
            if (FileLib.IsFileExists("vpos.vlcs"))//vlcs.json
            {
                FileLib.DeleteFile("vpos.vlcs", StrPath, false);
            }

            string StrResult = StringEncrypt.AesEncrypt(JsonClassConvert.VLCS2String(VLCSBuf));
            FileLib.TxtFile("vpos.vlcs", StrPath, StrResult);
        }

        //public static int m_intNetworkLevel = 0;//紀錄網路連線等級 0(網卡不通)、-1(GOOGLE不通)、-2(POS不通)
        public bool IsRegisterDevice()//判斷是否需要註冊設備
        {
            bool blnResult = false;
            string StrLoginInputResult = "";
            LogFile.Write("IsRegisterDevice() start");
            //---
            //判斷vpos.vlcs檔案存在與否與正確性
            if (!FileLib.IsFileExists("vpos.vlcs"))//vlcs.json
            {//檔案不存在
                LogFile.Write("IsRegisterDevice() file not find");

                //if (SqliteDataAccess.m_terminal_data.Count > 0)
                //{
                //    LogFile.Write("IsRegisterDevice() get data for db");
                //    String terminal_sid = SqliteDataAccess.m_terminal_data[0].SID;
                //    String api_token = SqliteDataAccess.m_terminal_data[0].api_token_id;

                //    if (VerifyVLCS(terminal_sid, api_token))//使用DB資料進行驗證
                //    {
                //        blnResult = false;//不用註冊;需要同步更新資料
                //        SyncDBData.Iint(terminal_sid, api_token);
                //    }
                //    else
                //    {//DB資料驗證失敗
                //        LogFile.Write("IsRegisterDevice() not get data for db");
                //        blnResult = true;//需要設備註冊
                //    }
                //}
                //else
                //{//DB沒有資料
                //    LogFile.Write("IsRegisterDevice() not db");
                //    blnResult = true;//需要設備註冊
                //}

                blnResult = true;//需要設備註冊

            }
            else
            {//檔案存在
                LogFile.Write("IsRegisterDevice() get vpos.vlcs");
                string StrVLCS = StringEncrypt.AesDecrypt(FileLib.ReadTxtFile("vpos.vlcs"));
                VLCS VLCSBuf = JsonClassConvert.VLCS2Class(StrVLCS);

                if ((VLCSBuf != null) && (SqliteDataAccess.m_terminal_data != null) && (SqliteDataAccess.m_terminal_data.Count > 0))
                {//有vlcs檔案能用
                    LogFile.Write("IsRegisterDevice() read vpos.vlcs OK");
                    if ((VLCSBuf.terminal_sid == SqliteDataAccess.m_terminal_data[0].SID) && (VLCSBuf.api_token == SqliteDataAccess.m_terminal_data[0].api_token_id))
                    {//與DB資料一致
                        HttpsFun.m_intNetworkLevel = 0;
                        if (HttpsFun.WebRequestTest(ref HttpsFun.m_intNetworkLevel))//判斷是否有網路
                        {
                            string StrResult = terminal_dataGet(VLCSBuf.terminal_sid, VLCSBuf.api_token);//呼叫 /api/terminal/data API
                            StrResult = StrResult.Replace("\"reg_accept_unix_time\":null", "\"reg_accept_unix_time\":0");//防堵WEB輸出JSON的BUG
                            get_terminal_data get_terminal_dataBuf = JsonClassConvert.get_terminal_data2Class(StrResult);
                            if ((get_terminal_dataBuf != null) && (get_terminal_dataBuf.status == "ACCEPTED") && (get_terminal_dataBuf.data.del_flag == "N") && (get_terminal_dataBuf.data.reg_state == "Y"))
                            {
                                //---
                                //營業日對應運算&判斷機制:
                                string Strbusiness_day = ((get_terminal_dataBuf.data.descript != null) && (get_terminal_dataBuf.data.descript.business_day > 0)) ? TimeConvert.UnixTimeStampToDateTime(get_terminal_dataBuf.data.descript.business_day).ToString("yyyy-MM-dd") : DateTime.Now.ToString("yyyy-MM-dd");
                                if (SqliteDataAccess.m_terminal_data.Count > 0)
                                {
                                    DateTime dt1 = VP_Convert.ToDateTime(Strbusiness_day);
                                    DateTime dt2 = VP_Convert.ToDateTime(SqliteDataAccess.m_terminal_data[0].business_day);
                                    //TimeSpan ts = dt1 - dt2;
                                    Strbusiness_day = (string.Compare(dt1.ToString("yyyyMMdd"), dt2.ToString("yyyyMMdd")) == 1) ? Strbusiness_day : SqliteDataAccess.m_terminal_data[0].business_day;
                                }
                                //---營業日對應運算&判斷機制:

                                //---
                                //同步terminal_data
                                string SQL = string.Format("UPDATE terminal_data SET company_sid='{0}',terminal_name='{1}',app_version='{2}',invoice_active_state='{3}',pos_no='{4}',pid='{5}',rid='{6}',reg_submit_time='{7}',keyhook_enable='{8}',last_order_no='{9}',last_class_report_no='{10}',last_daily_report_no='{11}',client_id='{12}',client_secret='{13}',business_day='{14}',api_token_id='{15}',params='{16}',use_call_num_date='{17}',panel_styles='{18}' WHERE SID='{19}'",
                                    get_terminal_dataBuf.data.company_sid,
                                    get_terminal_dataBuf.data.terminal_name,
                                    get_terminal_dataBuf.data.app_version,
                                    get_terminal_dataBuf.data.invoice_active_state,
                                    get_terminal_dataBuf.data.pos_no,
                                    get_terminal_dataBuf.data.pid,
                                    get_terminal_dataBuf.data.rid,
                                    get_terminal_dataBuf.data.reg_submit_time,
                                    get_terminal_dataBuf.data.keyhook_enable,
                                    get_terminal_dataBuf.data.last_order_no,
                                    get_terminal_dataBuf.data.last_class_report_no,
                                    get_terminal_dataBuf.data.last_daily_report_no,
                                    get_terminal_dataBuf.data.client_id,
                                    get_terminal_dataBuf.data.client_secret,
                                    Strbusiness_day,
                                    get_terminal_dataBuf.data.api_token,
                                    get_terminal_dataBuf.data.@params,//新增 終端設備資料表 params at 20221020
                                    get_terminal_dataBuf.data.use_call_num_date,
                                    get_terminal_dataBuf.data.panel_styles,
                                    get_terminal_dataBuf.data.terminal_sid);
                                SQLDataTableModel.SQLiteInsertUpdateDelete(SQL);
                                //MainWindow.m_terminal_panel_styles = JsonClassConvert.terminal_panel_styles2Class(get_terminal_dataBuf.data.panel_styles);
                                //---同步terminal_data

                                blnResult = false;//不用註冊;需要同步更新資料
                                SyncDBData.Iint(VLCSBuf.terminal_sid, VLCSBuf.api_token);
                            }
                            else
                            {//有資料但網路驗證失敗

                                blnResult = true;//需要設備註冊
                            }
                        }
                        else
                        {
                            HttpsFun.m_intNetworkLevel *= -1;//紀錄網路連線等級 0(網卡不通)、-1(GOOGLE不通)、-2(POS不通)
                            blnResult = false;//不需要設備註冊
                        }

                    }
                    else
                    {//vlcs 和 DB資料不一致
                        LogFile.Write("IsRegisterDevice() vpos.vlcs != DB");
                        blnResult = true;//需要設備註冊
                    }
                }
                else
                {//有vlcs檔案但是不能用
                    LogFile.Write("IsRegisterDevice() read vpos.vlcs Fall");

                    blnResult = true;//需要設備註冊 [堵死V1自動升級V2流程(vpos.vlcs 解不開 就要設備註冊)]
                    /*
                    if (SqliteDataAccess.m_terminal_data.Count > 0)
                    {
                        string terminal_sid = SqliteDataAccess.m_terminal_data[0].SID;
                        string api_token = SqliteDataAccess.m_terminal_data[0].api_token_id;

                        if (VerifyVLCS(terminal_sid, api_token))//使用DB資料進行驗證
                        {
                            LogFile.Write("IsRegisterDevice() DB data OK");
                            blnResult = false;//不需要設備註冊
                            SyncDBData.Iint(terminal_sid, api_token);
                        }
                        else
                        {//DB資料驗證失敗
                            LogFile.Write("IsRegisterDevice() DB data Fall");
                            blnResult = true;//需要設備註冊
                        }
                    }
                    else
                    {//DB沒有資料
                        LogFile.Write("IsRegisterDevice() DB has no data");
                        blnResult = true;//需要設備註冊
                    }
                    */
                }
            }
            //---判斷vpos.vlcs檔案存在與否與正確性

            LogFile.Write("IsRegisterDevice() finish");

            return blnResult;

        }

        public static string terminal_dataGet(string Username, string Password)// IsRegisterDevice() / VerifyVLCS()
        {
            //c# httpwebrequest basic authentication
            //https://stackoverflow.com/questions/4334521/httpwebrequest-using-basic-authentication
            //https://zh.wikipedia.org/zh-tw/ISO/IEC_8859-1
            string username = Username;//terminal_sid
            string password = Password;//api_token
            string encoded = System.Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
            HttpsFun.setDomainMode(1);//POS
            string StrResult = HttpsFun.RESTfulAPI_get("/api/terminal/data", "", "Authorization", "Basic " + encoded);
            return StrResult;
        }
        //---設備註冊 & 同步資料流程

        public override void Initialize()
        {
            // 註冊編碼提供者,這樣可以使用 big5 編碼
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            AvaloniaXamlLoader.Load(this);
        }
        public static void ShowLoadingAndLoginUI(IClassicDesktopStyleApplicationLifetime desktop)
        {
            if (HttpsFun.WebRequestTest(ref HttpsFun.m_intNetworkLevel))//判斷是否有網路
            {
                Loading LoadingUI = new Loading();//同步本地端資料庫

                LoadingUI.Closed += (s, e) =>
                {
                    Login LoginUI = new Login();
                    desktop.MainWindow = LoginUI;
                    LoginUI.Closed += (sender, args) =>
                    {
                        if (Login.m_blnCloseApp)
                        {
                            desktop.Shutdown();//應用程式關閉。[WPF]
                        }
                    };
                    LoginUI.Show();
                };

                desktop.MainWindow = LoadingUI;
                LoadingUI.Show();
            }
            else
            {
                Login LoginUI = new Login();
                desktop.MainWindow = LoginUI;
                LoginUI.Closed += (sender, args) =>
                {
                    if (Login.m_blnCloseApp)
                    {
                        desktop.Shutdown();//應用程式關閉。[WPF]
                    }
                };
                LoginUI.Show();
            }
        }

        public static void ShowAuthorizationUI(IClassicDesktopStyleApplicationLifetime desktop)
        {
            InvisibleWindow InvisibleWindowBuf = new InvisibleWindow();
            InvisibleWindowBuf.Closed += (sender, args) =>
            {
                if(InvisibleWindow.m_blnResult)
                {
                    ShowLoadingAndLoginUI(desktop);
                }
                else
                {
                    desktop.Shutdown();//應用程式關閉。[WPF]
                }
            };

            desktop.MainWindow = InvisibleWindowBuf;
        }
        public override void OnFrameworkInitializationCompleted()
        {

            if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
            {
                // 1. 先建立並顯示 Logo 視窗
                var splashWindow = new SplashScreenWindow();
                desktop.MainWindow = splashWindow;
                splashWindow.Show();

                LogFile.Write("App Start");
                DBFilesInit(true);
                HttpsFun.DomainVarInit();
                SqliteDataAccess.m_terminal_data = SqliteDataAccess.terminal_dataLoad();//讀取DB設備參數資料(terminal_data)


                SetThemeColor();// 確保在 Styles 載入後初始化
                desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown;//只有在呼叫了 Shutdown() 時,應用程式才會關閉。[WPF]

                if (!IsRegisterDevice())//判斷是否註冊POS
                {//同步DB
                    ShowLoadingAndLoginUI(desktop);
                }
                else
                {
                    ShowAuthorizationUI(desktop);
                }

                // 4. 切換主視窗並關閉 Logo 視窗
                splashWindow.Close();// 關閉 Logo 視窗
            }

            base.OnFrameworkInitializationCompleted();
        }
    }
}

目的: 使用過場動畫 降低 等待程式啟動的無聊和焦慮

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *