259 lines
8.0 KiB
C++
259 lines
8.0 KiB
C++
#pragma once
|
|
#include "adminive/adminive.hpp"
|
|
#include "adminive/adapters/httplib.hpp"
|
|
#include "adminive/adapters/magic_enum.hpp"
|
|
#include "adminive/adapters/nlohmann_json.hpp"
|
|
#include <chrono>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <utility>
|
|
#include <variant>
|
|
namespace adminive::example {
|
|
using Json = nlohmann::json;
|
|
inline constexpr std::string_view radio_states_api = "/admin/radio_states";
|
|
template <class T>
|
|
using Http_Resource = adminive::Http_Resource<T, Json>;
|
|
template <class T>
|
|
using Http_Collection_Resource = adminive::Http_Collection_Resource<T, Json>;
|
|
std::string format_utc_time(std::chrono::system_clock::time_point value);
|
|
enum class Radio_Mode {
|
|
receive,
|
|
transmit,
|
|
duplex,
|
|
maintenance
|
|
};
|
|
enum class Radio_Operating_State {
|
|
starting,
|
|
running,
|
|
degraded,
|
|
stopped
|
|
};
|
|
enum class Log_Level {
|
|
trace,
|
|
debug,
|
|
info,
|
|
warning,
|
|
error
|
|
};
|
|
enum class Alert_Channel {
|
|
dashboard,
|
|
email,
|
|
webhook
|
|
};
|
|
enum class Serial_Parity {
|
|
none,
|
|
odd,
|
|
even
|
|
};
|
|
enum class Network_Protocol {
|
|
tcp,
|
|
udp,
|
|
websocket
|
|
};
|
|
enum class Device_Table_Type {
|
|
serial,
|
|
network
|
|
};
|
|
struct Server_Status {
|
|
std::string service_state{"running"};
|
|
std::string server_time;
|
|
std::uint64_t uptime_seconds{};
|
|
std::uint64_t poll_sequence{};
|
|
std::uint64_t radio_state_count{};
|
|
int listen_port{};
|
|
};
|
|
struct Radio_Item_Status {
|
|
Status_Value<Radio_Operating_State> operating_state;
|
|
Status_Value<std::uint64_t> refresh_sequence;
|
|
Status_Value<std::string> refresh_time;
|
|
};
|
|
struct Endpoint_Config {
|
|
bool enabled{true};
|
|
std::string host{"127.0.0.1"};
|
|
Range_Value<int, 1, 65535> port{9000};
|
|
};
|
|
struct Appearance_Config {
|
|
std::string panel_title{"Radio Control"};
|
|
std::string effective_date{"2026-08-06"};
|
|
std::string accent_color{"#2563eb"};
|
|
};
|
|
struct Radio_Service_Config {
|
|
std::string profile_name{"Primary Radio Profile"};
|
|
Radio_Mode mode{Radio_Mode::receive};
|
|
Range_Value<int, 1, 64> worker_count{4};
|
|
double receive_gain{1.25};
|
|
Endpoint_Config primary_endpoint{};
|
|
Endpoint_Config backup_endpoint{true, "127.0.0.2", Range_Value<int, 1, 65535>{9001}};
|
|
Appearance_Config appearance{};
|
|
};
|
|
struct Alert_Config {
|
|
bool enabled{true};
|
|
std::string rule_name{"Radio Health Alert"};
|
|
Alert_Channel channel{Alert_Channel::dashboard};
|
|
Log_Level minimum_level{Log_Level::warning};
|
|
Range_Value<int, 1, 1440> repeat_minutes{10};
|
|
std::string effective_date{"2026-08-06"};
|
|
std::string highlight_color{"#d97706"};
|
|
Endpoint_Config webhook_endpoint{true, "127.0.0.1", Range_Value<int, 1, 65535>{9100}};
|
|
};
|
|
struct Serial_Table_Config {
|
|
std::string group_name{"串口设备"};
|
|
Range_Value<int, 1200, 4000000> default_baud_rate{115200};
|
|
Serial_Parity default_parity{Serial_Parity::none};
|
|
std::string accent_color{"#2563eb"};
|
|
};
|
|
struct Network_Table_Config {
|
|
std::string group_name{"网络设备"};
|
|
Network_Protocol default_protocol{Network_Protocol::tcp};
|
|
Range_Value<int, 100, 60000> timeout_ms{3000};
|
|
bool tls_enabled{};
|
|
std::string accent_color{"#16a34a"};
|
|
};
|
|
struct Application_Config {
|
|
Device_Table_Type default_device_type{Device_Table_Type::serial};
|
|
Radio_Service_Config radio_service{};
|
|
Alert_Config alerts{};
|
|
Serial_Table_Config serial_table{};
|
|
Network_Table_Config network_table{};
|
|
};
|
|
struct Gallery_Config {
|
|
struct Even_Validator {
|
|
static constexpr int multiple_of = 2;
|
|
static constexpr std::string_view message = "值必须是偶数";
|
|
void operator()(const int& value) const {
|
|
if(value % 2 != 0) {
|
|
throw std::invalid_argument("value must be even");
|
|
}
|
|
}
|
|
};
|
|
std::string automatic_text{"自动推导为文本输入"};
|
|
std::string text_value{"单行文本"};
|
|
std::string multiline_value{"第一行\n第二行"};
|
|
Range_Value<int, 0, 100> number_value{42};
|
|
Validated_Value<int, Even_Validator> even_number{4};
|
|
bool boolean_value{true};
|
|
Log_Level select_value{Log_Level::info};
|
|
std::string date_value{"2026-08-08"};
|
|
std::string color_value{"#2563eb"};
|
|
std::optional<std::string> optional_text{"这个字段可以清空"};
|
|
bool show_conditional{true};
|
|
std::string conditional_text{"这个字段由上面的开关控制显示"};
|
|
std::string no_default_text{"Descriptor 不输出默认值"};
|
|
std::string backend_only{"后端可写,但前端不能直接编辑或创建"};
|
|
std::string hidden_backend{"后端可读写,但不会输出到前端"};
|
|
std::string read_only_text{"只读字段使用 static 展示,不生成编辑控件"};
|
|
Endpoint_Config nested{};
|
|
};
|
|
enum class Gallery_Category {
|
|
primary,
|
|
secondary,
|
|
experimental
|
|
};
|
|
struct Gallery_Row_Status {
|
|
Status_Value<std::string> state;
|
|
Status_Value<int> score;
|
|
};
|
|
struct Gallery_Row {
|
|
std::string name;
|
|
Gallery_Category category{Gallery_Category::primary};
|
|
Range_Value<int, 0, 100> score{50};
|
|
bool enabled{true};
|
|
std::string color{"#2563eb"};
|
|
Gallery_Row_Status status() const {
|
|
return Gallery_Row_Status{status_value(enabled ? std::string{"enabled"} : std::string{"disabled"}, enabled ? "#16a34a" : "#64748b"), status_value(score.value(), color)};
|
|
}
|
|
};
|
|
struct Gallery_Color_Code {
|
|
std::string value{"#7c3aed"};
|
|
};
|
|
struct Gallery_Adapter_Config {
|
|
Gallery_Color_Code accent;
|
|
std::string secret{"gallery-token"};
|
|
std::string visible{"普通字段仍然正常输出"};
|
|
};
|
|
struct Gallery_Reflected_Config {
|
|
int count{3};
|
|
std::string name{"Reflection Adapter"};
|
|
};
|
|
struct Gallery_Editable_Reflected_Fields {
|
|
template <std::size_t Index, adminive::Field_Descriptor_Type Field>
|
|
auto operator()(Field value) const {
|
|
return value.editable();
|
|
}
|
|
};
|
|
struct Gallery_Serial_Target {
|
|
std::string port{"COM7"};
|
|
Range_Value<int, 1200, 4000000> baud_rate{115200};
|
|
Gallery_Color_Code color;
|
|
};
|
|
struct Gallery_Network_Target {
|
|
std::string host{"127.0.0.1"};
|
|
Range_Value<int, 1, 65535> port{9000};
|
|
};
|
|
using Gallery_Target = std::variant<Gallery_Serial_Target, Gallery_Network_Target>;
|
|
struct Gallery_Polymorphic_Config {
|
|
Gallery_Target target{Gallery_Serial_Target{}};
|
|
};
|
|
struct Gallery_Runtime_Model {
|
|
Endpoint_Config endpoint{};
|
|
std::string name{"Object Adapter Runtime"};
|
|
std::uint64_t apply_count{};
|
|
std::uint64_t transaction_commits{};
|
|
};
|
|
class Gallery_Runtime_Config {
|
|
public:
|
|
Gallery_Runtime_Model snapshot() const {
|
|
auto result = model_;
|
|
result.apply_count = apply_count_;
|
|
result.transaction_commits = transaction_commits_;
|
|
return result;
|
|
}
|
|
void apply(Gallery_Runtime_Model value) {
|
|
model_.endpoint = std::move(value.endpoint);
|
|
model_.name = std::move(value.name);
|
|
++apply_count_;
|
|
}
|
|
void transaction_committed() noexcept {
|
|
++transaction_commits_;
|
|
}
|
|
private:
|
|
Gallery_Runtime_Model model_;
|
|
std::uint64_t apply_count_{};
|
|
std::uint64_t transaction_commits_{};
|
|
};
|
|
struct Serial_Device_Row {
|
|
std::string port_name;
|
|
Range_Value<int, 1200, 4000000> baud_rate{115200};
|
|
Serial_Parity parity{Serial_Parity::none};
|
|
bool enabled{true};
|
|
};
|
|
struct Network_Device_Row {
|
|
std::string endpoint;
|
|
Network_Protocol protocol{Network_Protocol::tcp};
|
|
Range_Value<int, 100, 60000> timeout_ms{3000};
|
|
bool tls_enabled{};
|
|
};
|
|
struct Radio_State {
|
|
struct Even_Validator {
|
|
static constexpr int multiple_of = 2;
|
|
static constexpr std::string_view message = "buffer_count must be even";
|
|
void operator()(const int& value) const;
|
|
};
|
|
struct Watermark_Validator {
|
|
void operator()(const Radio_State& value) const;
|
|
};
|
|
Radio_Mode mode{Radio_Mode::receive};
|
|
Range_Value<int, 1, 65535> port{9999};
|
|
Validated_Value<int, Even_Validator> buffer_count{2};
|
|
int low_watermark{};
|
|
int high_watermark{};
|
|
Radio_Item_Status status();
|
|
private:
|
|
std::uint64_t status_sequence_{};
|
|
};
|
|
}
|