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();
|
|||
|
|
}
|