151 lines
3.7 KiB
Markdown
151 lines
3.7 KiB
Markdown
# Adminive Backend-Driven CRUD And Lazy Status Demo
|
||
|
||
Adminive 使用 C++20 模板、Concepts、成员指针和 `magic_enum` 描述业务类型。同一份类型描述驱动对象与 JSON 双向转换、事务式赋值、字段权限、后端校验和 amis CRUD Schema。前端只读取 `/admin/amis` 并渲染后端返回的页面 JSON,不包含业务字段、状态字段或刷新策略。
|
||
|
||
## 列字段描述
|
||
|
||
字段的数据名、表单标签和列表表头分别描述:
|
||
|
||
```cpp
|
||
ADMINIVE_FIELD(T, buffer_count)
|
||
.label("Buffer Count")
|
||
.list_label("Buffers")
|
||
.order(10)
|
||
.sortable();
|
||
```
|
||
|
||
- `name` 来自成员名称,用于 JSON 字段和接口参数。
|
||
- `label` 用于表单和字段说明。
|
||
- `list_label` 只用于列表表头,未设置时回退到 `label`。
|
||
- `order` 控制列表列顺序,未设置时按字段声明顺序生成默认值。
|
||
- `sortable` 默认关闭,开启后后端接受 `orderBy` 和 `orderDir` 并执行排序。
|
||
|
||
## 对象状态模型
|
||
|
||
对象状态使用独立返回类型描述,不再混入 CRUD 对象字段:
|
||
|
||
```cpp
|
||
struct Radio_Item_Status {
|
||
Status_Value<Radio_Operating_State> operating_state;
|
||
Status_Value<std::uint64_t> refresh_sequence;
|
||
Status_Value<std::string> refresh_time;
|
||
};
|
||
```
|
||
|
||
`Status_Value<T>` 同时携带值和颜色:
|
||
|
||
```json
|
||
{
|
||
"operating_state": {
|
||
"value": "running",
|
||
"color": "#16a34a"
|
||
}
|
||
}
|
||
```
|
||
|
||
状态类型生成独立 JSON 模式:
|
||
|
||
```text
|
||
GET /admin/radio_states/status/descriptor
|
||
```
|
||
|
||
协议名为 `adminive.status`,每个字段包含名称、标签、值类型以及是否支持颜色。
|
||
|
||
## 注册对象状态函数
|
||
|
||
业务对象提供无参数成员函数,返回已描述的状态类型:
|
||
|
||
```cpp
|
||
Radio_Item_Status Radio_State::status();
|
||
```
|
||
|
||
资源通过成员函数指针注册:
|
||
|
||
```cpp
|
||
adminive::Http_Collection_Resource<Radio_State> resource(
|
||
"/admin/radio_states",
|
||
std::move(initial),
|
||
"/admin/status"
|
||
);
|
||
resource.register_status<&Radio_State::status>(2000);
|
||
resource.bind(server);
|
||
```
|
||
|
||
注册后自动生成:
|
||
|
||
```text
|
||
GET /admin/radio_states/status/descriptor
|
||
GET /admin/radio_states/{id}/status
|
||
```
|
||
|
||
表格只显示 `View status ▾`。用户点击并打开状态 PopOver 后,其中的 amis `service` 才首次请求对象状态并按注册周期刷新。关闭 PopOver 后该状态视图被卸载,不再显示,也不通过 CRUD 列表轮询对象状态。普通 CRUD 列表本身不配置定时轮询。
|
||
|
||
## 前端
|
||
|
||
```powershell
|
||
cd frontend
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
开发地址为 `http://127.0.0.1:5173`,Vite 将 `/admin` 代理到 `http://127.0.0.1:9999`。
|
||
|
||
生产构建:
|
||
|
||
```powershell
|
||
cd frontend
|
||
npm run build
|
||
```
|
||
|
||
输出目录:
|
||
|
||
```text
|
||
frontend_dist
|
||
```
|
||
|
||
## 后端
|
||
|
||
```powershell
|
||
cmake -S . -B build -G Ninja
|
||
cmake --build build
|
||
ctest --test-dir build --output-on-failure
|
||
./build/backend/Adminive_Server.exe 9999
|
||
```
|
||
|
||
访问 `http://127.0.0.1:9999`。
|
||
|
||
## API
|
||
|
||
```text
|
||
GET /admin/amis
|
||
GET /admin/status
|
||
GET /admin/radio_states/descriptor
|
||
GET /admin/radio_states/status/descriptor
|
||
GET /admin/radio_states/amis
|
||
GET /admin/radio_states
|
||
GET /admin/radio_states/{id}
|
||
GET /admin/radio_states/{id}/status
|
||
POST /admin/radio_states
|
||
PUT /admin/radio_states/{id}
|
||
PATCH /admin/radio_states/{id}
|
||
DELETE /admin/radio_states/{id}
|
||
```
|
||
|
||
## 源码压缩目标
|
||
|
||
```powershell
|
||
cmake --build build --target package_zip
|
||
```
|
||
|
||
输出文件位置由 `add_project_zip_target` 第二个参数明确指定:
|
||
|
||
```cmake
|
||
add_project_zip_target(
|
||
package_zip
|
||
"${CMAKE_CURRENT_LIST_DIR}/Adminive.zip"
|
||
adminive_package_excludes
|
||
)
|
||
```
|
||
|
||
第三个参数是排除规则列表的变量名,函数内部解析列表内容。相对输出路径以 `cmake/PackageZip.cmake` 所在目录为基准。
|