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 管理系统。
