隨筆 20250519 基于MAUI Blazor整合SQLite数据库与Star打印机的详细步骤
以下是基于MAUI Blazor整合SQLite数据库与Star打印机的详细步骤,包含必要的NuGet包引入及核心代码实现:
零、目錄結構
一、整合SQLite数据库
1. 安装NuGet包
# SQLite核心库
Install-Package sqlite-net-pcl
# SQLite平台适配库(解决跨平台兼容性问题)
Install-Package sqlitepclraw.bundle_green
2. 数据库配置
-
创建数据模型(如
Order.cs
):using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace StarMauiPrinter.Models {public class Order{[PrimaryKey, AutoIncrement]public int Id { get; set; }// 注文番号public string OrderNumber { get; set; }// 注文日時public string OrderTime { get; set; }// 商品コードpublic string ProductCode { get; set; }// 商品名public string ProductName { get; set; }// 単価public decimal UnitPrice { get; set; }// 数量public int Quantity { get; set; }// 担当者public string ResponsiblePerson { get; set; }// 顧客名public string CustomerName { get; set; }// 支払方法public string PaymentMethod { get; set; }// 合計金額public decimal TotalAmount { get; set; }public override string ToString() =>$"[{OrderNumber}] {ProductName} x{Quantity} 総額:{TotalAmount:C}";} }
-
实现数据库服务类(
DatabaseHelper.cs
):using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace StarMauiPrinter.Services {public class DatabaseHelper{private readonly SQLiteAsyncConnection _connection;public DatabaseHelper(string dbName = "app.db3"){var dbPath = Path.Combine(FileSystem.AppDataDirectory, dbName);Console.WriteLine($"Database Path: {dbPath}");_connection = new SQLiteAsyncConnection(dbPath);}/// <summary>/// テーブルを作成する(ジェネリック)/// </summary>public Task CreateTableAsync<T>() where T : new(){return _connection.CreateTableAsync<T>();}/// <summary>/// 全てのレコードを取得する/// </summary>public Task<List<T>> GetAllAsync<T>() where T : new(){return _connection.Table<T>().ToListAsync();}/// <summary>/// 主キーIDでレコードを取得する/// </summary>public Task<T> GetByIdAsync<T>(int id) where T : new(){return _connection.FindAsync<T>(id);}/// <summary>/// レコードを挿入または更新する/// </summary>public async Task<int> SaveAsync<T>(T entity) where T : class{var type = typeof(T);var idProp = type.GetProperty("Id");var id = (int?)idProp?.GetValue(entity);if (id == 0){return await _connection.InsertAsync(entity);}var updated = await _connection.UpdateAsync(entity);var result = updated > 0 ? id.Value : 0;return result;}/// <summary>/// レコードを挿入する/// </summary>public Task<int> InsertAsync<T>(T entity) where T : new(){return _connection.InsertAsync(entity);}/// <summary>/// レコードを更新する/// </summary>public Task<int> UpdateAsync<T>(T entity) where T : new(){return _connection.UpdateAsync(entity);}/// <summary>/// レコードを削除する/// </summary>public Task<int> DeleteAsync<T>(T entity) where T : new(){return _connection.DeleteAsync(entity);}/// <summary>/// SQL文を実行してデータを取得する(クエリ)/// </summary>public Task<List<T>> QueryAsync<T>(string sql, params object[] args) where T : new(){return _connection.QueryAsync<T>(sql, args);}/// <summary>/// SQL文を実行する(非クエリ)/// </summary>public Task<int> ExecuteAsync(string sql, params object[] args){return _connection.ExecuteAsync(sql, args);}/ <summary>/ トランザクションを実行する/ </summary>//public Task RunInTransactionAsync(Action<SQLiteConnection> action)//{// return Task.Run(() =>// {// var syncConn = _connection.GetConnection();// syncConn.RunInTransaction(action);// });//}} }
-
定义類service類(OrderService.cs)
using StarMauiPrinter.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace StarMauiPrinter.Services {public class OrderService{private readonly DatabaseHelper _db;public OrderService(DatabaseHelper dbHelper){try{_db = dbHelper;_db.CreateTableAsync<Order>().Wait();}catch (Exception ex){throw;}}public Task<List<Order>> GetAllAsync(){try{return _db.GetAllAsync<Order>();}catch (Exception ex){throw;}}public Task<Order> GetByIdAsync(int id){try{return _db.GetByIdAsync<Order>(id);}catch (Exception ex){throw;}}public Task<int> SaveAsync(Order order){try{if (string.IsNullOrWhiteSpace(order.OrderNumber)){order.OrderNumber = $"ORD-{DateTime.Now:yyyyMMddHHmmss}-{Guid.NewGuid().ToString("N")[..4]}";}return _db.SaveAsync(order);}catch (Exception ex){throw;}}public Task<int> DeleteAsync(Order order){try{return _db.DeleteAsync(order);}catch (Exception ex){throw;}}public Task<List<Order>> QueryByCustomer(string customerName){try{return _db.QueryAsync<Order>("SELECT * FROM Order WHERE CustomerName = ?", customerName);}catch (Exception ex){throw;}}} }
3. 注册服务
在MauiProgram.cs
中注入数据库服务:
// sqlitebuilder.Services.AddSingleton<DatabaseHelper>();builder.Services.AddSingleton<OrderService>();builder.Services.AddSingleton<Order>();
二、整合Star打印机
1. 安装Star打印机SDK
通过NuGet安装官方或第三方SDK(需根据具体型号选择):
using StarMicronics.StarIO;
using StarMicronics.StarIOExtension;
using StarMicronics.StarIODeviceSetting;
# 示例包(需确认具体型号)
Install-Package StarIO_Extension
2. 实现跨平台打印服务
-
定义打印幫助類(
PrintService.cs
):using System; using System.Text; using System.Threading.Tasks; using System.Data; using System.Collections.Generic; using StarMicronics.StarIO; using StarMicronics.StarIOExtension; using StarMicronics.StarIODeviceSetting;namespace StarMauiPrinter.Services {/// <summary>/// STARプリンター操作用サービスクラス/// </summary>internal class PrintService{// プリンター接続情報 デフォルトIPアドレスpublic string PrinterIp { get; set; } = "192.168.11.75";// デフォルトポート番号public int PrinterPort { get; set; } = 9100;// タイムアウト設定(ミリ秒)private const int Timeout = 10000;/// <summary>/// プリンター接続情報を指定可能なコンストラクター/// </summary>/// <param name="printerIp">IPアドレス</param>/// <param name="printerPort">ポート番号</param>public PrintService(string printerIp = "192.168.11.75", int printerPort = 9100){PrinterIp = printerIp;PrinterPort = printerPort;}/// <summary>/// テスト用レシート印刷メソッド(非同期)/// </summary>/// <param name="portTimeout">接続タイムアウト時間</param>/// <returns>操作結果メッセージ</returns>public async Task<string> PrintTestReceipt(int portTimeout = Timeout){string portName = $"TCP:{PrinterIp}";string portSettings = "Standard";IPort port = null;try{// プリンターポートを取得port = Factory.I.GetPort(portName, portSettings, portTimeout);// 日本JIS X 9001規格に準拠した領収書コマンドを生成byte[] command = GenerateJapaneseReceipt();//byte[] command = GenerateJapaneseReceipt_StarPRNT();// 非同期印刷実行await Task.Run(() => port.WritePort(command, 0, (uint)command.Length));return "✅ 印刷が正常に完了しました!";}catch (PortException pEx){return $"❌ ハードウェア接続異常:\n•{pEx.Message}";}catch (EncoderFallbackException){return "❌ 文字コード異常:Shift_JIS非対応文字検出";}catch (Exception ex){return $"❌ システム例外:{ex.GetType().Name}\n{ex.Message}";}finally{if (port != null){// StarMicronics SDK仕様に基づきリソースを解放Factory.I.ReleasePort(port);port = null;}}}/// <summary>/// 日本の請求書仕様に準拠した印刷指示書を生成します/// </summary>private byte[] GenerateJapaneseReceipt(){// NOstring no = "NO.026";// 時間string formattedDateTime = DateTime.Now.ToString("yy/MM/dd (HH:mm)");// 担当者名string representative = "祐希";// お客様名string customer = "みおん";// 総合計string total = "10,000";// お支払string payment = "10,000";// 支払い方法string paymentType = "現金";// お預りstring deposit = "10,000";// お釣りstring change = "0";// セット料金string setfee = "10,000";// 小計string subtotal = "5,000";// プリンターの初期化List<byte> commands = new List<byte>();// ESC @ プリンターリセットcommands.AddRange(new byte[] { 0x1B, 0x40 });// 日本語Shift_JISエンコーディング設定Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);var shiftJis = Encoding.GetEncoding("Shift_JIS");commands.AddRange(new byte[] { 0x1B, 0x61, 0x01, 0x1D, 0x21, 0x11 });commands.AddRange(shiftJis.GetBytes($" 【御計算書】 {formattedDateTime} {no}\n"));// 担当者・顧客情報commands.AddRange(new byte[] { 0x1B, 0x61, 0x00 });commands.AddRange(shiftJis.GetBytes($"担当者:{representative} お客様:{customer} 様\n"));// 明細情報commands.AddRange(new byte[] { 0x1B, 0x61, 0x02 });commands.AddRange(shiftJis.GetBytes($"[4-L] 初期インデックス 21:56~\n\n" +$" 総合計: ¥{total}\n" +$"-----------------------------------------------\n" +$" お支払: {paymentType} ¥{payment}\n" +$" (お預り: ¥{deposit} お釣り: ¥{change})\n"));// 料金詳細セクションcommands.AddRange(new byte[] { 0x1B, 0x61, 0x02 });commands.AddRange(shiftJis.GetBytes($" セット料金: {setfee}\n" +$" ---------------------------\n" +$" 小計: {subtotal}\n"));// 終了処理 自動用紙切断コマンド(ESC V 66)commands.AddRange(new byte[] { 0x1D, 0x56, 0x41 });return commands.ToArray();}} }
-
注册平台服务:
在MauiProgram.cs
中添加:// PrintServicebuilder.Services.AddSingleton<PrintService>();
三、Blazor组件集成
1. 打印頁面Print.razor
@page "/print"
@inject Services.PrintService PrintService<h3>StarPrintTest</h3><button class="btn btn-primary" @onclick="PrintTest">印刷</button><p>@message</p>@code {private string message;private async Task PrintTest(){try{ // 印刷サービスを呼び出すmessage = await PrintService.PrintTestReceipt();}catch (Exception ex){message = $"エラー: {ex.Message}";}}
}
2. 數據操作頁面(Weather.razor)
@page "/weather"
@inject Services.OrderService OrderService
@using Microsoft.JSInterop
@inject IJSRuntime JS<h1>Weather</h1><div style="display: flex; align-items: center; gap: 10px;"><label for="orderNumber">ID:</label><input type="text" id="id" @bind="id" placeholder="IDを入力してください" /><button @onclick="SearchOrder">検索</button><button @onclick="ShowAddForm">新規</button><label style="color:red">@if (!string.IsNullOrEmpty(errorMessage)){@errorMessage}</label></div>@if (orders == null)
{<p><em>Loading...</em></p>
}
else
{<table class="table"><thead><tr><th>ID</th><th>订单番号</th><th>注文時間</th><th>商品番号</th><th>商品名称</th><th>単価</th><th>件数</th><th>担当者</th><th>お客様</th><th>支払い方法</th><th>最終支払い金額</th><th>操作</th></tr></thead><tbody>@foreach (var forecast in orders){<tr><td>@forecast.Id</td><td>@forecast.OrderNumber</td><td>@forecast.OrderTime</td><td>@forecast.ProductCode</td><td>@forecast.ProductName</td><td>@forecast.UnitPrice.ToString("N0") 円</td><td>@forecast.Quantity 件</td><td>@forecast.ResponsiblePerson</td><td>@forecast.CustomerName</td><td>@forecast.PaymentMethod</td><td>@forecast.TotalAmount.ToString("N0") 円</td><td><button @onclick="() => DeleteOrder(forecast)">削除</button><button @onclick="() => EditOrder(forecast)">変更</button></td></tr>}</tbody></table>
}<div class="modal fade @(showEditForm ? "show d-block" : "")" tabindex="-1" role="dialog" style="background-color: rgba(0,0,0,0.5);"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">@((newOrder?.Id ?? 0) == 0 ? "新規注文" : "注文の編集")</h5><button type="button" class="btn-close" aria-label="Close" @onclick="CancelEdit"></button></div><div class="modal-body"><EditForm Model="newOrder" OnValidSubmit="SaveOrder"><DataAnnotationsValidator /><ValidationSummary /><div class="mb-2"><label>注文番号</label><InputText class="form-control" @bind-Value="newOrder.OrderNumber" /></div><div class="mb-2"><label>注文時間</label><InputText class="form-control" @bind-Value="newOrder.OrderTime" @bind-Value:format="yyyy-MM-dd" />@* <InputDate @bind-Value="newOrder.OrderTime" /> *@@* <InputText type="datetime-local" class="form-control" @bind-Value="newOrder.OrderTime" @bind-Value:format="yyyy/MM/dd HH:mm" /> *@</div><div class="mb-2"><label>商品番号</label><InputText class="form-control" @bind-Value="newOrder.ProductCode" /></div><div class="mb-2"><label>商品名称</label><InputText class="form-control" @bind-Value="newOrder.ProductName" /></div><div class="mb-2"><label>単価</label><InputNumber class="form-control" @bind-Value="newOrder.UnitPrice" /></div><div class="mb-2"><label>件数</label><InputNumber class="form-control" @bind-Value="newOrder.Quantity" /></div><div class="mb-2"><label>担当者</label><InputText class="form-control" @bind-Value="newOrder.ResponsiblePerson" /></div><div class="mb-2"><label>お客様</label><InputText class="form-control" @bind-Value="newOrder.CustomerName" /></div><div class="mb-2"><label>支払い方法</label><InputText class="form-control" @bind-Value="newOrder.PaymentMethod" /></div><div class="mb-2"><label>最終支払い金額</label><InputNumber class="form-control" @bind-Value="newOrder.TotalAmount" /></div><div class="modal-footer"><button type="submit" class="btn btn-primary">保存</button><button type="button" class="btn btn-secondary" @onclick="CancelEdit">取消</button></div></EditForm></div></div></div>
</div>@code {private List<Models.Order> orders;private string id = "";private string errorMessage = "";private bool showEditForm = false;private Models.Order newOrder = new Models.Order();protected override async Task OnInitializedAsync(){await LoadDataAsync();}private async Task LoadDataAsync(){orders = await OrderService.GetAllAsync();}private async Task DeleteOrder(Models.Order order){var isConfirmed = await JS.InvokeAsync<bool>("confirm", "本当に削除しますか?");if (isConfirmed){clearMassg();await OrderService.DeleteAsync(order);await LoadDataAsync();}}private void clearMassg(){errorMessage = string.Empty;}private async Task SearchOrder(){clearMassg();if (!string.IsNullOrEmpty(id)){if (!int.TryParse(id, out int outid)){errorMessage = "IDは数字でなければなりません";id = string.Empty;return;}var order = await OrderService.GetByIdAsync(Convert.ToInt32(id));if (order != null){orders = new List<Models.Order> { order };}else{orders = new List<Models.Order>();}}else{await LoadDataAsync();}}private void ShowAddForm(){clearMassg();newOrder = new Models.Order();showEditForm = true;}private void EditOrder(Models.Order order){clearMassg();newOrder = new Models.Order{Id = order.Id,OrderNumber = order.OrderNumber,OrderTime = order.OrderTime,ProductCode = order.ProductCode,ProductName = order.ProductName,UnitPrice = order.UnitPrice,Quantity = order.Quantity,ResponsiblePerson = order.ResponsiblePerson,CustomerName = order.CustomerName,PaymentMethod = order.PaymentMethod,TotalAmount = order.TotalAmount};showEditForm = true;}private async Task SaveOrder(){await OrderService.SaveAsync(newOrder);showEditForm = false;newOrder = new Models.Order();await LoadDataAsync();}private void CancelEdit(){clearMassg();showEditForm = false;}
}
关键注意事项
- 数据库事务:在批量操作时使用
BeginTransaction
提升性能。 - 打印机兼容性:不同型号Star打印机需调整指令格式(如ESC/POS指令集)。
- 异步处理:避免在UI线程执行耗时操作(如数据库查询、打印任务)。
- 错误处理:捕获SQLite和打印机连接中的异常,确保应用稳定性。
相关文章:
隨筆 20250519 基于MAUI Blazor整合SQLite数据库与Star打印机的详细步骤
以下是基于MAUI Blazor整合SQLite数据库与Star打印机的详细步骤,包含必要的NuGet包引入及核心代码实现: 零、目錄結構 一、整合SQLite数据库 1. 安装NuGet包 # SQLite核心库 Install-Package sqlite-net-pcl # SQLite平台适配库&am…...
电子电路原理第十六章(负反馈)
1927年8月,年轻的工程师哈罗德布莱克(Harold Black)从纽约斯塔顿岛坐渡轮去上班。为了打发时间,他粗略写下了关于一个新想法的几个方程式。后来又经过反复修改, 布莱克提交了这个创意的专利申请。起初这个全新的创意被认为像“永动机”一样愚蠢可笑,专利申请也遭到拒绝。但…...
推客小程序系统开发:全栈式技术解决方案与行业赋能实践
在数字化营销深度渗透各行业的当下,传统推广模式已难以满足企业精细化运营与高效获客的需求。专业的推客小程序系统凭借其强大的裂变传播能力与灵活的推广机制,成为企业构建私域流量池、提升推广效能的核心工具。我们基于多年技术沉淀与行业洞察&…...
【prometheus+Grafana篇】基于Prometheus+Grafana实现Oracle数据库的监控与可视化
💫《博主主页》: 🔎 CSDN主页 🔎 IF Club社区主页 🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了…...
【Android构建系统】Soong构建系统,通过.bp + .go定制编译
背景介绍 本篇是一篇实操内容,是对【Android构建系统】如何在Camera Hal的Android.bp中选择性引用某个模块的优化与改进。本篇内容主要想通过一个具体例子介绍Soong构建系统较复杂的定制化方法和步骤,以便在今后的工作学习中更好的使用Soong构建系统。 …...
Qt开发:QUdpSocket的详解
文章目录 一、QUdpSocket 简介二、常用函数的介绍和使用三、接收端完整示例四、发送端完整示例 一、QUdpSocket 简介 在 Qt 中,UDP(User Datagram Protocol,用户数据报协议)是通过 QUdpSocket 类实现的。UDP 是一种无连接的、轻量…...
【android bluetooth 协议分析 01】【HCI 层介绍 9】【ReadLocalSupportedCommands命令介绍】
1. HCI_Read_Local_Supported_Commands 命令介绍 1. 命令介绍(Description) HCI_Read_Local_Supported_Commands 是 HCI 层中非常重要的查询命令。它允许 Host(如 Android 系统中的 Bluetooth stack)获取 Controller(…...
Model 速通系列(一)nanoGPT
这个是新开的一个系列用来手把手复现一些模型工程,之所以开这个系列是因为有人留言说看到一个工程不知道从哪里读起,出于对自身能力的提升与兴趣,故新开了这个系列。由于主要动机是顺一遍代码并提供注释。 该系列第一篇博客是 nanoGPT &…...
星际争霸小程序:用Java实现策略模式的星际大战
在游戏开发的世界里,策略模式是一种非常实用的设计模式,它允许我们在运行时动态地选择算法或行为。今天,我将带你走进一场星际争霸的奇幻之旅,用Java实现一个简单的星际争霸小程序,通过策略模式来模拟不同种族单位的战…...
网络Tips20-007
网络威胁会导致非授权访问、信息泄露、数据被破坏等网络安全事件发生, 其常见的网络威胁包括窃听、拒绝服务、病毒、木马、( 数据完整性破坏 )等, 常见的网络安全防范措施包括访问控制、审计、身份认证、数字签名、( 数据加密 )、 包过滤和检测等。 AE…...
2.微服务-配置
引入springcloud的pom配置 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/></parent> <dependencyManagemen…...
python实现pdf转图片(针对每一页)
from pdf2image import convert_from_path import ospdf_file rC:\Users\\Desktop\拆分\产权证.pdf poppler_path rC:\poppler-24.08.0\Library\bin # 这里改成你自己的路径output_dir rC:\Users\\Desktop\拆分\output_images os.makedirs(output_dir, exist_okTrue)image…...
Python编程从入门到实践 PDF 高清版
各位程序员朋友们,还在为找不到合适的Python学习资料而烦恼吗?还在为晦涩难懂的编程书籍而头疼吗?今天,就给大家带来一份重磅福利——237完整版PDF, 我用网盘分享了「Python编程:从入门到实践__超清版.pdf…...
CVE-2015-3934 Fiyo CMS SQL注入
CVE-2015-3934 Fiyo CMS SQL注入 页面抓登录数据包 构造延时注入语句在user处’%2B(select(0)from(select(sleep(5)))v)%2B’ 存在延时注入,使用脚本即可...
【Pandas】pandas DataFrame mode
Pandas2.2 DataFrame Computations descriptive stats 方法描述DataFrame.abs()用于返回 DataFrame 中每个元素的绝对值DataFrame.all([axis, bool_only, skipna])用于判断 DataFrame 中是否所有元素在指定轴上都为 TrueDataFrame.any(*[, axis, bool_only, skipna])用于判断…...
(思维题、贪心)洛谷 P11232 CSPS2024 超速检测 题解
这一题在 2024 将我击败,但我怎么现在才补题解 …… 题意 原题 思路 对于每一辆车,我们可以算出,其在距离左端点哪段位置会超速 [ l , r ] [l,r] [l,r],那么这辆车会被 l l l 右侧最近的测速仪到 r r r 左侧最近的测速仪检…...
C#:多线程
一.线程常用概念 线程(Thread):操作系统执行程序的最小单位 进程(Process):程序在内存中的运行实例 并发(Concurrency):多个任务交替执行(单核CPU࿰…...
虚拟币制度钱包开发:功能设计与成本全解析
虚拟币制度钱包开发:功能设计与成本全解析 ——从基础架构到合规风控的完整解决方案 一、开发成本:分层定价与关键影响因素 根据2024-2025年行业数据显示,虚拟币钱包App开发成本跨度较大,主要受功能复杂度、技术架构与合规要求三…...
TransmittableThreadLocal实现上下文传递-笔记
1.TransmittableThreadLocal简介 com.alibaba.ttl.TransmittableThreadLocal(简称 TTL)是阿里巴巴开源的一个工具类,旨在解决 ThreadLocal 在线程池中无法传递上下文变量 的问题。它是对 InheritableThreadLocal 的增强,尤其适用…...
应对WEEE 2025:猎板PCB的区块链追溯与高温基材创新
在全球电子产业加速向循环经济转型的背景下,欧盟《绿色新政》与《WEEE指令》对PCB行业提出更高要求。作为行业先行者,猎板PCB(Hunter PCB)以生物降解基材为核心,结合全球合规体系与产业链协同创新,构建从材…...
大陆资产在香港发行RWA的合规路径与核心限制
大陆资产在香港发行RWA的合规路径与核心限制 ——从“双重合规原则”到资产准入边界的全景解读 一、法律框架:双重合规原则的刚性约束 根据香港金管局Ensemble沙盒项目要求,大陆资产在香港发行RWA需遵循“双重合规原则”,即底层资产需同时符…...
爬虫攻防战:从入门到放弃的完整对抗史与实战解决方案
爬虫攻防战:从入门到放弃的完整对抗史与实战解决方案 这张有趣的图片生动描绘了爬虫开发者与反爬工程师之间的"军备竞赛"。作为技术博主,我将基于这张图的各个阶段,深入分析爬虫技术的演进与对应的反制措施,提供一套完整的反爬解决方案,包括技术原理、实施方法…...
Fabric初体验(踩坑笔记)
搭建fabric部署合约学习笔记 环境准备CURl安装docker 参照官网文档实现(2025.05.19)根据前言交代的文章去尝试(失败版)安装fabric-samples安装指定2.2.0版本Fabric二进制文件和配置文件直接手动下载(不建议)…...
区块链blog2_中心化与效率
🌿中心化出现原因 信息/服务分散在各处会浪费时间且不方便使用,由此,把信息/服务集中在一起,便于管理,避免了不必要的效率损失。 即集中资源,使得对信息处理的全过程效率升高。中心化不是网络中产生的&…...
2024年ASOC SCI2区TOP,多机制群优化算法+多风场输电线路巡检中多无人机任务分配与路径规划,深度解析+性能实测
目录 1.摘要2.考虑风场影响的多无人机任务分配3.基于双向蚁群和离散蜜獾算法求解多无人机任务分配问题(BACOHBA)4.考虑风场的多无人机路径规划5.结果展示6.参考文献7.代码获取8.读者交流 1.摘要 随着电力系统规模的不断扩大,复杂环境下的电力线路及设施的巡检与维护…...
智慧赋能光伏运维——无人机巡检+地面监控双链路覆盖,打造光伏电站管理新标杆
一、引言:光伏电站运维的挑战与机遇 在全球能源转型浪潮下,光伏电站作为清洁能源的重要载体,其高效运维管理成为行业核心命题。然而,传统光伏电站运维存在覆盖范围广、设备分散、人工巡检效率低、故障响应慢等痛点。为破解这一难…...
c/c++的opencv开闭操作
OpenCV 中的形态学开运算与闭运算 (C) 在计算机视觉和图像处理领域,形态学操作是用于分析和处理图像形状的一系列非线性操作。OpenCV 作为一个强大的开源计算机视觉库,提供了丰富的形态学转换函数。其中,“开运算”(Opening&…...
Linux利用多线程和线程同步实现一个简单的聊天服务器
1. 概述 本文实现一个基于TCP/IP的简单多人聊天室程序。它包含一个服务器端和一个客户端:服务器能够接收多个客户端的连接,并将任何一个客户端发来的消息广播给所有其他连接的客户端;客户端则可以连接到服务器,发送消息并接收来自…...
无人机遥控器光纤通信模块技术要点!
一、技术要点 1. 长距离低损耗传输 采用单模光纤(如G.654.E光纤),利用光纤的低衰减特性(0.17 dB/km以下),支持10公里以上的远距离通信,突破了传统无线信号因衰减导致的覆盖限制。例如&…...
深入解析OkHttp与Retrofit:Android网络请求的黄金组合
前言 在移动应用开发中,网络请求是连接客户端与服务器的关键桥梁。对于Android开发者而言,OkHttp和Retrofit这对组合已经成为处理网络请求的事实标准。本文将全面剖析这两个框架的设计理念、核心功能、协同关系以及最佳实践,帮助开发者构建高…...
Python操作PDF书签详解 - 添加、修改、提取和删除
目录 简介 使用工具 Python 向 PDF 添加书签 添加书签 添加嵌套书签 Python 修改 PDF 书签 Python 展开或折叠 PDF 书签 Python 提取 PDF 书签 Python 删除 PDF 书签 简介 PDF 书签是 PDF 文件中的导航工具,通常包含一个标题和一个跳转位置(如…...
Spring Boot与Kafka集成实践:从入门到实战
Spring Boot与Kafka集成实践 引言 在现代分布式系统中,消息队列是不可或缺的组件之一。Apache Kafka作为一种高吞吐量的分布式消息系统,广泛应用于日志收集、流处理、事件驱动架构等场景。Spring Boot作为Java生态中最流行的微服务框架,提供…...
luckysheet的使用——17.将表格作为pdf下载到本地
luckysheet源码里面自带有打印按钮,但是功能是无法使用的,所以我把该功能重写了一遍 1.在menuButton.js文件中找到源码打印按钮的触发事件: $("#luckysheet-icon-print").click(function () {}2.使用自己写的挂载方法 window.pr…...
矿井支架LCYVB-6钢丝编织护套连接器介绍
LCYVB-6钢丝编织护套连接器是一种专为矿井支架设计的连接装置,主要用于增强支架的稳定性和安全性。该连接器采用高强度钢丝编织护套,具有优异的抗拉强度和耐磨性,适用于恶劣的矿井环境。 主要特点 高强度钢丝编织护套:采用优质钢…...
git仓库中.git 文件很大,怎么清理掉一部分
查询 .git 文件大小,在 git-bash 里执行(后面有些命令不能执行,也请在 git-bash 里执行) windows11 安装好后右键没有 git bash 命令-CSDN博客 du -sh .git // 592m .git 操作前最好先备份一份,避免推送到远程时出错…...
Qt框架核心组件完全指南:从按钮交互到定时器实现
文章目录 前言一、QAbstractButton 按钮类概述1.1 常用属性1.2 常用信号1.3QButtonGroup 按钮组 二、QComboBox 组合框三、若干与数字相关的组件四、QString 字符串类五、Qt容器类5.1 顺序容器 QList5.2 关联容器 QMap 六、QVariant七、跨平台数据类型7.1 基础数据类型7.2 特殊…...
Axure设计数字乡村可视化大屏:从布局到交互的实战经验分享
乡村治理正从传统模式向“数据驱动”转型。数字乡村可视化大屏作为数据展示的核心载体,不仅能直观呈现乡村发展全貌,还能为决策提供科学依据。本文以Axure为工具,结合实际案例,分享如何从零设计一个功能完备、交互流畅的数字乡村大…...
60天python训练计划----day30
DAY 30 模块和库的导入 知识点回顾: 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致) 一.导入官方库 我们复盘下学习python的逻辑,所谓学习pyth…...
HJ3 明明的随机数【牛客网】
文章目录 零、原题链接一、题目描述二、测试用例三、解题思路3.1 快排去重3.2 散列 四、参考代码4.1 快排去重4.2 散列 零、原题链接 HJ3 明明的随机数 一、题目描述 二、测试用例 三、解题思路 3.1 快排去重 基本思路: 先将序列进行快速排序,然后…...
BGP选路
一、拓扑图 二、要求及分析 1.要求 1.使用Preva1策略,确保R4通过R2到达192.168.10.0/24 2、用As Path策略,确保R4通过R3到达192.168.11.0/24 3.配置MED策略,确保R4通过R3到达192.168.12.0/24 4.使用Local Preference策略,确保…...
践行“科学智能”!和鲸打造 AI for Science 专属应用
AI for good, AI for Science. 在传统科研领域,人力与经验的局限始终如影随形。而“AI for Science”正逐渐改变科学研究的模式,以科学数据为基石、以强大算力为支撑,借助人工智能技术,开展计算密集度高且能够实现高效迭代的科学…...
【vs2022的C#窗体项目】打开运行+sql Server改为mysql数据库+发布
1. vs2022打开运行原sql Server的C#窗体项目更改为mysql数据库 1.1. vs2022安装基础模块即可 安装1️⃣vs核心编辑器2️⃣.net桌面开发必选,可选均不安装!!! 为了成功连接mysql数据库,需要安装组件NuGet包管理器 安…...
wpf DataGrid 行选择事件
在WPF中处理DataGrid行选择事件主要有以下几种实现方式: 1.SelectionChanged事件处理 通过直接订阅DataGrid的SelectionChanged事件实现行选择响应: <DataGrid SelectionChanged="DataGridAccurateLocationList_SelectionChanged" .../>后台代码中处理…...
Spring Cloud Seata 深度解析:原理与架构设计
文章目录 前言:为什么我们需要理解分布式事务?一、Seata 核心架构深度拆解1.1 分布式事务核心模型1.2 Seata undo_log 存储结构与版本控制存储结构版本控制核心算法 1.3 Seata 事务模型深度对比与实现原理AT 模式(Auto Transaction࿰…...
从产品展示到工程设计:3DXML 转 STP 的跨流程数据转换技术解析
在数字化设计与制造领域,不同格式的三维模型文件常常需要进行转换,以满足不同软件和工作流程的需求。3DXML 和 STP(STEP AP214/AP242)是工业领域常用的两种三维模型文件格式,3DXML 格式以其轻量化和便于网络传输、可视…...
基于RT-Thread的STM32F4开发第五讲——软件模拟I2C
文章目录 前言一、RT-Thread工程创建二、AT24C02三、函数编写1.I2C_soft.c2.I2C_soft.h3.main.h 四、效果展示五、资源分享总结 前言 本章是基于RT-Thread studio实现软件模拟I2C,开发板是正点原子的STM32F4探索者,使用的RT-Thread驱动是5.1.0࿰…...
pkucpc2025 L:Game on Tree
题意 两个人在一棵无根树上玩游戏,每次可以删掉若干个叶子节点,不能操作的人输。 思路 比赛的时候我去写H Quintuple了,队友貌似在我写的时候把这道题讨论出来了。 后来补题的时候花了大概花了70分钟左右ac这道题。 首先考虑一条链的情况…...
大数据实时分析:ClickHouse、Doris、TiDB 对比分析
随着企业对数据分析实时性、复杂性和多样性的要求越来越高,传统的批处理数仓已经无法满足实时指标看板、流量监控、用户行为分析等场景需求。因此,越来越多的公司开始引入实时分析型数据库系统。 目前,国内外常见的实时分析数据库有: ClickHouse:列式数据库,极致的分析性…...
网络流量分析系统的十大应用场景
在现代企业和组织的IT运维体系中,网络流量分析系统(Network Traffic Analysis, NTA)早已不仅仅是用来查看带宽使用率的“流量计数器”。随着网络环境的复杂化、攻击技术的不断演进,以及对业务连续性要求的提升,网络流量…...
问题 | 代码审查:函数是否包含返回语句
“函数是否包含返回语句”这一问题的核心是:在编程中,函数是否按照设计要求正确使用了 返回语句(如 return、return value),以便向调用者传递结果或控制权。以下是详细解释: 1. 什么是函数的返回语句&#…...