a0ca831a0008bb7ac0eccf41a929a546b6ed4d4a
Adminive Backend-Driven CRUD And Lazy Status Demo
Adminive 使用 C++20 模板、Concepts、成员指针和 magic_enum 描述业务类型。同一份类型描述驱动对象与 JSON 双向转换、事务式赋值、字段权限、后端校验和 amis CRUD Schema。前端只读取 /admin/amis 并渲染后端返回的页面 JSON,不包含业务字段、状态字段或刷新策略。
列字段描述
字段的数据名、表单标签和列表表头分别描述:
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 对象字段:
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> 同时携带值和颜色:
{
"operating_state": {
"value": "running",
"color": "#16a34a"
}
}
状态类型生成独立 JSON 模式:
GET /admin/radio_states/status/descriptor
协议名为 adminive.status,每个字段包含名称、标签、值类型以及是否支持颜色。
注册对象状态函数
业务对象提供无参数成员函数,返回已描述的状态类型:
Radio_Item_Status Radio_State::status();
资源通过成员函数指针注册:
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);
注册后自动生成:
GET /admin/radio_states/status/descriptor
GET /admin/radio_states/{id}/status
表格只显示 View status ▾。用户点击并打开状态 PopOver 后,其中的 amis service 才首次请求对象状态并按注册周期刷新。关闭 PopOver 后该状态视图被卸载,不再显示,也不通过 CRUD 列表轮询对象状态。普通 CRUD 列表本身不配置定时轮询。
前端
cd frontend
npm install
npm run dev
开发地址为 http://127.0.0.1:5173,Vite 将 /admin 代理到 http://127.0.0.1:9999。
生产构建:
cd frontend
npm run build
输出目录:
frontend_dist
后端
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
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}
源码压缩目标
cmake --build build --target package_zip
输出文件位置由 add_project_zip_target 第二个参数明确指定:
add_project_zip_target(
package_zip
"${CMAKE_CURRENT_LIST_DIR}/Adminive.zip"
adminive_package_excludes
)
第三个参数是排除规则列表的变量名,函数内部解析列表内容。相对输出路径以 cmake/PackageZip.cmake 所在目录为基准。
Description
Languages
C++
81.2%
CMake
7.8%
TypeScript
7%
CSS
2.2%
Python
1.1%
Other
0.6%