MAUI 嵌入式 Web 架构实战中,如何构建完整的 Web Admin 管理后台?

摘要:MAUI 嵌入式 Web 架构实战(五) 使用 PicoServer 构建完整 Web Admin 管理后台 源码地址 https:github.comdensen2014MauiPicoAdmin 一、从 API Server 到
MAUI 嵌入式 Web 架构实战(五) 使用 PicoServer 构建完整 Web Admin 管理后台 源码地址 https://github.com/densen2014/MauiPicoAdmin 一、从 API Server 到完整应用 在前几篇文章中,我们已经逐步构建了 PicoServer 在 MAUI 中的核心能力: 第一篇 在 MAUI 中嵌入 PicoServer 本地 Web 服务。 第二篇 实现 PicoServer 路由机制与 API 设计。 第三篇 构建可扩展的 REST API 架构: Controller Service Model 第四篇 实现静态文件托管,让 PicoServer 可以运行 Web 页面。 此时我们的系统已经具备: 本地 Web Server 本地 REST API 本地 Web 前端 也就是说: 一个完整 Web 应用的基础设施已经具备。 接下来我们要做一件更重要的事情: 构建真正可用的 Web Admin 管理后台 例如: 商品管理 设备管理 系统配置 日志查看 最终效果类似: localhost:8090 ↓ Admin Dashboard ↓ API ↓ MAUI 本地逻辑 二、Web Admin 架构 在 PicoServer + MAUI 架构下,一个完整后台系统结构如下: ┌─────────────────────┐ │ Web Admin │ │ Vue / React / UI │ └──────────▲──────────┘ │ fetch │ ┌──────────┴──────────┐ │ PicoServer │ │ Static + REST │ └──────────▲──────────┘ │ ┌──────┴──────┐ │ Controller │ └──────▲──────┘ │ ┌──────┴──────┐ │ Service │ └──────▲──────┘ │ ┌──────┴──────┐ │ MAUI Logic │ └─────────────┘ 核心思想: UI 使用 Web 技术 API 使用 PicoServer 逻辑使用 C# 这种模式在很多系统中都非常常见,例如: 工业设备系统 IoT 管理平台 本地控制系统 嵌入式设备后台 三、选择 Admin UI 框架 开发后台界面通常不需要从零开始。 可以直接使用成熟的 Admin UI。 推荐几个常用方案: Bootstrap Admin 最简单方案: Bootstrap Chart.js jQuery 适合: 轻量后台 快速开发 Vue Admin 常见方案: Vue Element Plus Vite 优点: 组件丰富 开发效率高 生态成熟 React Admin 技术栈: React Ant Design 适合: 复杂系统 大型后台 在本系列中,为了简单,我们先使用: 原生 HTML + Bootstrap 后续可以升级到 Vue。 四、创建 Admin 页面 在 wwwroot 目录创建: wwwroot ├─ index.html ├─ product.html ├─ css └─ js index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>PicoServer Admin</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body class="container"> <h1 class="mt-4">PicoServer Admin</h1> <div class="mt-4"> <a href="product.html" class="btn btn-primary"> 商品管理 </a> </div> </body> </html> 访问: http://localhost:8090 就可以看到后台首页。 五、商品管理页面 创建: product.html 页面结构 <h2>商品管理</h2> <button onclick="loadProducts()"> 加载商品 </button> <table id="table"> <thead> <tr> <th>ID</th> <th>名称</th> <th>价格</th> </tr> </thead> <tbody></tbody> </table> 六、调用 API 加载数据 添加 JavaScript: async function loadProducts() { let res = await fetch("/api/product/list"); let json = await res.json(); let list = json.data; let tbody = document.querySelector("#table tbody"); tbody.innerHTML = ""; for(let p of list) { let row = ` <tr> <td>${p.id}</td> <td>${p.name}</td> <td>${p.price}</td> </tr> `; tbody.innerHTML += row; } } 此时: 页面 ↓ fetch API ↓ PicoServer ↓ 返回 JSON ↓ 渲染表格 七、API 实现 Controller: public async Task List(HttpListenerRequest req, HttpListenerResponse res) { var data = service.GetProducts(); var result = ApiResult.Success(data); string json = JsonSerializer.Serialize(result); res.ContentType = "application/json"; await res.WriteAsync(json); } Service: public List<object> GetProducts() { return new List<object> { new { id = 1, name = "Apple", price = 10 }, new { id = 2, name = "Orange", price = 8 } }; } 页面完整代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>PicoServer Admin</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body class="bg-light"> <div class="container py-5"> <div class="row justify-content-center"> <div class="col-lg-8"> <div class="card shadow-sm"> <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center"> <h4 class="mb-0">商品管理</h4> <button onclick="loadProducts()" class="btn btn-light btn-sm"> <span class="bi bi-arrow-repeat"></span> 加载商品 </button> </div> <div class="card-body"> <div id="spinner" class="text-center my-3" style="display:none;"> <div class="spinner-border text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> </div> <div class="table-responsive"> <table id="table" class="table table-striped table-hover align-middle"> <thead class="table-primary"> <tr> <th>ID</th> <th>名称</th> <th>价格</th> </tr> </thead> <tbody></tbody> </table> </div> </div> </div> </div> </div> </div> <script> async function loadProducts() { document.getElementById("spinner").style.display = "block"; let res = await fetch("/api/product/list"); let json = await res.json(); let list = json.data; let tbody = document.querySelector("#table tbody"); tbody.innerHTML = ""; for (let p of list) { let row = ` <tr> <td>${p.id}</td> <td>${p.name}</td> <td>${p.price}</td> </tr> `; tbody.innerHTML += row; } document.getElementById("spinner").style.display = "none"; } </script> </body> </html> 八、增加 CRUD 功能 后台系统通常需要完整 CRUD。 例如: 新增商品 编辑商品 删除商品 查询商品 API 示例: GET /api/product/list GET /api/product/detail?id=1 POST /api/product/add POST /api/product/delete 前端调用: fetch("/api/product/add") fetch("/api/product/delete") 九、Admin 后台最终效果 完成后系统结构如下: localhost:8090 后台页面: 首页 商品管理 系统配置 调用流程: Web UI ↓ fetch API ↓ PicoServer ↓ Controller ↓ Service ↓ MAUI Logic 此时你的 MAUI 应用实际上已经变成: 一个完整 Web 应用容器 十、为什么这种架构非常强 这种架构在很多场景下非常有优势。 例如: 1 工业设备系统 设备控制 参数配置 日志查看 2 IoT 系统 设备管理 数据展示 远程控制 3 本地管理后台 库存系统 POS系统 离线业务系统 4 跨平台 UI 同一套 Web UI 可以运行在: Windows Android iOS Mac Linux 十一、WebView App 壳 在 MAUI 中可以直接嵌入: <WebView Source="http://127.0.0.1:8090" /> 应用结构: MAUI App ↓ WebView ↓ PicoServer ↓ Web Admin 这就是: Local Web Shell 架构 很多桌面应用其实都在使用类似架构,例如: VS Code Slack Notion 十二、本篇总结 本篇我们完成了整个系列的重要里程碑: 构建完整 Web Admin 管理后台 实现内容包括: Admin Dashboard 页面 商品管理 CRUD 示例 API 与前端联动 完整 Web Admin 架构 此时我们的 MAUI 应用已经具备: 本地 Web Server 本地 API 本地 Web UI 完整 Admin 系统 下一篇预告 接下来我们将继续升级系统: MAUI 嵌入式 Web 架构实战(六) Web Admin 权限系统与登录认证 我们将实现: 用户登录 Token 认证 权限控制 登录拦截 API 鉴权 最终实现一个 真正可用的 Admin 管理系统。