├── .editorconfig ├── .gitattributes ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── AME.Extensions ├── AME.Extensions.csproj ├── AME.Extensions.xml ├── Directory.Build.props ├── Extensions │ ├── BytesExtensions.cs │ ├── DateExtensions.cs │ ├── EnumExtensions.cs │ ├── FileExtensions.cs │ ├── GlobalExtensions.cs │ ├── IEnumerableExtensions.cs │ ├── IQueryableExtensions.cs │ ├── ImageExtensions.cs │ ├── LambadaExpressionExtensions.cs │ ├── LamdaHelper.cs │ ├── ObjectExtensions.cs │ ├── PathExtensions.cs │ └── StringExtensions.cs ├── Models │ ├── CheckNewResponse.cs │ └── UploadFile.cs ├── README.md └── Utils │ ├── CodePages.cs │ ├── ColorUtil.cs │ ├── ColsName.cs │ ├── ConventUtil.cs │ ├── DebugLog.cs │ ├── DirectoryGet.cs │ ├── GeneralResponse.cs │ ├── HardwareUtil.cs │ ├── HttpClientUtils.cs │ ├── IsTypes.cs │ ├── PrinterErrorHandle.cs │ ├── Reflections.cs │ ├── SerialPortUtils.cs │ ├── Tools.cs │ └── ToolsJson.cs ├── Blazor ├── CommonUtils │ ├── IWebClientInfoProvider.cs │ └── WebClientInfoProvider.cs ├── Components │ ├── AmeBlazorComponentBase.cs │ ├── AmeTabComponentBase.cs │ ├── ComponentEmpty.razor │ ├── ComponentEmpty.razor.cs │ ├── ImgColumn.razor │ ├── ImgColumn.razor.cs │ ├── NavMenuButton │ │ ├── AmeMenu.razor │ │ ├── AmeMenu.razor.css │ │ ├── AmeMenuAuthorize.razor │ │ ├── AmeMenuBase.razor │ │ ├── AmeMenuItem.cs │ │ ├── BigButton.razor │ │ └── BigConfigItem.cs │ ├── NullClass.cs │ ├── TableImgField.cs │ ├── TableLazyHero.razor │ ├── TableLazyHero.razor.cs │ ├── TimerAme.razor │ └── TimerAme.razor.cs ├── Densen.Extensions.BootstrapBlazor.csproj ├── Densen.Extensions.BootstrapBlazor.xml ├── Enums │ └── EnumsGeneral.cs ├── Extensions │ ├── HtmlDirectoryFormatterExtensions.cs │ └── NavigationManagerExtensions.cs ├── Pages │ └── ScanBarcode.razor ├── README.md ├── Services │ ├── BrowserService.cs │ ├── ClipboardService.cs │ ├── DensenServiceCollectionExtensions.cs │ └── LazyHeroDataService.cs ├── _Imports.razor ├── logo.png └── wwwroot │ └── download.js ├── ConsoleTest ├── ConsoleTest.csproj ├── ConsoleTest.xml ├── Program.cs └── Properties │ └── launchSettings.json ├── Demo ├── Antd │ ├── BlazorTest.sln │ └── BlazorTest │ │ ├── AntdBlazor.csproj │ │ ├── AntdBlazor.xml │ │ ├── App.razor │ │ ├── Data │ │ ├── WeatherForecast.cs │ │ └── WeatherForecastService.cs │ │ ├── Pages │ │ ├── Counter.razor │ │ ├── Error.cshtml │ │ ├── Error.cshtml.cs │ │ ├── FetchData.razor │ │ ├── ImportPhoto1.razor │ │ ├── ImportPhoto1.razor.cs │ │ ├── ImportPhoto11.razor │ │ ├── ImportPhoto11.razor.cs │ │ ├── ImportPhoto111.razor │ │ ├── ImportPhoto111.razor.cs │ │ ├── Index.razor │ │ ├── _Host.cshtml │ │ └── _Layout.cshtml │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ ├── NavMenu.razor.css │ │ └── SurveyPrompt.razor │ │ ├── _Imports.razor │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ │ ├── css │ │ │ │ └── open-iconic-bootstrap.min.css │ │ │ │ └── fonts │ │ │ │ ├── open-iconic.eot │ │ │ │ ├── open-iconic.otf │ │ │ │ ├── open-iconic.svg │ │ │ │ ├── open-iconic.ttf │ │ │ │ └── open-iconic.woff │ │ └── site.css │ │ ├── favicon.ico │ │ ├── photo-1.jpg │ │ ├── photo-2.jpg │ │ └── photo-3.jpg ├── DemoBlazorWpfApp │ ├── App.xaml │ ├── App.xaml.cs │ ├── AssemblyInfo.cs │ ├── DemoBlazorWpfApp.csproj │ ├── DemoBlazorWpfApp.xml │ ├── DemoBlazorWpfApp_st51me52_wpftmp.xml │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Services │ │ ├── MyErrorBoundaryLogger.cs │ │ └── SharedServiceCollectionExtensions.cs │ ├── Startup.cs │ ├── _Imports.razor │ ├── appsettings.json │ └── wwwroot │ │ └── index.html ├── DemoLib │ ├── Demo.cs │ ├── DemoLib.csproj │ └── DemoLib.xml ├── DemoPWA │ ├── DemoPWA.csproj │ ├── DemoPWA.xml │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── _Imports.razor │ └── wwwroot │ │ ├── appsettings.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── service-worker.js │ │ └── service-worker.published.js ├── DemoSSR │ ├── .config │ │ └── dotnet-tools.json │ ├── Controllers │ │ ├── AzureController.cs │ │ ├── EchoController.cs │ │ └── SampleController.cs │ ├── DemoSSR.csproj │ ├── DemoSSR.xml │ ├── Pages │ │ ├── Error.cshtml │ │ ├── Error.cshtml.cs │ │ ├── _Host.cshtml │ │ └── _Layout.cshtml │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── _Imports.razor │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ │ ├── fxf5kv2kjka8vfwgvim6.pdf │ │ └── mljq8tr2k29nbrbanmci.pdf ├── DemoShared │ ├── App.razor │ ├── Component │ │ ├── AppComponentBase.cs │ │ └── InputOnKeyup.razor │ ├── DemoShared.csproj │ ├── DemoShared.xml │ ├── Pages │ │ ├── AiFormPage.razor │ │ ├── AiFormPage.razor.cs │ │ ├── AppFiles.razor │ │ ├── AttributeItem.cs │ │ ├── AttributeTable.razor │ │ ├── AzureOpenAIPage.razor │ │ ├── BaiduMapPage.razor │ │ ├── BaiduMapPage.razor.cs │ │ ├── BarcodeGenerators.razor │ │ ├── BarcodeScannerPage.razor │ │ ├── BarcodeScannerPage.razor.cs │ │ ├── BarcodeScannerPageEN.razor │ │ ├── Blazor100 │ │ │ ├── B19LongPressButton.razor │ │ │ ├── B20Gesture.razor │ │ │ ├── EnumGesture.cs │ │ │ ├── GestureComponent.razor │ │ │ └── LongPressButton.razor │ │ ├── BtBatteryLevelPage.razor │ │ ├── BtHeartratePage.razor │ │ ├── BtNotificationPage.razor │ │ ├── BtPrinterPage.razor │ │ ├── CV2Dnn.razor │ │ ├── Charts.razor │ │ ├── Downloads.razor │ │ ├── FilePreviewer.razor │ │ ├── FileSystemPage.razor │ │ ├── FileUpload.razor │ │ ├── FileViewers.razor │ │ ├── Files.razor │ │ ├── GeolocationPage.razor │ │ ├── GeolocationPage.razor.cs │ │ ├── HandwrittenPage.razor │ │ ├── ImageCroppers.razor │ │ ├── ImageHelpers.razor │ │ ├── Index.razor │ │ ├── IpPage.razor │ │ ├── JsBridge.razor │ │ ├── JsBridge.razor.cs │ │ ├── JsBridge.razor.js │ │ ├── MapsPage.razor │ │ ├── MapsPage.razor.cs │ │ ├── MindMaps.razor │ │ ├── MindMaps.razor.cs │ │ ├── MindMaps.razor.css │ │ ├── OcrPage.razor │ │ ├── OcrPage.razor.cs │ │ ├── OfdReaders.razor │ │ ├── OfdReaders.razor.cs │ │ ├── OnScreenKeyboards.razor │ │ ├── OpenAI2Page.razor │ │ ├── OpenAIPage.razor │ │ ├── PdfReaders.razor │ │ ├── PdfReaders.razor.cs │ │ ├── PlayAudioPage.razor │ │ ├── PlayAudioPage.razor.cs │ │ ├── ScreenCapturePage.razor │ │ ├── ScreenCapturePage.razor.cs │ │ ├── ScreenCapturePage.razor.css │ │ ├── ScreenOrientations.razor │ │ ├── ScreenRecords.razor │ │ ├── ShareObject.razor │ │ ├── SignaturePadPage.razor │ │ ├── SignaturePadPageResponsive.razor │ │ ├── SignaturePadPageResponsive.razor.cs │ │ ├── Speechs.razor │ │ ├── Storages.razor │ │ ├── Storages.razor.cs │ │ ├── TableLazyHeroPage.razor │ │ ├── TableLazyHeroPage.razor.cs │ │ ├── Test │ │ │ ├── TestCanvas.razor │ │ │ ├── TestIframe2.razor │ │ │ ├── TestOcrPage.razor │ │ │ ├── TestOcrPage.razor.cs │ │ │ ├── Testcodes.razor │ │ │ └── Testcodes.razor.cs │ │ ├── TimerAmePage.razor │ │ ├── TranslatePage.razor │ │ ├── UploadToBase64s.razor │ │ ├── UploadToBase64s.razor.cs │ │ ├── VideoPlayers.razor │ │ ├── VideoWall.razor │ │ ├── ViewerPage.razor │ │ ├── ViewerjsFull.razor │ │ ├── WebApiPage.razor │ │ ├── WebApiPage.razor.cs │ │ ├── WebSerialPage.razor │ │ ├── WebSerialPage.razor.cs │ │ ├── WebSerialPage.razor.css │ │ ├── WxQrCodes.razor │ │ └── btPrinterPage.razor.css │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ ├── NavMenu.razor.cs │ │ └── NavMenu.razor.js │ ├── UtilityChart.cs │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ ├── font-awesome.min.css │ │ └── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ ├── css │ │ │ └── open-iconic-bootstrap.min.css │ │ │ └── fonts │ │ │ ├── open-iconic.eot │ │ │ ├── open-iconic.otf │ │ │ ├── open-iconic.svg │ │ │ ├── open-iconic.ttf │ │ │ └── open-iconic.woff │ │ ├── favicon.ico │ │ ├── icon-192.png │ │ ├── icon-512.png │ │ ├── manifest.json │ │ ├── samples │ │ ├── qr1.jpg │ │ ├── sample.docx │ │ ├── sample.ofd │ │ ├── sample.pdf │ │ ├── sample.xlsx │ │ ├── sample2.docx │ │ ├── sample2.ofd │ │ ├── sample2.pdf │ │ ├── sample2.xlsx │ │ └── sample3.xlsx │ │ └── test.jpg ├── Receive_DSP.ino ├── Wpf7WithWebview2 │ ├── App.xaml │ ├── App.xaml.cs │ ├── AssemblyInfo.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ └── Wpf7WithWebview2.csproj └── logo.png ├── Densen.Component.Blazor ├── BaiduMap.md ├── BarcodeScanner.md ├── Bluetooth.md ├── Components │ ├── BarcodeScanner.razor │ └── Handwritten.razor ├── Densen.Component.Blazor.csproj ├── Densen.Component.Blazor.xml ├── Directory.Build.props ├── Extensions │ └── ServerSideBlazorExtensions.cs ├── Geolocation.md ├── Handwritten.md ├── Map.md ├── OCR.md ├── OnScreenKeyboard.md ├── README.md ├── README.nuget.md ├── README.zh-CN.md ├── SignaturePad.md ├── Viewerjs.md ├── WebAPI.md ├── _Imports.razor └── wwwroot │ ├── lib │ ├── handwritten │ │ ├── handwritten.css │ │ └── handwritten.js │ └── zxing │ │ ├── qrcode.min.js │ │ ├── zxing.min.js │ │ └── zxingjs.js │ └── logo.png ├── Densen.Extensions.SC.sln ├── Densen.Extensions.sln ├── Directory.Build.props ├── HtmlDirectoryFormatterExtensions ├── AME.SortedDirectoryChs.csproj ├── AME.SortedDirectoryChs.xml ├── Directory.Build.props ├── HtmlDirectoryFormatterExtensions.cs └── README.md ├── LICENSE ├── PropertiesTools ├── Program.cs └── PropertiesTools.csproj ├── README.Nuget.md ├── README.md ├── README.zh-CN.md ├── WinFormsApp1 ├── FileViewer.Designer.cs ├── FileViewer.cs ├── FileViewer.resx ├── Form1.Designer.cs ├── Form1.cs └── WinFormsApp1.csproj ├── keys └── Longbow.Utility.snk └── logo.png /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": ".NET Core Launch (web)", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "build", 12 | "program": "${workspaceFolder}/Demo/DemoSSR/bin/Debug/net6.0/DemoSSR.dll", 13 | "args": [], 14 | "cwd": "${workspaceFolder}/Demo/DemoSSR", 15 | "stopAtEntry": false, 16 | "serverReadyAction": { 17 | "action": "openExternally", 18 | "pattern": "\\bNow listening on:\\s+(https?://\\S+)" 19 | }, 20 | "env": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | }, 23 | "sourceFileMap": { 24 | "/Views": "${workspaceFolder}/Views" 25 | } 26 | }, 27 | { 28 | "name": ".NET Core Attach", 29 | "type": "coreclr", 30 | "request": "attach" 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/Demo/DemoSSR/DemoSSR.csproj", 11 | "/property:GenerateFullPaths=true", 12 | "/consoleloggerparameters:NoSummary" 13 | ], 14 | "problemMatcher": "$msCompile" 15 | }, 16 | { 17 | "label": "publish", 18 | "command": "dotnet", 19 | "type": "process", 20 | "args": [ 21 | "publish", 22 | "${workspaceFolder}/Demo/DemoSSR/DemoSSR.csproj", 23 | "/property:GenerateFullPaths=true", 24 | "/consoleloggerparameters:NoSummary" 25 | ], 26 | "problemMatcher": "$msCompile" 27 | }, 28 | { 29 | "label": "watch", 30 | "command": "dotnet", 31 | "type": "process", 32 | "args": [ 33 | "watch", 34 | "run", 35 | "${workspaceFolder}/Demo/DemoSSR/DemoSSR.csproj", 36 | "/property:GenerateFullPaths=true", 37 | "/consoleloggerparameters:NoSummary" 38 | ], 39 | "problemMatcher": "$msCompile" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /AME.Extensions/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AME.Extensions/Extensions/IEnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System.Collections; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | 11 | namespace AME; 12 | 13 | /// 14 | /// IEnumerable 扩展方法 15 | /// 16 | 17 | 18 | public static class IEnumerableExtensions 19 | { 20 | public static IEnumerable Append(this IEnumerable first, params object[] second) 21 | { 22 | return first.OfType().Concat(second); 23 | } 24 | public static IEnumerable Append(this IEnumerable first, params T[] second) 25 | { 26 | return first.Concat(second); 27 | } 28 | public static IEnumerable Prepend(this IEnumerable first, params object[] second) 29 | { 30 | return second.Concat(first.OfType()); 31 | } 32 | public static IEnumerable Prepend(this IEnumerable first, params T[] second) 33 | { 34 | return second.Concat(first); 35 | } 36 | } 37 | 38 | /// 39 | /// Array 扩展方法 40 | /// 41 | 42 | 43 | public static class ArrayExtensions 44 | { 45 | public static object[] Append(this object[] first, params object[] second) => second == null ? first : first.ToList().OfType().Concat(second.ToList()).ToArray(); 46 | 47 | public static T[] Append(this T[] first, params T[] second) => second == null ? first : first?.ToList().Concat(second.ToList()).ToArray(); 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /AME.Extensions/Models/CheckNewResponse.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AME.Models; 8 | 9 | 10 | public class CheckNewResponse 11 | { 12 | /// 13 | /// 文件名,带相对路径 14 | /// 15 | public string Filename { get; set; } 16 | 17 | /// 18 | /// 文件版本 19 | /// 20 | public string Version { get; set; } 21 | 22 | /// 23 | /// 文件大小 24 | /// 25 | public string Size { get; set; } 26 | 27 | /// 28 | /// 建立时间 29 | /// 30 | public string CreationTime { get; set; } 31 | 32 | /// 33 | /// 刷新时间 34 | /// 35 | public string LasFetch { get; set; } 36 | } 37 | -------------------------------------------------------------------------------- /AME.Extensions/Models/UploadFile.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AME.Models; 8 | 9 | // 上传组件返回类 10 | public class UploadFile 11 | { 12 | 13 | // 14 | // 摘要: 15 | // 获得/设置 文件名 16 | public string FileName { get; set; } 17 | // 18 | // 摘要: 19 | // 获得/设置 原始文件名 20 | public string OriginFileName { get; } 21 | // 22 | // 摘要: 23 | // 获得/设置 文件大小 24 | public long Size { get; set; } 25 | // 26 | // 摘要: 27 | // 获得/设置 文件上传结果 0 表示成功 非零表示失败 28 | public int Code { get; set; } 29 | // 30 | // 摘要: 31 | // 获得/设置 文件预览地址 32 | public string PrevUrl { get; set; } 33 | // 34 | // 摘要: 35 | // 获得/设置 错误信息 36 | public string Error { get; set; } 37 | } 38 | -------------------------------------------------------------------------------- /AME.Extensions/README.md: -------------------------------------------------------------------------------- 1 | Densen的.net常用扩展库 -------------------------------------------------------------------------------- /AME.Extensions/Utils/CodePages.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System; 8 | using System.Linq; 9 | 10 | namespace AME 11 | { 12 | public partial class ConventUtil 13 | { 14 | //var str = @"C:\Users\Alex\Documents\Tencent Files\239548611\FileRecv\刪除面.mac"; 15 | //var files = File.ReadAllBytes(str); 16 | //ConventUtil.IsGB2312(files); 17 | 18 | public static bool IsGB2312(byte[] bytes) 19 | { 20 | for (int i = 0; i < bytes.Length; i += 2) 21 | { 22 | var x = bytes.Skip(i).Take(2).ToArray(); 23 | IsGB23122(x); 24 | } 25 | return true; 26 | } 27 | public static bool IsGB23122(byte[] bytes) 28 | { 29 | //在C#中,可以使用System.Text.Encoding类来判断一个中文字符串的编码是BIG5还是GB2312。具体实现方法如下: 30 | 31 | //1. 首先将中文字符串转换为字节数组: 32 | 33 | //byte[] bytes = System.Text.Encoding.Default.GetBytes(str); 34 | 35 | //2. 判断字节数组的前两个字节是否符合BIG5编码或GB2312编码的规范: 36 | 37 | if (bytes[0] >= 0x81 && bytes[0] <= 0xFE && bytes[1] >= 0x40 && bytes[1] <= 0x7E || bytes[1] >= 0xA1 && bytes[1] <= 0xFE) 38 | { 39 | // 是BIG5编码 40 | Console.WriteLine("是BIG5编码"); 41 | 42 | } 43 | else if (bytes[0] >= 0xB0 && bytes[0] <= 0xF7 && bytes[1] >= 0xA1 && bytes[1] <= 0xFE) 44 | { 45 | // 是GB2312编码 46 | Console.WriteLine("是GB2312编码"); 47 | } 48 | else 49 | { 50 | // 不是BIG5编码也不是GB2312编码 51 | Console.WriteLine("其他编码"); 52 | } 53 | 54 | //以上代码中,判断BIG5编码的规范是第一个字节在0x81到0xFE之间,第二个字节在0x40到0x7E之间或在0xA1到0xFE之间;判断GB2312编码的规范是第一个字节在0xB0到0xF7之间,第二个字节在0xA1到0xFE之间。如果不符合以上两种编码的规范,则认为不是BIG5编码也不是GB2312编码。 55 | 56 | return true; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /AME.Extensions/Utils/ColsName.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System; 8 | 9 | namespace AME.Util 10 | { 11 | public static class ColsName 12 | { 13 | 14 | //C# Excel数字转字母列标 15 | public static string 数字转字母列标(int index) 16 | { 17 | var dividend = index; 18 | var columnName = string.Empty; 19 | 20 | while (dividend > 0) 21 | { 22 | var modulo = (dividend - 1) % 26; 23 | columnName = Convert.ToChar(65 + modulo) + columnName; 24 | dividend = (dividend - modulo) / 26; 25 | } 26 | 27 | return columnName; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /AME.Extensions/Utils/DebugLog.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System; 8 | 9 | namespace AME 10 | { 11 | public class DebugLog 12 | { 13 | 14 | internal static bool ConsoleWriteLine = false; 15 | public static void Log(string LogStr, string tag1 = "") 16 | { 17 | if (ConsoleWriteLine) Log($"时间 {DateTime.Now} : {LogStr} , Tag {tag1} "); 18 | } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /AME.Extensions/Utils/DirectoryGet.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System; 8 | using System.Collections; 9 | using System.Collections.Generic; 10 | using System.Diagnostics; 11 | using System.IO; 12 | 13 | namespace DirectoryGet; 14 | 15 | public class Library : IEnumerable 16 | { 17 | 18 | // warning IL3000: 'System.Reflection.Assembly.Loc 19 | // ation' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is 20 | // needed, consider calling 'System.AppContext.BaseDirectory'. 21 | public IEnumerator GetEnumerator() 22 | { 23 | yield return $"{Environment.CurrentDirectory}"; 24 | yield return $"{Directory.GetCurrentDirectory()}"; 25 | yield return $"{GetType().Assembly.Location}"; 26 | yield return $"{Process.GetCurrentProcess().MainModule.FileName}"; 27 | yield return $"{AppDomain.CurrentDomain.BaseDirectory}"; 28 | } 29 | 30 | IEnumerator IEnumerable.GetEnumerator() 31 | { 32 | return GetEnumerator(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /AME.Extensions/Utils/GeneralResponse.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System; 8 | using System.Linq; 9 | 10 | namespace AME.Base; 11 | #nullable enable 12 | #pragma warning disable CA1416 // #warning 指令 13 | 14 | 15 | public class GeneralResponse 16 | { 17 | public int Code { get; set; } 18 | public string? Message { get; set; } 19 | } 20 | -------------------------------------------------------------------------------- /AME.Extensions/Utils/IsTypes.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System; 8 | 9 | namespace AME.Extensions 10 | { 11 | public class IsTypes 12 | { 13 | public static bool IsNumericType(Type o) 14 | { 15 | var Nullabletypeget = Nullable.GetUnderlyingType(o); 16 | o = Nullabletypeget ?? o; 17 | if (o.FullName.Contains("Enum")) 18 | return false; 19 | var typeget = Type.GetTypeCode(o); 20 | return typeget switch 21 | { 22 | TypeCode.Byte or TypeCode.SByte or TypeCode.UInt16 or TypeCode.UInt32 or TypeCode.UInt64 or TypeCode.Int16 or TypeCode.Int32 or TypeCode.Int64 or TypeCode.Decimal or TypeCode.Double or TypeCode.Single => true, 23 | _ => false, 24 | }; 25 | } 26 | 27 | public static bool IsNumericTypeObj(object o) 28 | { 29 | var Nullabletypeget = Nullable.GetUnderlyingType(o.GetType()); 30 | var typeget = Type.GetTypeCode(Nullabletypeget ?? o.GetType()); 31 | return typeget switch 32 | { 33 | TypeCode.Byte or TypeCode.SByte or TypeCode.UInt16 or TypeCode.UInt32 or TypeCode.UInt64 or TypeCode.Int16 or TypeCode.Int32 or TypeCode.Int64 or TypeCode.Decimal or TypeCode.Double or TypeCode.Single => true, 34 | _ => false, 35 | }; 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /AME.Extensions/Utils/PrinterErrorHandle.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using AME.Base; 8 | using System; 9 | using System.Linq; 10 | 11 | namespace AME.Util; 12 | #nullable enable 13 | #pragma warning disable CA1416 // #warning 指令 14 | 15 | public class PrinterError: GeneralResponse 16 | { 17 | public string? Printer { get; set; } 18 | 19 | public static PrinterError GetMessage(string message, bool isH5 = true) 20 | { 21 | var error = new PrinterError(); 22 | if (message.Contains("code=")) 23 | { 24 | //ERR:code={ex.HResult},message={ex.Message},printer={ipadress1} 25 | var errs = message.TrimStart(' ').Replace("ERR:", "").Split(','); 26 | try 27 | { 28 | error.Message = errs.First(a => a.StartsWith("message=")).Split('=')[1]; 29 | } 30 | catch { } 31 | try 32 | { 33 | error.Printer = errs.First(a => a.StartsWith("printer=")).Split('=')[1]; 34 | } 35 | catch { } 36 | try 37 | { 38 | var _code = errs.First(a => a.StartsWith("code=")).Split('=')[1]; 39 | error.Code = Convert.ToInt32(_code); 40 | error.Message = error.Code switch 41 | { 42 | //IP地址无法连通 43 | 10001 => $"打印机网线未连接.\n({error.Message})", 44 | -2147467259 => $"打印机网线未连接.\n({error.Message})", 45 | _ => $"{error.Message}\n{error.Printer}\n{error.Code}", 46 | }; 47 | } 48 | catch { } 49 | 50 | error.Message ??= message; 51 | 52 | if (isH5) 53 | { 54 | error.Message = error.Message.Replace("\n", "
"); 55 | } 56 | } 57 | else if (message.Contains("ERR:")) 58 | { 59 | error.Message ??= message; 60 | if (isH5) 61 | { 62 | error.Message = error.Message.Replace("\n", "
"); 63 | } 64 | } 65 | return error; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Blazor/CommonUtils/IWebClientInfoProvider.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AME.CommonUtils; 8 | 9 | public interface IWebClientInfoProvider 10 | { 11 | string? BrowserInfo { get; } 12 | string? ClientIpAddress { get; } 13 | string? ComputerName { get; } 14 | } 15 | -------------------------------------------------------------------------------- /Blazor/CommonUtils/WebClientInfoProvider.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.Extensions.Logging; 9 | using System.Net; 10 | 11 | namespace AME.CommonUtils; 12 | 13 | 14 | public class WebClientInfoProvider : IWebClientInfoProvider 15 | { 16 | public string? BrowserInfo => GetBrowserInfo(); 17 | public string? ClientIpAddress => GetClientIpAddress(); 18 | public string? ComputerName => GetComputerName(); 19 | 20 | public ILogger? Logger; 21 | private readonly IHttpContextAccessor _httpContextAccessor; 22 | private readonly HttpContext _httpContext; 23 | /// 24 | /// Creates a new 25 | /// 26 | public WebClientInfoProvider(IHttpContextAccessor httpContextAccessor)//, ILogger logger) 27 | { 28 | _httpContextAccessor = httpContextAccessor; 29 | _httpContext = httpContextAccessor.HttpContext; 30 | //Logger = logger; 31 | } 32 | protected virtual string? GetBrowserInfo() 33 | { 34 | var httpContext = _httpContextAccessor.HttpContext ?? _httpContext; 35 | return httpContext?.Request?.Headers?["User-Agent"]; 36 | } 37 | protected virtual string? GetClientIpAddress() 38 | { 39 | try 40 | { 41 | var httpContext = _httpContextAccessor.HttpContext ?? _httpContext; 42 | 43 | var headers = httpContext?.Request.Headers; 44 | if (httpContext !=null && headers != null && headers.ContainsKey("X-Forwarded-For")) 45 | { 46 | httpContext.Connection.RemoteIpAddress = IPAddress.Parse(headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[0]); 47 | } 48 | return httpContext?.Connection?.RemoteIpAddress?.ToString(); 49 | } 50 | catch (Exception) 51 | { 52 | //Logger.LogWarning(ex.ToString()); 53 | } 54 | return null; 55 | } 56 | protected virtual string? GetComputerName() 57 | { 58 | return null; //TODO: Implement! 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Blazor/Components/ComponentEmpty.razor: -------------------------------------------------------------------------------- 1 | @namespace AmeBlazor.Components 2 | -------------------------------------------------------------------------------- /Blazor/Components/ComponentEmpty.razor.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AmeBlazor.Components; 8 | 9 | public partial class Empty 10 | { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Blazor/Components/ImgColumn.razor: -------------------------------------------------------------------------------- 1 | @namespace AmeBlazor.Components 2 | 3 |
4 |
5 | 6 |
7 |
8 |
@Name
9 |
@Title
10 |
11 |
12 | 13 | -------------------------------------------------------------------------------- /Blazor/Components/ImgColumn.razor.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Components; 8 | 9 | namespace AmeBlazor.Components; 10 | 11 | public partial class ImgColumn : ComponentBase 12 | { 13 | [Parameter] public string? Url { get; set; } 14 | [Parameter] public string? BaseUrl { get; set; } = ""; 15 | [Parameter] public string? Name { get; set; } = "Name"; 16 | [Parameter] public string? Title { get; set; } = "Title"; 17 | [Parameter] public string Style { get; set; } = "max-height:50px;max-width:50px;"; 18 | 19 | protected override void OnInitialized() 20 | { 21 | base.OnInitialized(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Blazor/Components/NavMenuButton/AmeMenu.razor: -------------------------------------------------------------------------------- 1 | @namespace AmeBlazor.Components 2 | 3 | @if (Items != null) 4 | { 5 | @foreach (var menu in Items) 6 | { 7 | 21 | } 22 | } 23 | 24 | @code { 25 | [Parameter] public List? Items { get; set; } 26 | 27 | private bool collapseNavMenu = true; 28 | private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; 29 | 30 | private void ToggleNavMenu() => collapseNavMenu = !collapseNavMenu; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Blazor/Components/NavMenuButton/AmeMenu.razor.css: -------------------------------------------------------------------------------- 1 | .collapse:not(.show) { 2 | display: none 3 | } 4 | 5 | .collapsing { 6 | height: 0; 7 | overflow: hidden; 8 | transition: height .35s ease 9 | } 10 | 11 | .nav-toggler { 12 | /* background-color: rgba(255, 255, 255, 0.1); 13 | */ position: absolute; 14 | right: 8px; 15 | margin-top: -36px; 16 | } 17 | 18 | .nav-menu { 19 | /* background-color: rgba(255, 255, 255, 0.1); 20 | */} -------------------------------------------------------------------------------- /Blazor/Components/NavMenuButton/AmeMenuAuthorize.razor: -------------------------------------------------------------------------------- 1 | @namespace AmeBlazor.Components 2 | 3 | @if (string.IsNullOrEmpty(Roles)) 4 | { 5 | 6 | } 7 | else if (Roles == "") 8 | { 9 | 10 | 11 | 12 | 13 | 14 | } 15 | else 16 | { 17 | 18 | 19 | 20 | 21 | 22 | } 23 | 24 | @code { 25 | 26 | [Parameter] public List? Items { get; set; } 27 | [Parameter] public string? Roles { get; set; } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Blazor/Components/NavMenuButton/AmeMenuBase.razor: -------------------------------------------------------------------------------- 1 | @namespace AmeBlazor.Components 2 | 3 | 4 | @Text 5 | 6 | 7 | @code { 8 | 9 | [Parameter] public string? Link { get; set; } 10 | [Parameter] public string? Text { get; set; } 11 | [Parameter] public NavLinkMatch Match { get; set; } 12 | [Parameter] public BootstrapDynamicComponent? Component { get; set; } 13 | 14 | } -------------------------------------------------------------------------------- /Blazor/Components/NavMenuButton/AmeMenuItem.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Components.Routing; 8 | 9 | namespace AmeBlazor.Components; 10 | 11 | public class AmeMenuItem 12 | { 13 | public string? Link { get; set; } 14 | public string? Text { get; set; } 15 | public NavLinkMatch Match { get; set; } 16 | public string? AuthorizeRoles { get; set; } 17 | public List? SubItems { get; set; } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Blazor/Components/NavMenuButton/BigButton.razor: -------------------------------------------------------------------------------- 1 | @inherits AmeBlazorComponentBase 2 | @namespace AmeBlazor.Components 3 | 4 | 8 | 9 | @code{ 10 | 11 | /// 12 | /// 获得/设置 组件 class 13 | /// 14 | /// 默认 "card col-sm-6 col-md-4 col-lg-2 card bg-light text-dark" 15 | /// 16 | [Parameter] 17 | public string Class { get; set; } = "card col-sm-6 col-md-4 col-lg-2 card bg-light text-dark"; 18 | 19 | /// 20 | /// 获得/设置 组件 oi 图标默认 oi oi-book 21 | /// 22 | [Parameter] 23 | public string ClassOi { get; set; } = "oi oi-book"; 24 | 25 | /// 26 | /// 获得/设置 组件 跳转的Url 27 | /// 28 | [Parameter] 29 | public string? Url { get; set; } 30 | 31 | /// 32 | /// 获得/设置 组件显示文本 33 | /// 34 | [Parameter] 35 | public string? Text { get; set; } 36 | 37 | /// 38 | /// 获得/设置 按钮高度默认120px 39 | /// 40 | [Parameter] 41 | public int Height { get; set; } = 120; 42 | 43 | /// 44 | /// 获得/设置 按钮高度默认200px 45 | /// 46 | [Parameter] 47 | public int MaxWidth { get; set; } = 200; 48 | 49 | /// 50 | /// 获得/设置 组件 跳转是否开新窗口 51 | /// 52 | [Parameter] 53 | public bool NewTab { get; set; } 54 | 55 | Task gotoUrl() 56 | { 57 | if (string.IsNullOrEmpty(Url)) return Task.CompletedTask; 58 | if (NewTab) GotoNewTab(Url); 59 | else Goto(Url); 60 | return Task.CompletedTask; 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /Blazor/Components/NavMenuButton/BigConfigItem.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AmeBlazor.Components; 8 | 9 | public enum ConfigItemType 10 | { 11 | Button, 12 | Checkbox, 13 | Inputbox 14 | } 15 | 16 | 17 | public class BigConfigItem 18 | { 19 | /// 20 | /// 组件类型 21 | /// 22 | public ConfigItemType ItemType { get; set; } = ConfigItemType.Button; 23 | 24 | /// 25 | /// 组件 class 26 | /// 27 | public string? Class { get; set; } 28 | 29 | /// 30 | /// 组件 oi 图标,InputBox,CHeckBox无效 31 | /// 32 | public string? ClassOi { get; set; } 33 | 34 | /// 35 | /// 组件Style, Button无效 36 | /// 37 | public string? Style { get; set; } 38 | 39 | /// 40 | /// 组件显示文本 41 | /// 42 | public string? Text { get; set; } 43 | 44 | /// 45 | /// 绑定字段名称, Button无效 46 | /// 47 | public string? FiledName { get; set; } 48 | 49 | /// 50 | /// Button跳转Url,InputBox,CHeckBox无效 51 | /// 52 | public string? Url { get; set; } 53 | 54 | /// 55 | /// 按钮高度默认120px 56 | /// InputBox,CheckBox无效 57 | /// 58 | public int Height { get; set; } = 120; 59 | 60 | /// 61 | /// 按钮高度默认200px 62 | /// InputBox,CheckBox无效 63 | /// 64 | public int MaxWidth { get; set; } = 200; 65 | 66 | /// 67 | /// 授权列表 68 | /// 69 | public string[]? Roles { get; set; } 70 | } 71 | -------------------------------------------------------------------------------- /Blazor/Components/NullClass.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AmeBlazor.Components; 8 | 9 | /// 10 | /// 一个假的类 11 | /// 12 | public class NullClass 13 | { 14 | public int ID { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /Blazor/Components/TableImgField.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Components; 8 | 9 | namespace AmeBlazor.Components; 10 | 11 | /// 12 | /// 表格图片列 13 | /// 14 | public class TableImgField 15 | { 16 | public bool Render { get; set; } 17 | public Type FieldType { get; set; } = typeof(string); 18 | public string Field { get; set; } = "Photo"; 19 | public string? ColumnText { get; set; } 20 | public string? Title { get; set; } 21 | public string? Name { get; set; } 22 | public string? BaseUrl { get; set; } 23 | public string? Style { get; set; } 24 | 25 | public EventCallback Callback { get; set; } 26 | 27 | /// 28 | /// 获得/设置 识别完成回调方法,返回 Model 集合 29 | /// 30 | public Func? CallbackFunc { get; set; } 31 | } 32 | -------------------------------------------------------------------------------- /Blazor/Components/TimerAme.razor: -------------------------------------------------------------------------------- 1 | @namespace AmeBlazor.Components 2 |

@Label @DateTime.Now.ToLongTimeString()

-------------------------------------------------------------------------------- /Blazor/Components/TimerAme.razor.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Components; 8 | 9 | namespace AmeBlazor.Components; 10 | 11 | public partial class TimerAme : ComponentBase, IDisposable 12 | { 13 | [Parameter] 14 | public string Label { get; set; } = "时间:"; 15 | 16 | private CancellationTokenSource? AutoRefreshCancelTokenSource { get; set; } 17 | 18 | protected override void OnInitialized() => worker(); 19 | 20 | /// 21 | /// Dispose 方法 22 | /// 23 | public void Dispose() => AutoRefreshCancelTokenSource = null; 24 | 25 | public void worker() 26 | { 27 | AutoRefreshCancelTokenSource = new CancellationTokenSource(); 28 | _ = Task.Run(async () => 29 | { 30 | try 31 | { 32 | while (!(AutoRefreshCancelTokenSource?.IsCancellationRequested ?? true)) 33 | { 34 | await InvokeAsync(StateHasChanged); 35 | await Task.Delay(TimeSpan.FromSeconds(1), AutoRefreshCancelTokenSource?.Token ?? new CancellationToken(true)); 36 | } 37 | } 38 | catch (TaskCanceledException) { } 39 | }); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Blazor/Enums/EnumsGeneral.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AME; 8 | 9 | public partial class EnumsExtensions 10 | { 11 | 12 | public enum ShowToolbarType 13 | { 14 | 无, 15 | 导入Excel, 16 | 执行添加, 17 | 导出, 18 | 升级, 19 | 刷新, 20 | 打印, 21 | } 22 | public enum ShowDetailRowType 23 | { 24 | 表内明细, 25 | 弹窗, 26 | 图片列, 27 | 选项卡, 28 | 表内明细II, 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Blazor/Extensions/NavigationManagerExtensions.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.JSInterop; 8 | 9 | namespace AmeBlazor.Components; 10 | 11 | 12 | 13 | /// 14 | /// 15 | /// 16 | public static class NavigationManagerExtensions 17 | { 18 | 19 | /// 20 | /// 导航或打开新页面方法 21 | /// 22 | /// 23 | /// 24 | public static async void NavigateToNewTab(this IJSRuntime JsRuntime, string url) 25 | { 26 | if (JsRuntime != null) 27 | { 28 | await JsRuntime.InvokeAsync("open", new object[2] { url, "_blank" }); 29 | } 30 | } 31 | 32 | ///// 33 | ///// 导航或打开新页面方法 34 | ///// 35 | ///// 36 | ///// 37 | //public static async void NavigateToNewTab(this NavigationManager Navigation, string url) 38 | //{ 39 | // var JsRuntime = BootstrapBlazor.Components.ServiceProviderHelper.ServiceProvider.GetRequiredService(); 40 | // if (JsRuntime != null) 41 | // { 42 | // await JsRuntime.InvokeAsync("open", new object[2] { url, "_blank" }); 43 | // } 44 | //} 45 | } 46 | -------------------------------------------------------------------------------- /Blazor/README.md: -------------------------------------------------------------------------------- 1 | Densen Blazor组件库以及BootstrapBlazor服务扩展包 -------------------------------------------------------------------------------- /Blazor/Services/ClipboardService.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.JSInterop; 8 | 9 | 10 | namespace AME.Services; 11 | 12 | public class ClipboardService 13 | { 14 | private readonly IJSRuntime _jsRuntime; 15 | 16 | public ClipboardService(IJSRuntime jsRuntime) 17 | { 18 | _jsRuntime = jsRuntime; 19 | } 20 | 21 | public ValueTask ReadTextAsync() 22 | { 23 | return _jsRuntime.InvokeAsync("navigator.clipboard.readText"); 24 | } 25 | 26 | public ValueTask WriteTextAsync(string text) 27 | { 28 | return _jsRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Blazor/Services/DensenServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using AME.CommonUtils; 8 | using AME.Services; 9 | using Microsoft.AspNetCore.Http; 10 | using ClipboardService = AME.Services.ClipboardService; 11 | 12 | namespace Microsoft.Extensions.DependencyInjection; 13 | 14 | /// 15 | /// Densen BootstrapBlazor 服务扩展类 16 | /// 17 | public static class DensenServiceCollectionExtensions 18 | { 19 | 20 | /// 21 | /// 增加 BootstrapBlazor Table 服务扩展类, 22 | /// 包含BootstrapBlazor/LazyHero/WebClientInfo/BrowserService/Clipboard 23 | /// 24 | /// 25 | /// 26 | public static IServiceCollection AddDensenExtensions(this IServiceCollection services) 27 | { 28 | services.AddBootstrapBlazor(); 29 | //Table附加内存数据操作服务 30 | services.AddTransient(typeof(LazyHeroDataService<>)); 31 | services.AddTransient(); 32 | services.AddScoped(); 33 | services.AddHttpContextAccessor(); 34 | services.AddScoped(); 35 | services.AddHttpClient(); 36 | services.AddScoped(); 37 | services.AddScoped(); 38 | return services; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Blazor/_Imports.razor: -------------------------------------------------------------------------------- 1 | @namespace AmeBlazor.Components 2 | @using System.Net.Http 3 | @using Microsoft.AspNetCore.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.JSInterop 8 | @using BootstrapBlazor.Components 9 | @using static AME.EnumsExtensions 10 | @using Microsoft.AspNetCore.Components.Authorization 11 | -------------------------------------------------------------------------------- /Blazor/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Blazor/logo.png -------------------------------------------------------------------------------- /Blazor/wwwroot/download.js: -------------------------------------------------------------------------------- 1 | export async function downloadFileFromStream(fileName, contentStreamReference) { 2 | const arrayBuffer = await contentStreamReference.arrayBuffer(); 3 | const blob = new Blob([arrayBuffer]); 4 | const url = URL.createObjectURL(blob); 5 | const anchorElement = document.createElement('a'); 6 | anchorElement.href = url; 7 | if (fileName == null) fileName = "" 8 | anchorElement.download = fileName; 9 | anchorElement.click(); 10 | anchorElement.remove(); 11 | URL.revokeObjectURL(url); 12 | } 13 | 14 | export async function downloadFileFromUrl(fileName, url) { 15 | const anchorElement = document.createElement('a') 16 | anchorElement.href = url 17 | if (fileName == null) fileName = "" 18 | anchorElement.download = fileName 19 | anchorElement.click() 20 | anchorElement.remove() 21 | } -------------------------------------------------------------------------------- /ConsoleTest/ConsoleTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | Debug;Release 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ConsoleTest/ConsoleTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ConsoleTest 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ConsoleTest/Program.cs: -------------------------------------------------------------------------------- 1 | using AME; 2 | using static AME.Enums; 3 | using static AME.EnumExtensions; 4 | using System; 5 | 6 | namespace ConsoleTest 7 | { 8 | internal class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | //var CurrentDirectory = ""; 13 | 14 | //var FileNames2 = CurrentDirectory.GetDirFiles("*.*"); 15 | //FileNames2 = "".GetDirFiles(); 16 | //FileNames2 = "F:\\Repos\\wwwroot\\uploads\\demo\\Product".GetDirFiles(exclude: "chk"); 17 | //foreach (string file in FileNames2) 18 | //{ 19 | // Console.WriteLine(file); 20 | //} 21 | //Console.WriteLine("-------------- \n------------"); 22 | 23 | var enums = "SectionType"; 24 | var xxx= typeof(SectionType); 25 | var res3 =typeof(销售单状态_销售经营历程_补充).GetEnumValueAndDescriptions(); 26 | var res = GetEnumValueAndDescriptionsFromEnumsName("销售登记表付款方式", assemblyString: "AME.API"); 27 | var res1 = GetValuesFromEnumsName(enums, assemblyString: "AME.API"); 28 | 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ConsoleTest/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "WSL": { 4 | "commandName": "WSL2", 5 | "distributionName": "" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.32112.339 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorTest", "BlazorTest\BlazorTest.csproj", "{BBBA0C43-D5C9-4939-9009-D84924EB83E7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {BBBA0C43-D5C9-4939-9009-D84924EB83E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {BBBA0C43-D5C9-4939-9009-D84924EB83E7}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {BBBA0C43-D5C9-4939-9009-D84924EB83E7}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {BBBA0C43-D5C9-4939-9009-D84924EB83E7}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {304A798F-C2DE-41A0-814E-6789BCCF620B} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/AntdBlazor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/AntdBlazor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AntdBlazor 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Not found 8 | 9 |

Sorry, there's nothing at this address.

10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Data/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AntdBlazor.Data 8 | { 9 | public class WeatherForecast 10 | { 11 | public DateTime Date { get; set; } 12 | 13 | public int TemperatureC { get; set; } 14 | 15 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 16 | 17 | public string? Summary { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Data/WeatherForecastService.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace AntdBlazor.Data 8 | { 9 | public class WeatherForecastService 10 | { 11 | private static readonly string[] Summaries = new[] 12 | { 13 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 14 | }; 15 | 16 | public Task GetForecastAsync(DateTime startDate) 17 | { 18 | return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast 19 | { 20 | Date = startDate.AddDays(index), 21 | TemperatureC = Random.Shared.Next(-20, 55), 22 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 23 | }).ToArray()); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model AntdBlazor.Pages.ErrorModel 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Error 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |

Error.

19 |

An error occurred while processing your request.

20 | 21 | @if (Model.ShowRequestId) 22 | { 23 |

24 | Request ID: @Model.RequestId 25 |

26 | } 27 | 28 |

Development Mode

29 |

30 | Swapping to the Development environment displays detailed information about the error that occurred. 31 |

32 |

33 | The Development environment shouldn't be enabled for deployed applications. 34 | It can result in displaying sensitive information from exceptions to end users. 35 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 36 | and restarting the app. 37 |

38 |
39 |
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.AspNetCore.Mvc.RazorPages; 9 | using System.Diagnostics; 10 | 11 | namespace AntdBlazor.Pages 12 | { 13 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 14 | [IgnoreAntiforgeryToken] 15 | public class ErrorModel : PageModel 16 | { 17 | public string? RequestId { get; set; } 18 | 19 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 20 | 21 | private readonly ILogger _logger; 22 | 23 | public ErrorModel(ILogger logger) 24 | { 25 | _logger = logger; 26 | } 27 | 28 | public void OnGet() 29 | { 30 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/FetchData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchdata" 2 | 3 | Weather forecast 4 | 5 | @using AntdBlazor.Data 6 | @inject WeatherForecastService ForecastService 7 | 8 |

Weather forecast

9 | 10 |

This component demonstrates fetching data from a service.

11 | 12 | @if (forecasts == null) 13 | { 14 |

Loading...

15 | } 16 | else 17 | { 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | @foreach (var forecast in forecasts) 29 | { 30 | 31 | 32 | 33 | 34 | 35 | 36 | } 37 | 38 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
39 | } 40 | 41 | @code { 42 | private WeatherForecast[]? forecasts; 43 | 44 | protected override async Task OnInitializedAsync() 45 | { 46 | forecasts = await ForecastService.GetForecastAsync(DateTime.Now); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/ImportPhoto1.razor: -------------------------------------------------------------------------------- 1 | @page "/ImportPhoto1" 2 | 上传和下载文件 3 |
4 |

5 | 6 | 7 | 10 | 11 | 12 |

13 |

14 | 16 |

17 | @if (!string.IsNullOrEmpty(_srcPhoto)) 18 | { 19 | @**@ 20 | 21 | 22 | } 23 |

24 | 25 |

26 |
27 |
28 |
29 |

30 | @if (!string.IsNullOrEmpty(_srcPhoto)) 31 | { 32 | @**@ 33 | 34 | } 35 |

36 |
37 | 38 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/ImportPhoto1.razor.cs: -------------------------------------------------------------------------------- 1 | using AmeBlazor.Components; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.Extensions.Logging; 4 | 5 | namespace AntdBlazor.Pages; 6 | public partial class ImportPhoto1 7 | { 8 | private string? _srcPhoto; 9 | private bool _visible = false; 10 | private void ShowModal() 11 | { 12 | _visible = true; 13 | } 14 | 15 | private void ShowPhoto() 16 | { 17 | this._srcPhoto = "photo-1.jpg"; 18 | } 19 | 20 | protected override void OnInitialized() 21 | { 22 | this.ShowPhoto(); 23 | } 24 | } -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/ImportPhoto11.razor: -------------------------------------------------------------------------------- 1 | @page "/ImportPhoto11" 2 | 上传和下载文件 3 |
4 |

5 | 6 | 7 | 10 | 11 | 12 |

13 |

14 | 16 |

17 | @if (!string.IsNullOrEmpty(_srcPhoto)) 18 | { 19 | @**@ 20 | 21 | 22 | } 23 |

24 | 25 |

26 |
27 |
28 |
29 |

30 | @if (!string.IsNullOrEmpty(_srcPhoto)) 31 | { 32 | @**@ 33 | 34 | } 35 |

36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/ImportPhoto11.razor.cs: -------------------------------------------------------------------------------- 1 | using AmeBlazor.Components; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.Extensions.Logging; 4 | 5 | namespace AntdBlazor.Pages; 6 | public partial class ImportPhoto11 7 | { 8 | private string? _srcPhoto; 9 | private bool _visible = false; 10 | private void ShowModal() 11 | { 12 | _visible = true; 13 | } 14 | 15 | private void ShowPhoto() 16 | { 17 | this._srcPhoto = "photo-2.jpg"; 18 | } 19 | 20 | protected override void OnInitialized() 21 | { 22 | this.ShowPhoto(); 23 | } 24 | } -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/ImportPhoto111.razor: -------------------------------------------------------------------------------- 1 | @page "/ImportPhoto111" 2 | 上传和下载文件 3 |
4 |

5 | 6 | 7 | 10 | 11 | 12 |

13 |

14 | 16 |

17 | @if (!string.IsNullOrEmpty(_srcPhoto)) 18 | { 19 | @**@ 20 | 21 | 22 | } 23 |

24 | 25 |

26 |
27 |
28 |
29 |

30 | @if (!string.IsNullOrEmpty(_srcPhoto)) 31 | { 32 | @**@ 33 | 34 | } 35 |

36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/ImportPhoto111.razor.cs: -------------------------------------------------------------------------------- 1 | using AmeBlazor.Components; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.Extensions.Logging; 4 | 5 | namespace AntdBlazor.Pages; 6 | public partial class ImportPhoto111 7 | { 8 | private string? _srcPhoto; 9 | private bool _visible = false; 10 | private void ShowModal() 11 | { 12 | _visible = true; 13 | } 14 | 15 | private void ShowPhoto() 16 | { 17 | this._srcPhoto = "photo-3.jpg"; 18 | } 19 | 20 | protected override void OnInitialized() 21 | { 22 | this.ShowPhoto(); 23 | } 24 | } -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @page "/TreeControl" 3 | @using System.Diagnostics.CodeAnalysis 4 | 树型组件 5 | 6 |

7 | 10 | 11 | 12 | @for (int i = 0; i < 100; i++) 13 | { 14 | 15 | } 16 | 17 | 18 |

19 |

20 | 21 |

22 | 23 |

24 | 27 | 28 |

29 | 30 | @code 31 | { 32 | string[] _checkedKeys = new string[] { "0901" }; 33 | protected override void OnInitialized() 34 | { 35 | List list = new List(); 36 | @for (int i = 0; i < 200; i++) 37 | { 38 | list.Add($"090{i}"); 39 | } 40 | _checkedKeys = list.ToArray(); 41 | } 42 | public void OnSave() 43 | { 44 | } 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace AntdBlazor.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | @{ 5 | Layout = "_Layout"; 6 | } 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Pages/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | @namespace AntdBlazor.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | @RenderBody() 19 | 20 |
21 | 22 | An error has occurred. This application may no longer respond until reloaded. 23 | 24 | 25 | An unhandled exception has occurred. See browser dev tools for details. 26 | 27 | Reload 28 | 🗙 29 |
30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Program.cs: -------------------------------------------------------------------------------- 1 | using AntdBlazor.Data; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.AspNetCore.Components.Web; 4 | 5 | var builder = WebApplication.CreateBuilder(args); 6 | 7 | // Add services to the container. 8 | builder.Services.AddRazorPages(); 9 | builder.Services.AddServerSideBlazor(); 10 | builder.Services.AddSingleton(); 11 | builder.Services.AddAntDesign(); 12 | var app = builder.Build(); 13 | 14 | // Configure the HTTP request pipeline. 15 | if (!app.Environment.IsDevelopment()) 16 | { 17 | app.UseExceptionHandler("/Error"); 18 | } 19 | 20 | 21 | app.UseStaticFiles(); 22 | 23 | app.UseRouting(); 24 | 25 | app.MapBlazorHub(); 26 | app.MapFallbackToPage("/_Host"); 27 | 28 | app.Run(); 29 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:63164", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "AntdBlazor": { 12 | "commandName": "Project", 13 | "dotnetRunMessages": true, 14 | "launchBrowser": true, 15 | "applicationUrl": "http://localhost:5288", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "IIS Express": { 21 | "commandName": "IISExpress", 22 | "launchBrowser": true, 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | AntdBlazor 4 | 5 |
6 | 9 | 10 |
11 |
12 | About 13 |
14 | 15 |
16 | @Body 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | } 28 | 29 | .top-row a:first-child { 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | } 33 | 34 | @media (max-width: 640.98px) { 35 | .top-row:not(.auth) { 36 | display: none; 37 | } 38 | 39 | .top-row.auth { 40 | justify-content: space-between; 41 | } 42 | 43 | .top-row a, .top-row .btn-link { 44 | margin-left: 0; 45 | } 46 | } 47 | 48 | @media (min-width: 641px) { 49 | .page { 50 | flex-direction: row; 51 | } 52 | 53 | .sidebar { 54 | width: 250px; 55 | height: 100vh; 56 | position: sticky; 57 | top: 0; 58 | } 59 | 60 | .top-row { 61 | position: sticky; 62 | top: 0; 63 | z-index: 1; 64 | } 65 | 66 | .top-row, article { 67 | padding-left: 2rem !important; 68 | padding-right: 1.5rem !important; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  9 | 10 |
11 | 38 |
39 | 40 | @code { 41 | private bool collapseNavMenu = true; 42 | 43 | private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; 44 | 45 | private void ToggleNavMenu() 46 | { 47 | collapseNavMenu = !collapseNavMenu; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 | 
2 | 3 | @Title 4 | 5 | 6 | Please take our 7 | brief survey 8 | 9 | and tell us what you think. 10 |
11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string? Title { get; set; } 16 | } 17 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Authorization 3 | @using Microsoft.AspNetCore.Components.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using AntdBlazor 10 | @using AntdBlazor.Shared 11 | @using AntDesign 12 | @using AmeBlazor.Components 13 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/photo-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/photo-1.jpg -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/photo-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/photo-2.jpg -------------------------------------------------------------------------------- /Demo/Antd/BlazorTest/wwwroot/photo-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/Antd/BlazorTest/wwwroot/photo-3.jpg -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System.Windows; 8 | using static DemoBlazorWpfApp.Startup; 9 | 10 | namespace DemoBlazorWpfApp 11 | { 12 | /// 13 | /// Interaction logic for App.xaml 14 | /// 15 | public partial class App : Application 16 | { 17 | public App() 18 | { 19 | Init(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System.Windows; 8 | 9 | [assembly: ThemeInfo( 10 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 11 | //(used if a resource is not found in the page, 12 | // or application resource dictionaries) 13 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 14 | //(used if a resource is not found in the page, 15 | // app, or any theme specific resource dictionaries) 16 | )] 17 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/DemoBlazorWpfApp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | WinExe 4 | net9.0-windows9.0 5 | enable 6 | true 7 | enable 8 | DemoBlazorWpfApp 9 | 102ba2ce-c240-49cd-a064-deee597f8998 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | Always 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/DemoBlazorWpfApp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DemoBlazorWpfApp 5 | 6 | 7 | 8 | 9 | Interaction logic for App.xaml 10 | 11 | 12 | App 13 | 14 | 15 | 16 | 17 | InitializeComponent 18 | 19 | 20 | 21 | 22 | Application Entry Point. 23 | 24 | 25 | 26 | 27 | Interaction logic for MainWindow.xaml 28 | 29 | 30 | MainWindow 31 | 32 | 33 | 34 | 35 | InitializeComponent 36 | 37 | 38 | 39 | 40 | IErrorBoundaryLogger扩展类 41 | 42 | 43 | 44 | 45 | 服务扩展类 46 | 47 | 48 | 49 | 50 | 服务扩展类, 51 | 包含各平台差异实现 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/DemoBlazorWpfApp_st51me52_wpftmp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DemoBlazorWpfApp 5 | 6 | 7 | 8 | 9 | Interaction logic for App.xaml 10 | 11 | 12 | App 13 | 14 | 15 | 16 | 17 | InitializeComponent 18 | 19 | 20 | 21 | 22 | Application Entry Point. 23 | 24 | 25 | 26 | 27 | Interaction logic for MainWindow.xaml 28 | 29 | 30 | MainWindow 31 | 32 | 33 | 34 | 35 | InitializeComponent 36 | 37 | 38 | 39 | 40 | IErrorBoundaryLogger扩展类 41 | 42 | 43 | 44 | 45 | 服务扩展类 46 | 47 | 48 | 49 | 50 | 服务扩展类, 51 | 包含各平台差异实现 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  15 | 16 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System.Windows; 8 | 9 | namespace DemoBlazorWpfApp 10 | { 11 | /// 12 | /// Interaction logic for MainWindow.xaml 13 | /// 14 | public partial class MainWindow : Window 15 | { 16 | public MainWindow() 17 | { 18 | Resources.Add("services", Startup.Services); 19 | InitializeComponent(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "DemoBlazorWpfApp": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "https://localhost:58644;http://localhost:58645" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/Services/MyErrorBoundaryLogger.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Components.Web; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Microsoft.Extensions.DependencyInjection; 11 | 12 | /// 13 | /// IErrorBoundaryLogger扩展类 14 | /// 15 | 16 | public sealed class MyErrorBoundaryLogger : IErrorBoundaryLogger 17 | { 18 | private readonly ILogger _errorBoundaryLogger; 19 | 20 | public MyErrorBoundaryLogger(ILogger errorBoundaryLogger) 21 | { 22 | _errorBoundaryLogger = errorBoundaryLogger ?? throw new ArgumentNullException(nameof(errorBoundaryLogger)); 23 | } 24 | 25 | public ValueTask LogErrorAsync(Exception exception) 26 | { 27 | // For, client-side code, all internal state is visible to the end user. We can just 28 | // log directly to the console. 29 | _errorBoundaryLogger.LogError(exception, exception.ToString()); 30 | return ValueTask.CompletedTask; 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/Services/SharedServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | //using System.Data.SQLite; 8 | using Microsoft.AspNetCore.Components.Web; 9 | using System.Globalization; 10 | 11 | namespace Microsoft.Extensions.DependencyInjection; 12 | 13 | /// 14 | /// 服务扩展类 15 | /// 16 | public static class SharedServiceCollectionExtensions 17 | { 18 | 19 | /// 20 | /// 服务扩展类, 21 | /// 包含各平台差异实现 22 | /// 23 | /// 24 | /// 25 | public static IServiceCollection AddSharedExtensions(this IServiceCollection services) 26 | { 27 | var cultureInfo = new CultureInfo("zh-CN"); 28 | CultureInfo.DefaultThreadCurrentCulture = cultureInfo; 29 | CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; 30 | 31 | services.AddDensenExtensions(); 32 | 33 | //据说已经修复 34 | //2022/8/11 测试fsql是不是这个问题 35 | services.AddSingleton(); 36 | return services; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/Startup.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Hosting; 10 | 11 | namespace DemoBlazorWpfApp 12 | { 13 | public static class Startup 14 | { 15 | public class ConfigFake { } 16 | public static IServiceProvider? Services { get; private set; } 17 | public static IConfiguration? Config; 18 | 19 | public static void Init() 20 | { 21 | var host = Host.CreateDefaultBuilder() 22 | .ConfigureAppConfiguration((hostingContext, config) => 23 | { 24 | config.AddUserSecrets().Build(); 25 | //config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); 26 | Config = config.Build(); 27 | }) 28 | .ConfigureServices(WireupServices) 29 | .Build(); 30 | Services = host.Services; 31 | } 32 | 33 | private static void WireupServices(HostBuilderContext context, IServiceCollection services) 34 | { 35 | services.AddWpfBlazorWebView(); 36 | services.AddSharedExtensions(); 37 | services.AddOcrExtensions(); 38 | services.AddAIFormExtensions(); 39 | #if DEBUGSC || DEBUG 40 | services.AddBlazorWebViewDeveloperTools(); 41 | #endif 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Routing 2 | @using Microsoft.AspNetCore.Components.Web 3 | @using DemoBlazorWpfApp 4 | @using DemoShared 5 | @using DemoShared.Shared 6 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "BaiduKey": "BaiduKey", 11 | "GoogleKey": "GoogleKey", 12 | "AzureCvKey": "AzureCvKey", 13 | "AzureCvUrl": "https://xxx.cognitiveservices.azure.com/", 14 | "AzureCvFaceKey": "AzureCvFaceKey", 15 | "AzureCvFaceUrl": "https://xxx.cognitiveservices.azure.com/", 16 | "AzureAiFormKey": "AzureAiFormKey", 17 | "AzureAiFormUrl": "https://xxx.cognitiveservices.azure.com/", 18 | "AzureSsKey": "AzureSsKey", 19 | "AzureSsUrl": "https://xxx.api.cognitive.microsoft.com/sts/v1.0/issuetoken" 20 | } 21 | -------------------------------------------------------------------------------- /Demo/DemoBlazorWpfApp/wwwroot/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Blazor app 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 | An unhandled error has occurred. 22 | Reload 23 | 🗙 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Demo/DemoLib/DemoLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net9.0 5 | 8.0.0 6 | 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Demo/DemoLib/DemoLib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DemoLib 5 | 6 | 7 | 8 | 9 | 商品名称 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Demo/DemoPWA/DemoPWA.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net9.0 5 | service-worker-assets.js 6 | 102ba2ce-c240-49cd-a064-deee597f8998 7 | enable 8 | false 9 | Default 10 | true 11 | 12 | 13 | 14 | True 15 | 16 | 17 | 18 | True 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Demo/DemoPWA/DemoPWA.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DemoPWA 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/DemoPWA/Program.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using DemoShared; 8 | using Microsoft.AspNetCore.Components.Web; 9 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 10 | using System.Globalization; 11 | using System.Reflection; 12 | 13 | var cultureInfo = new CultureInfo("zh-CN"); 14 | CultureInfo.DefaultThreadCurrentCulture = cultureInfo; 15 | CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; 16 | 17 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 18 | builder.RootComponents.Add("#app"); 19 | builder.RootComponents.Add("head::after"); 20 | 21 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 22 | builder.Services.AddDensenExtensions(); 23 | builder.Services.AddStorages(); 24 | builder.Services.ConfigureJsonLocalizationOptions(op => 25 | { 26 | // 忽略文化信息丢失日志 27 | op.IgnoreLocalizerMissing = true; 28 | 29 | // 附加自己的 json 多语言文化资源文件 如 zh-TW.json 30 | op.AdditionalJsonAssemblies = new Assembly[] 31 | { 32 | //typeof(BootstrapBlazor.Shared.App).Assembly, 33 | typeof(BootstrapBlazor.Components.Chart).Assembly, 34 | //typeof(BootstrapBlazor.Components.SignaturePad).Assembly 35 | }; 36 | }); 37 | builder.Services.AddOcrExtensions(builder.Configuration["AzureCvKey"], builder.Configuration["AzureCvUrl"]); 38 | builder.Services.AddAIFormExtensions(builder.Configuration["AzureAiFormKey"], builder.Configuration["AzureAiFormUrl"]); 39 | await builder.Build().RunAsync(); 40 | -------------------------------------------------------------------------------- /Demo/DemoPWA/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:57605/", 7 | "sslPort": 44338 8 | } 9 | }, 10 | "profiles": { 11 | "DemoPWA": { 12 | "commandName": "Project", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | }, 17 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 18 | "applicationUrl": "https://localhost:5011;http://localhost:5000", 19 | "dotnetRunMessages": true 20 | }, 21 | "IIS Express": { 22 | "commandName": "IISExpress", 23 | "launchBrowser": true, 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}" 28 | }, 29 | "WSL": { 30 | "commandName": "WSL2", 31 | "launchBrowser": true, 32 | "launchUrl": "https://localhost:5011", 33 | "environmentVariables": { 34 | "ASPNETCORE_ENVIRONMENT": "Development", 35 | "ASPNETCORE_URLS": "https://localhost:5011;http://localhost:5000" 36 | }, 37 | "distributionName": "" 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Demo/DemoPWA/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http.Json 2 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 3 | @using DemoPWA 4 | @using DemoShared 5 | @using DemoShared.Shared 6 | -------------------------------------------------------------------------------- /Demo/DemoPWA/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "BaiduKey": "BaiduKey", 3 | "GoogleKey": "GoogleKey", 4 | "AzureCvKey": "AzureCvKey", 5 | "AzureCvUrl": "https://xxx.cognitiveservices.azure.com/", 6 | "AzureCvFaceKey": "AzureCvFaceKey", 7 | "AzureCvFaceUrl": "https://xxx.cognitiveservices.azure.com/", 8 | "AzureAiFormKey": "AzureAiFormKey", 9 | "AzureAiFormUrl": "https://xxx.cognitiveservices.azure.com/", 10 | "AzureSsKey": "AzureSsKey", 11 | "AzureSsUrl": "https://xxx.api.cognitive.microsoft.com/sts/v1.0/issuetoken" 12 | } 13 | -------------------------------------------------------------------------------- /Demo/DemoPWA/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/DemoPWA/wwwroot/favicon.ico -------------------------------------------------------------------------------- /Demo/DemoPWA/wwwroot/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | DemoPWA 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
Loading...
21 | 22 |
23 | An unhandled error has occurred. 24 | Reload 25 | 🗙 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Demo/DemoPWA/wwwroot/service-worker.js: -------------------------------------------------------------------------------- 1 | // In development, always fetch from the network and do not enable offline support. 2 | // This is because caching would make development more difficult (changes would not 3 | // be reflected on the first load after each change). 4 | self.addEventListener('fetch', () => { }); 5 | -------------------------------------------------------------------------------- /Demo/DemoSSR/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "5.0.8", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Demo/DemoSSR/Controllers/EchoController.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using BootstrapBlazor.AzureServices; 8 | using BootstrapBlazor.Ocr.Services; 9 | using BootstrapBlazor.OpenAI.Services; 10 | using Microsoft.AspNetCore.Mvc; 11 | 12 | namespace AME.Controllers; 13 | #nullable enable 14 | 15 | [ApiController] 16 | [Route("[controller]")] 17 | public class EchoController : ControllerBase 18 | { 19 | /// 20 | /// Echo接口 21 | /// 22 | /// 23 | /// 24 | [HttpPost] 25 | [HttpGet] 26 | public IActionResult Echo(string info = "test") 27 | { 28 | if (string.IsNullOrWhiteSpace(info)) 29 | { 30 | return BadRequest("输入不能为空"); 31 | } 32 | 33 | return Ok(info); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Demo/DemoSSR/DemoSSR.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0;net9.0 5 | 102ba2ce-c240-49cd-a064-deee597f8998 6 | true 7 | enable 8 | Debug;Release;DebugSC 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | PreserveNewest 26 | 27 | 28 | PreserveNewest 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Demo/DemoSSR/DemoSSR.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DemoSSR 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/DemoSSR/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model DemoSSR.Pages.ErrorModel 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Error 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |

Error.

19 |

An error occurred while processing your request.

20 | 21 | @if (Model.ShowRequestId) 22 | { 23 |

24 | Request ID: @Model.RequestId 25 |

26 | } 27 | 28 |

Development Mode

29 |

30 | Swapping to the Development environment displays detailed information about the error that occurred. 31 |

32 |

33 | The Development environment shouldn't be enabled for deployed applications. 34 | It can result in displaying sensitive information from exceptions to end users. 35 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 36 | and restarting the app. 37 |

38 |
39 |
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Demo/DemoSSR/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.AspNetCore.Mvc.RazorPages; 9 | using System.Diagnostics; 10 | 11 | namespace DemoSSR.Pages 12 | { 13 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 14 | [IgnoreAntiforgeryToken] 15 | public class ErrorModel : PageModel 16 | { 17 | public string RequestId { get; set; } 18 | 19 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 20 | 21 | private readonly ILogger _logger; 22 | 23 | public ErrorModel(ILogger logger) 24 | { 25 | _logger = logger; 26 | } 27 | 28 | public void OnGet() 29 | { 30 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Demo/DemoSSR/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace Demo.SSR 3 | @using DemoShared 4 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 5 | @{ 6 | Layout = "_Layout"; 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /Demo/DemoSSR/Pages/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | @namespace BlazorApp1.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | 5 | 6 | 7 | 8 | 9 | 10 | DemoSSR 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | @RenderBody() 23 | 24 |
25 | 26 | An error has occurred. This application may no longer respond until reloaded. 27 | 28 | 29 | An unhandled exception has occurred. See browser dev tools for details. 30 | 31 | Reload 32 | 33 |
34 | 39 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Demo/DemoSSR/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Authorization 2 | @using Microsoft.AspNetCore.Components.Authorization 3 | @using DemoSSR 4 | @using DemoShared 5 | @using DemoShared.Shared 6 | -------------------------------------------------------------------------------- /Demo/DemoSSR/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Demo/DemoSSR/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "BaiduKey": "BaiduKey", 11 | "GoogleKey": "GoogleKey", 12 | "AzureCvKey": "AzureCvKey", 13 | "AzureCvUrl": "https://xxx.cognitiveservices.azure.com/", 14 | "AzureAiFormKey": "AzureAiFormKey", 15 | "AzureAiFormUrl": "https://xxx.cognitiveservices.azure.com/", 16 | "AzureTranslateKey": "AzureTranslateKey", 17 | "AzureTranslateUrl": "https://api.cognitive.microsofttranslator.com", 18 | "AzureCvFaceKey": "AzureCvFaceKey", 19 | "AzureCvFaceUrl": "https://xxx.cognitiveservices.azure.com/", 20 | "AzureSsKey": "AzureSsKey", 21 | "AzureSsUrl": "https://xxx.tts.speech.microsoft.com/cognitiveservices/v1", 22 | "AzureSsFetchTokenUri": "https://xxx.api.cognitive.microsoft.com/sts/v1.0/issueToken", 23 | "OpenAIKey": "OpenAIKey", 24 | "AzureOpenAIZone": "westeurope", 25 | "AzureOpenAIUrl": "https://xxx.openai.azure.com/openai/deployments/", 26 | "AzureOpenAIKey": "AzureOpenAIKey", 27 | "OpenAiClientConfiguration": { 28 | "BaseUri": "[your_fqdn]", 29 | "ApiKey": "[your_api_key]", 30 | "DeploymentName": "[your,deployment_name]" 31 | }, 32 | "Key": "419130936", 33 | "BlazorHybridPath": "C:\\Users\\Alex\\Documents\\Photo" 34 | } 35 | -------------------------------------------------------------------------------- /Demo/DemoSSR/wwwroot/fxf5kv2kjka8vfwgvim6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/DemoSSR/wwwroot/fxf5kv2kjka8vfwgvim6.pdf -------------------------------------------------------------------------------- /Demo/DemoSSR/wwwroot/mljq8tr2k29nbrbanmci.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/densen2014/Densen.Extensions/360de80d7855b2e821b6f568f61fa76dc1343976/Demo/DemoSSR/wwwroot/mljq8tr2k29nbrbanmci.pdf -------------------------------------------------------------------------------- /Demo/DemoShared/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Not found 9 | 10 |

Sorry, there's nothing at this address.

11 |
12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /Demo/DemoShared/Component/AppComponentBase.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using BootstrapBlazor.Components; 8 | using BootstrapBlazor.WebAPI.Services; 9 | using Microsoft.AspNetCore.Components; 10 | using Microsoft.JSInterop; 11 | using System.Diagnostics.CodeAnalysis; 12 | 13 | namespace DemoShared; 14 | 15 | 16 | /// 17 | /// 组件基类 18 | /// 19 | public abstract partial class AppComponentBase : ComponentBase, IDisposable 20 | { 21 | [Inject, NotNull] protected ToastService? ToastService { get; set; } 22 | [Inject, NotNull] protected MessageService? MessageService { get; set; } 23 | [Inject, NotNull] protected IJSRuntime? JSRuntime { get; set; } 24 | [Inject, NotNull] protected ICookie? Cookie { get; set; } 25 | [Inject, NotNull] protected IStorage? Storage { get; set; } 26 | [Inject, NotNull] protected NavigationManager? NavigationManager { get; set; } 27 | protected bool IsBusy { get; set; } 28 | 29 | [Parameter] 30 | public EventCallback Changed { get; set; } 31 | 32 | /// 33 | /// Dispose 方法 34 | /// 35 | /// 36 | protected virtual void Dispose(bool disposing) 37 | { 38 | 39 | } 40 | 41 | /// 42 | /// Dispose 方法 43 | /// 44 | public void Dispose() 45 | { 46 | Dispose(disposing: true); 47 | GC.SuppressFinalize(this); 48 | } 49 | 50 | protected override void OnInitialized() 51 | { 52 | base.OnInitialized(); 53 | } 54 | 55 | protected virtual Task BackToHome() 56 | { 57 | NavigationManager.NavigateTo("/"); 58 | return Task.CompletedTask; 59 | } 60 | 61 | [NotNull] 62 | protected Message? Message { get; set; } 63 | 64 | protected async Task ShowBottomMessage(string message, bool error = false) 65 | { 66 | await MessageService.Show(new MessageOption() 67 | { 68 | Content = message, 69 | Icon = "fa-solid fa-circle-info", 70 | Color = error ? Color.Warning : Color.Primary 71 | }, Message); 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /Demo/DemoShared/Component/InputOnKeyup.razor: -------------------------------------------------------------------------------- 1 | @namespace BootstrapBlazor.Components 2 | @typeparam TValue 3 | @inherits BootstrapInputBase 4 | 5 | @if (IsShowLabel) 6 | { 7 | 8 | } 9 | 10 | 11 | 12 | @code{ 13 | 14 | /// 15 | /// 获得/设置 是否为只读 默认 false 16 | /// 17 | [Parameter] 18 | public bool Readonly { get; set; } 19 | 20 | private string? ReadonlyString => Readonly ? "true" : null; 21 | 22 | /// 23 | /// 获得/设置 是否在文本框的值更改时触发 默认 false 24 | /// 25 | [Parameter] 26 | public bool OnInput { get; set; }=false; 27 | 28 | private string EventString => OnInput ? "oninput" : "onchange"; 29 | 30 | } -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/AiFormPage.razor: -------------------------------------------------------------------------------- 1 | @page "/aiform" 2 | @attribute [TabItemOption(Text = "AI表格识别")] 3 | 4 |

表格识别 AI Form

5 |
6 |
页面源码
7 | 8 | ModelId="prebuilt-read" 9 | 10 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/AiFormPage.razor.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using Azure.AI.FormRecognizer.DocumentAnalysis; 8 | 9 | 10 | namespace DemoShared.Pages; 11 | 12 | public partial class AiFormPage 13 | { 14 | private List? models { get; set; } 15 | private Task OnResult(List models) 16 | { 17 | this.models = models; 18 | StateHasChanged(); 19 | return Task.CompletedTask; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/AttributeItem.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | namespace DemoShared 8 | { 9 | public class AttributeItem 10 | { 11 | public AttributeItem() { } 12 | 13 | public AttributeItem(string Name, string Description, string DefaultValue, string Type = "string", string ValueList = "-") 14 | { 15 | this.Name = Name; 16 | this.Description = Description; 17 | this.Type = Type; 18 | this.ValueList = ValueList; 19 | this.DefaultValue = DefaultValue; 20 | } 21 | 22 | public string? Name { get; set; } 23 | public string? Description { get; set; } 24 | public string? Type { get; set; } = "string"; 25 | public string? ValueList { get; set; } = "-"; 26 | public string? DefaultValue { get; set; } = ""; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/AttributeTable.razor: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 |
5 |
6 | 7 |

@Title

8 | 9 |
10 | 11 |
12 |
13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | @foreach (var item in Items) 32 | { 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | } 42 | 43 |
参数/Parameter
说明/Description
类型/Type
默认值/DefaultValue
可选值/ValueList
@item.Name
@item.Description
@item.Type
@item.DefaultValue
@item.ValueList
44 |
45 | 46 |
47 |
48 | 49 |
50 |
51 | 52 | @code{ 53 | 54 | /// 55 | /// 获得/设置 项目 56 | /// 57 | [Parameter] 58 | public IEnumerable Items { get; set; } = new AttributeItem[] { }; 59 | 60 | /// 61 | /// 62 | /// 63 | [Parameter] 64 | public string? Title { get; set; } = "事件 Events"; 65 | 66 | 67 | } -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/AzureOpenAIPage.razor: -------------------------------------------------------------------------------- 1 | @page "/AzureOpenAI" 2 | @attribute [TabItemOption(Text = "AzureOpenAI")] 3 | 4 |

Azure OpenAI

5 |
6 |
页面源码
7 | 8 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/BaiduMapPage.razor: -------------------------------------------------------------------------------- 1 | @page "/baidumap" 2 | @attribute [TabItemOption(Text = "百度地图 BaiduMap")] 3 | 4 |

百度地图 Baidu Map

5 |
6 |
页面源码
7 | 8 | 9 |

@message

10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/BaiduMapPage.razor.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using BootstrapBlazor.Components; 8 | 9 | namespace DemoShared.Pages; 10 | 11 | /// 12 | /// 百度地图 BaiduMap 13 | /// 14 | public sealed partial class BaiduMapPage 15 | { 16 | 17 | private string? message; 18 | private BaiduItem? baiduItem; 19 | 20 | private Task OnResult(BaiduItem geolocations) 21 | { 22 | baiduItem = geolocations; 23 | message = baiduItem.Status; 24 | StateHasChanged(); 25 | return Task.CompletedTask; 26 | } 27 | 28 | private Task OnError(string message) 29 | { 30 | this.message = message; 31 | StateHasChanged(); 32 | return Task.CompletedTask; 33 | } 34 | 35 | 36 | 37 | /// 38 | /// 获得属性方法 39 | /// 40 | /// 41 | private IEnumerable GetAttributes() => new AttributeItem[] 42 | { 43 | new AttributeItem("BaiduKey",@"为空则在 IConfiguration 服务获取 ""BaiduKey"" , 默认在 appsettings.json 文件配置", ""), 44 | new AttributeItem("Style","地图大小", "height:700px;width:100%;","string"), 45 | new AttributeItem("Init","初始化", "-","Task"), 46 | new AttributeItem("ResetMaps","复位", "-","Task"), 47 | new AttributeItem("GetLocation","获取定位", "-","void"), 48 | new AttributeItem("OnResult","获取定位回调", "-","Func"), 49 | new AttributeItem("OnError","错误信息回调", "-","Func"), 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/Blazor100/B19LongPressButton.razor: -------------------------------------------------------------------------------- 1 | @page "/b19LongPressButton" 2 | @namespace DemoShared 3 | @attribute [TabItemOption(Text = "长按事件")] 4 | 5 | 支持长按事件的按钮组件 6 | 7 | Blazor100 : 自做一个支持长按事件的按钮组件 8 | https://www.cnblogs.com/densen2014/p/17915285.html 9 | 10 | 11 |
12 |

LongPressButton

13 |
14 |
15 | 16 |

@message

17 | 18 | @code { 19 | string message = "No long press"; 20 | 21 | private Task TaskOnLongPress(MouseEventArgs e) 22 | { 23 | message = e.Type; 24 | StateHasChanged(); 25 | return Task.CompletedTask; 26 | } 27 | } -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/Blazor100/B20Gesture.razor: -------------------------------------------------------------------------------- 1 | @page "/b20Gesture" 2 | @namespace DemoShared 3 | @attribute [TabItemOption(Text = "手势")] 4 | 5 | 手势滑动组件 6 | 7 | Blazor100 : 自做一个手势滑动组件 8 | https://www.cnblogs.com/densen2014/p/17915288.html 9 | 10 | 11 | 12 |
13 |

Slide me

14 |

page @pageNumber

15 |
16 |
17 | 18 | @code { 19 | 20 | int pageNumber = 1; 21 | 22 | private Task OnGesture(EnumGesture gesture) 23 | { 24 | switch (gesture) 25 | { 26 | case EnumGesture.Back: 27 | pageNumber--; 28 | break; 29 | case EnumGesture.PageUp: 30 | pageNumber++; 31 | break; 32 | default: 33 | break; 34 | } 35 | if (pageNumber < 1) 36 | { 37 | pageNumber = 1; 38 | } 39 | 40 | //翻页和路由参数跳转大佬们自由发挥测试 41 | //NavigationManager.NavigateTo($"/Page{page}"); 42 | 43 | 44 | StateHasChanged(); 45 | return Task.CompletedTask; 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/Blazor100/EnumGesture.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using System.ComponentModel; 8 | 9 | namespace DemoShared; 10 | 11 | 12 | public enum EnumGesture 13 | { 14 | [Description("无手势")] 15 | None, 16 | 17 | [Description("向左滑动")] 18 | Left, 19 | 20 | [Description("向右滑动")] 21 | Right, 22 | 23 | [Description("回退手势")] 24 | Back, 25 | 26 | [Description("翻页手势")] 27 | PageUp, 28 | 29 | [Description("刷新手势")] 30 | Refresh, 31 | 32 | [Description("退出手势")] 33 | Exit, 34 | } 35 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/Blazor100/GestureComponent.razor: -------------------------------------------------------------------------------- 1 | @namespace DemoShared 2 | 3 |

startX @startX

4 |

endX @endX

5 |

deltaX @deltaX

6 |

check @(Math.Abs(deltaX) > Threshold)

7 |

gesture @gesture

8 | 9 |
10 | 11 | @ChildContent 12 | 13 |
14 | 15 | @code { 16 | 17 | double startX, endX, deltaX; 18 | 19 | EnumGesture gesture = EnumGesture.None; 20 | 21 | //// 默认手势移动距离阈值px 22 | [Parameter] 23 | public int Threshold { get; set; } = 100; 24 | 25 | [Parameter] 26 | public RenderFragment? ChildContent { get; set; } 27 | 28 | /// 29 | /// 获得/设置 手势动作回调委托 30 | /// 31 | [Parameter] 32 | public Func? OnGesture { get; set; } 33 | 34 | private void OnTouchStart(TouchEventArgs e) 35 | { 36 | // 记录手势起始点坐标 37 | startX = e.Touches[0].PageX; 38 | } 39 | 40 | private void OnTouchMove(TouchEventArgs e) 41 | { 42 | 43 | endX = e.Touches[0].PageX; 44 | 45 | deltaX = endX - startX; 46 | 47 | gesture = deltaX > 0 ? EnumGesture.Right : EnumGesture.Left; 48 | 49 | StateHasChanged(); 50 | 51 | } 52 | 53 | private void OnTouchEnd(TouchEventArgs e) 54 | { 55 | 56 | deltaX = endX - startX; 57 | 58 | if (deltaX > 0 && deltaX > Threshold) 59 | { 60 | 61 | gesture = EnumGesture.Back; 62 | } 63 | else if (Math.Abs(deltaX) > Threshold) 64 | { 65 | gesture = EnumGesture.PageUp; 66 | } 67 | else 68 | { 69 | gesture = EnumGesture.None; 70 | } 71 | 72 | if (OnGesture != null) 73 | { 74 | OnGesture.Invoke(gesture); 75 | } 76 | 77 | StateHasChanged(); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/BtBatteryLevelPage.razor: -------------------------------------------------------------------------------- 1 | @page "/BtBatteryLevel" 2 | @attribute [TabItemOption(Text = "蓝牙设备电量")] 3 | 4 |

蓝牙设备电量

5 |
6 |
页面源码
7 | 8 | 9 | 10 |
11 | @value % 12 |
@message
13 |
@statusmessage
14 |
@errmessage
15 | 16 | @code{ 17 | 18 | BatteryLevel batteryLevel { get; set; } = new BatteryLevel(); 19 | 20 | private decimal? value = 0; 21 | private string? message; 22 | private string? statusmessage; 23 | private string? errmessage; 24 | 25 | private Task OnResult(string message) 26 | { 27 | this.message = message; 28 | StateHasChanged(); 29 | return Task.CompletedTask; 30 | } 31 | 32 | private Task OnUpdateValue(decimal value) 33 | { 34 | this.value = value; 35 | this.statusmessage = $"设备电量{value}%"; 36 | StateHasChanged(); 37 | return Task.CompletedTask; 38 | } 39 | 40 | 41 | private Task OnUpdateStatus(BluetoothDevice device) 42 | { 43 | this.statusmessage = device.Status; 44 | StateHasChanged(); 45 | return Task.CompletedTask; 46 | } 47 | 48 | private Task OnError(string message) 49 | { 50 | this.errmessage = message; 51 | StateHasChanged(); 52 | return Task.CompletedTask; 53 | } 54 | 55 | public async void GetBatteryLevel() 56 | { 57 | await batteryLevel.GetBatteryLevel(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/BtHeartratePage.razor: -------------------------------------------------------------------------------- 1 | @page "/BtHeartrate" 2 | @attribute [TabItemOption(Text = "蓝牙心率带")] 3 | 4 |

蓝牙心率带

5 |
6 |
页面源码
7 | 8 | 9 | 10 | 11 |

12 |
@message
13 |
@statusmessage
14 |
@errmessage
15 | 16 | @code{ 17 | //string? heartrateIcon;// { get => (heartrateIcon == "❤" ? "♥" : "❤"); } 18 | 19 | Heartrate heartrate { get; set; } = new Heartrate(); 20 | 21 | private string? message; 22 | private int? value; 23 | private string? statusmessage; 24 | private string? errmessage; 25 | 26 | private Task OnResult(string message) 27 | { 28 | this.message = message; 29 | StateHasChanged(); 30 | return Task.CompletedTask; 31 | } 32 | 33 | private Task OnUpdateValue(int value) 34 | { 35 | this.value = value; 36 | this.statusmessage = $"心率{value}"; 37 | StateHasChanged(); 38 | return Task.CompletedTask; 39 | } 40 | 41 | 42 | private Task OnUpdateStatus(BluetoothDevice device) 43 | { 44 | this.statusmessage = device.Status; 45 | StateHasChanged(); 46 | return Task.CompletedTask; 47 | } 48 | 49 | private Task OnError(string message) 50 | { 51 | this.errmessage = message; 52 | StateHasChanged(); 53 | return Task.CompletedTask; 54 | } 55 | 56 | public async void GetHeartrate() 57 | { 58 | await heartrate.GetHeartrate(); 59 | } 60 | 61 | public async void StopHeartrate() 62 | { 63 | await heartrate.StopHeartrate(); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/CV2Dnn.razor: -------------------------------------------------------------------------------- 1 | @page "/CV2Dnn" 2 | @namespace DemoShared.Pages 3 | @attribute [TabItemOption(Text = "物体检测")] 4 | 5 | @using BootstrapBlazor.Components 6 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/Charts.razor: -------------------------------------------------------------------------------- 1 | @page "/charts" 2 | @attribute [TabItemOption(Text = "图表", Icon = "fa fa-chart")] 3 | 4 | 图表 5 | 6 |

折线图

7 | 8 | 9 | 10 | 11 | 12 | @code{ 13 | private Random Randomer { get; } = new Random(); 14 | private int LineDatasetCount = 2; 15 | private int LineDataCount = 7; 16 | 17 | private Chart LineChart { get; set; } = new Chart(); 18 | 19 | private Task OnInit(float tension, bool hasNull) 20 | { 21 | var ds = new ChartDataSource(); 22 | ds.Options.Title = "Line 折线图"; 23 | ds.Options.X.Title = "天数"; 24 | ds.Options.Y.Title = "数值"; 25 | ds.Labels = Enumerable.Range(1, LineDataCount).Select(i => i.ToString()); 26 | for (var index = 0; index < LineDatasetCount; index++) 27 | { 28 | ds.Data.Add(new ChartDataset() 29 | { 30 | Tension = tension, 31 | Label = $"数据集 {index}", 32 | Data = Enumerable.Range(1, LineDataCount).Select((i, index) => (index == 2 && hasNull) ? null! : (object)Randomer.Next(20, 37)) 33 | }); 34 | } 35 | return Task.FromResult(ds); 36 | } 37 | } -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/GeolocationPage.razor: -------------------------------------------------------------------------------- 1 | @page "/geolocations" 2 | @attribute [TabItemOption(Text = "定位/持续定位")] 3 | 4 |

定位/持续定位 Geolocation

5 |
6 |
页面源码
7 | 8 | 9 |

@message

10 | 11 | 12 | 13 | @status 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/GeolocationPage.razor.cs: -------------------------------------------------------------------------------- 1 | // ********************************** 2 | // Densen Informatica 中讯科技 3 | // 作者:Alex Chow 4 | // e-mail:zhouchuanglin@gmail.com 5 | // ********************************** 6 | 7 | using BootstrapBlazor.Components; 8 | 9 | namespace DemoShared.Pages; 10 | 11 | /// 12 | /// Geolocation 地理定位/移动距离追踪 13 | /// 14 | /// 扩展阅读:Chrome中模拟定位信息,清除定位信息 15 | /// https://blog.csdn.net/u010844189/article/details/81163438 16 | /// 17 | public sealed partial class GeolocationPage 18 | { 19 | 20 | private string? status { get; set; } 21 | private Geolocationitem? geolocations { get; set; } 22 | private List Items { get; set; } = new List() { new Geolocationitem() }; 23 | private string? message; 24 | 25 | private Task OnResult(Geolocationitem geolocations) 26 | { 27 | this.geolocations = geolocations; 28 | Items[0] = geolocations; 29 | StateHasChanged(); 30 | return Task.CompletedTask; 31 | } 32 | 33 | private Task OnUpdateStatus(string status) 34 | { 35 | this.status = status; 36 | StateHasChanged(); 37 | return Task.CompletedTask; 38 | } 39 | 40 | private Task OnError(string message) 41 | { 42 | this.message = message; 43 | StateHasChanged(); 44 | return Task.CompletedTask; 45 | } 46 | 47 | 48 | /// 49 | /// 获得属性方法 50 | /// 51 | /// 52 | private IEnumerable GetAttributes() => new AttributeItem[] 53 | { 54 | new AttributeItem("GetLocationButtonText","获取位置按钮文字", "获取位置"), 55 | new AttributeItem("WatchPositionButtonText","移动距离追踪按钮文字","移动距离追踪"), 56 | new AttributeItem("ClearWatchPositionButtonText","停止追踪按钮文字","停止追踪"), 57 | new AttributeItem("ShowButtons","是否显示默认按钮界面","true","bool","true|false"), 58 | new AttributeItem("OnResult","定位完成回调方法", "-","Func"), 59 | new AttributeItem("OnUpdateStatus","状态更新回调方法", "-","Func"), 60 | new AttributeItem("OnError","错误信息回调", "-","Func"), 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /Demo/DemoShared/Pages/HandwrittenPage.razor: -------------------------------------------------------------------------------- 1 | @page "/handwritten" 2 | @attribute [TabItemOption(Text = "手写签名")] 3 | 4 |

Handwritten 手写签名

5 |

建议转为使用 SignaturePadPage组件

6 |
7 |
页面源码
8 | 9 | 14 |