191 lines
6.8 KiB
C++
191 lines
6.8 KiB
C++
#include "app.hpp"
|
||
#include <stdexcept>
|
||
#include <cassert>
|
||
|
||
// =========================================================================
|
||
// 内部辅助函数
|
||
// =========================================================================
|
||
|
||
std::string ODFManager::connector_type_str(ConnectorType t) {
|
||
switch (t) {
|
||
case ConnectorType::LC: return "LC";
|
||
case ConnectorType::SC: return "SC";
|
||
case ConnectorType::MPO: return "MPO";
|
||
default: return "UNKNOWN";
|
||
}
|
||
}
|
||
|
||
std::string ODFManager::polish_type_str(PolishType p) {
|
||
switch (p) {
|
||
case PolishType::UPC: return "UPC";
|
||
case PolishType::APC: return "APC";
|
||
default: return "UNKNOWN";
|
||
}
|
||
}
|
||
|
||
// =========================================================================
|
||
// 单元管理
|
||
// =========================================================================
|
||
|
||
void ODFManager::register_unit(const ODFUnitInfo& unit) {
|
||
if (unit.max_capacity_cores > 288) {
|
||
throw std::invalid_argument(
|
||
"ODF unit capacity exceeds 288 cores (constraint violated)");
|
||
}
|
||
if (unit.unit_id.empty()) {
|
||
throw std::invalid_argument("unit_id must not be empty");
|
||
}
|
||
// 检查重复 ID
|
||
for (const auto& existing : units_) {
|
||
if (existing.unit_id == unit.unit_id) {
|
||
throw std::invalid_argument("duplicate unit_id: " + unit.unit_id);
|
||
}
|
||
}
|
||
units_.push_back(unit);
|
||
}
|
||
|
||
const ODFUnitInfo* ODFManager::find_unit(const std::string& unit_id) const {
|
||
for (const auto& u : units_) {
|
||
if (u.unit_id == unit_id) return &u;
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
const std::vector<ODFUnitInfo>& ODFManager::all_units() const {
|
||
return units_;
|
||
}
|
||
|
||
// =========================================================================
|
||
// 编码生成
|
||
// =========================================================================
|
||
|
||
std::string ODFManager::generate_naming_code(const std::string& site,
|
||
const std::string& cabinet,
|
||
const std::string& slot) const {
|
||
// 格式: [site]-[cabinet]-[slot]
|
||
// 例如: DC01-RF02-SL05
|
||
std::ostringstream oss;
|
||
oss << site << "-" << cabinet << "-" << slot;
|
||
std::string code = oss.str();
|
||
|
||
// 约束:长度不超过 64 字符
|
||
if (code.size() > 64) {
|
||
// 截断到 64 字节,并尽可能保留尾部标识
|
||
code = code.substr(0, 61) + "...";
|
||
}
|
||
|
||
// 保证全局唯一:检查是否与已注册某单元的 unit_id 重复
|
||
// 实际生产可通过数据库约束保证,此处仅做运行时提醒
|
||
for (const auto& u : units_) {
|
||
if (u.unit_id == code) {
|
||
// 若冲突则追加时间戳后缀(简单去重)
|
||
std::time_t now = std::time(nullptr);
|
||
std::tm* tm = std::localtime(&now);
|
||
std::ostringstream suffix;
|
||
suffix << std::put_time(tm, "_%H%M%S");
|
||
code += suffix.str();
|
||
if (code.size() > 64) code = code.substr(0, 64);
|
||
break;
|
||
}
|
||
}
|
||
return code;
|
||
}
|
||
|
||
// =========================================================================
|
||
// 典型配置
|
||
// =========================================================================
|
||
|
||
TypicalConfig ODFManager::get_typical_config(const std::string& scene_type) const {
|
||
for (const auto& cfg : configs_) {
|
||
if (cfg.scene_name.find(scene_type) != std::string::npos) {
|
||
return cfg;
|
||
}
|
||
}
|
||
// 未找到时返回空配置
|
||
return TypicalConfig{};
|
||
}
|
||
|
||
void ODFManager::register_typical_config(const TypicalConfig& cfg) {
|
||
configs_.push_back(cfg);
|
||
}
|
||
|
||
// =========================================================================
|
||
// 兼容性校验
|
||
// =========================================================================
|
||
|
||
bool ODFManager::validate_adapter_compatibility(const AdapterSpec& a,
|
||
const AdapterSpec& b) const {
|
||
// 1) 接口类型必须相同
|
||
if (a.interface_type != b.interface_type) {
|
||
return false;
|
||
}
|
||
// 2) 端面类型允许混合(UPC ↔ APC 可以物理插入)
|
||
// 但回波损耗会受短板影响;此处仅校验物理兼容
|
||
// 3) 额外检查:连接器等级不同时,物理上仍可插拔
|
||
// 不阻塞对接
|
||
return true;
|
||
}
|
||
|
||
// =========================================================================
|
||
// 报告与标签
|
||
// =========================================================================
|
||
|
||
std::string ODFManager::export_milestone_schedule() const {
|
||
if (milestones_.empty()) {
|
||
return "[No milestones scheduled]\n";
|
||
}
|
||
|
||
std::ostringstream oss;
|
||
oss << "+-----+----------------------+------------+------------+"
|
||
<< "----------------------+------+\n";
|
||
oss << "| # | Phase | Start | End |"
|
||
<< " Deliverable | Done |\n";
|
||
oss << "+-----+----------------------+------------+------------+"
|
||
<< "----------------------+------+\n";
|
||
|
||
int idx = 0;
|
||
for (const auto& ms : milestones_) {
|
||
++idx;
|
||
oss << "| " << std::left << std::setw(3) << idx << " "
|
||
<< "| " << std::setw(20) << ms.phase_name << " "
|
||
<< "| " << std::setw(10) << ms.start_date << " "
|
||
<< "| " << std::setw(10) << ms.end_date << " "
|
||
<< "| " << std::setw(20) << ms.deliverable << " "
|
||
<< "| " << (ms.is_completed ? " Y " : " N ")
|
||
<< "|\n";
|
||
}
|
||
oss << "+-----+----------------------+------------+------------+"
|
||
<< "----------------------+------+\n";
|
||
return oss.str();
|
||
}
|
||
|
||
void ODFManager::add_milestone(const Milestone& ms) {
|
||
milestones_.push_back(ms);
|
||
}
|
||
|
||
const std::vector<Milestone>& ODFManager::milestones() const {
|
||
return milestones_;
|
||
}
|
||
|
||
std::string ODFManager::print_label(const std::string& unit_id) const {
|
||
const ODFUnitInfo* unit = find_unit(unit_id);
|
||
if (!unit) {
|
||
return "[ERROR] Unit not found: " + unit_id + "\n";
|
||
}
|
||
|
||
std::ostringstream oss;
|
||
oss << "+====================================+\n";
|
||
oss << "| ODF Unit Label |\n";
|
||
oss << "+====================================+\n";
|
||
oss << "| ID: " << std::left << std::setw(27) << unit->unit_id << "|\n";
|
||
oss << "| Model: " << std::setw(27) << unit->model_name << "|\n";
|
||
oss << "| Location:" << std::setw(27) << unit->location << "|\n";
|
||
oss << "| Mfr: " << std::setw(27) << unit->manufacturer << "|\n";
|
||
oss << "| Date: " << std::setw(27) << unit->production_date << "|\n";
|
||
oss << "| Cores: " << std::setw(27) << unit->max_capacity_cores << "|\n";
|
||
oss << "+------------------------------------+\n";
|
||
oss << "| [QR CODE] " << unit->unit_id << " |\n";
|
||
oss << "+====================================+\n";
|
||
return oss.str();
|
||
}
|