diff --git a/app/src/domain/control_logic_model.cpp b/app/src/domain/control_logic_model.cpp index 6d88892..fa83d92 100644 --- a/app/src/domain/control_logic_model.cpp +++ b/app/src/domain/control_logic_model.cpp @@ -17,13 +17,13 @@ bool validateConfig(const ContactNodeConfig &config, std::string *error) { if (!config.address.isValid() || config.address.area() != RegisterArea::M) { - setError(error, "contact node requires a valid M address"); + setError(error, "触点节点必须使用有效的 M 区地址"); return false; } if (config.mode != ContactMode::NormallyOpen && config.mode != ContactMode::NormallyClosed) { - setError(error, "contact node has an unsupported mode"); + setError(error, "触点节点使用了不支持的模式"); return false; } return true; @@ -33,14 +33,14 @@ bool validateConfig(const CoilNodeConfig &config, std::string *error) { if (!config.address.isValid() || config.address.area() != RegisterArea::M) { - setError(error, "coil node requires a valid M address"); + setError(error, "线圈节点必须使用有效的 M 区地址"); return false; } if (config.mode != CoilMode::Normal && config.mode != CoilMode::Set && config.mode != CoilMode::Reset) { - setError(error, "coil node has an unsupported mode"); + setError(error, "线圈节点使用了不支持的模式"); return false; } return true; @@ -50,7 +50,7 @@ bool validateConfig(const CompareNodeConfig &config, std::string *error) { if (!config.address.isValid() || config.address.area() != RegisterArea::D) { - setError(error, "comparison node requires a valid D address"); + setError(error, "比较节点必须使用有效的 D 区地址"); return false; } if (config.comparison != ComparisonOperator::Equal @@ -60,7 +60,7 @@ bool validateConfig(const CompareNodeConfig &config, std::string *error) && config.comparison != ComparisonOperator::GreaterThan && config.comparison != ComparisonOperator::GreaterThanOrEqual) { - setError(error, "comparison node has an unsupported operator"); + setError(error, "比较节点使用了不支持的运算符"); return false; } return true; @@ -93,7 +93,7 @@ bool validateUniqueExpressionIds( std::sort(ids.begin(), ids.end()); if (std::adjacent_find(ids.cbegin(), ids.cend()) != ids.cend()) { - setError(error, "condition expression ids must be unique within a rung"); + setError(error, "同一网络内的条件表达式 ID 必须唯一"); return false; } return true; @@ -138,7 +138,7 @@ bool LogicNode::validate(std::string *error) const { if (id.empty()) { - setError(error, "logic node id must not be empty"); + setError(error, "逻辑节点 ID 不能为空"); return false; } return std::visit( @@ -174,28 +174,28 @@ bool ConditionExpression::validate(std::string *error) const { if (id.empty()) { - setError(error, "condition expression id must not be empty"); + setError(error, "条件表达式 ID 不能为空"); return false; } if (kind == ConditionExpressionKind::Node) { if (!node.has_value() || !children.empty() || !node->isCondition()) { - setError(error, "condition leaf requires one condition node and no children"); + setError(error, "条件叶节点必须包含一个条件节点且不能包含子表达式"); return false; } return node->validate(error); } if (node.has_value() || children.size() < 2U) { - setError(error, "series and parallel expressions require at least two children"); + setError(error, "串联和并联表达式至少需要两个子表达式"); return false; } for (const ConditionExpression &child : children) { if (child.kind == kind) { - setError(error, "nested expressions of the same kind must be normalized"); + setError(error, "同类型嵌套表达式必须先完成归一化"); return false; } if (!child.validate(error)) @@ -216,7 +216,7 @@ bool ConditionExpression::validateForRunning(std::string *error) const { if (!node->isConfigured()) { - setError(error, "ladder condition " + node->id + " is not configured"); + setError(error, "梯形图条件节点 " + node->id + " 尚未配置"); return false; } return true; @@ -343,7 +343,7 @@ bool LadderRung::validateForRunning(std::string *error) const } if (!condition.has_value() || !output.has_value()) { - setError(error, "incomplete ladder network requires conditions and an output coil"); + setError(error, "未完成的梯形图网络必须同时包含条件和输出线圈"); return false; } if (!condition->validateForRunning(error)) @@ -352,7 +352,7 @@ bool LadderRung::validateForRunning(std::string *error) const } if (!output->isConfigured()) { - setError(error, "output coil " + output->id + " is not configured"); + setError(error, "输出线圈 " + output->id + " 尚未配置"); return false; } return true; @@ -362,7 +362,7 @@ bool LadderRung::validateStructure(std::string *error) const { if (id.empty() || name.empty()) { - setError(error, "ladder rung id and name must not be empty"); + setError(error, "梯形图网络 ID 和名称不能为空"); return false; } std::vector node_ids; @@ -383,7 +383,7 @@ bool LadderRung::validateStructure(std::string *error) const { if (!output->validate(error) || !output->isOutput()) { - setError(error, "ladder rung output must be a coil node"); + setError(error, "梯形图网络输出必须是线圈节点"); return false; } node_ids.push_back(output->id); @@ -391,7 +391,7 @@ bool LadderRung::validateStructure(std::string *error) const std::sort(node_ids.begin(), node_ids.end()); if (std::adjacent_find(node_ids.cbegin(), node_ids.cend()) != node_ids.cend()) { - setError(error, "logic node ids must be unique within a rung"); + setError(error, "同一网络内的逻辑节点 ID 必须唯一"); return false; } return true; @@ -417,12 +417,12 @@ bool ControlLogic::validateStructure(std::string *error) const { if (id.empty() || name.empty()) { - setError(error, "control logic id and name must not be empty"); + setError(error, "控制逻辑 ID 和名称不能为空"); return false; } if (hasDuplicateId(rungs)) { - setError(error, "ladder rung ids must be unique within a logic"); + setError(error, "同一控制逻辑内的网络 ID 必须唯一"); return false; } std::vector node_ids; @@ -452,13 +452,13 @@ bool ControlLogic::validateStructure(std::string *error) const std::sort(expression_ids.begin(), expression_ids.end()); if (std::adjacent_find(node_ids.cbegin(), node_ids.cend()) != node_ids.cend()) { - setError(error, "logic node ids must be unique within a logic"); + setError(error, "同一控制逻辑内的逻辑节点 ID 必须唯一"); return false; } if (std::adjacent_find(expression_ids.cbegin(), expression_ids.cend()) != expression_ids.cend()) { - setError(error, "condition expression ids must be unique within a logic"); + setError(error, "同一控制逻辑内的条件表达式 ID 必须唯一"); return false; } return true; diff --git a/app/src/domain/hmi_model.cpp b/app/src/domain/hmi_model.cpp index 3c349da..bd0ec9f 100644 --- a/app/src/domain/hmi_model.cpp +++ b/app/src/domain/hmi_model.cpp @@ -31,19 +31,19 @@ bool HmiControl::validate(std::string *error) const { if (id.empty()) { - setError(error, "HMI control id must not be empty"); + setError(error, "HMI 控件 ID 不能为空"); return false; } if (bounds.width <= 0 || bounds.height <= 0) { - setError(error, "HMI control bounds must have positive size"); + setError(error, "HMI 控件的宽度和高度必须大于 0"); return false; } for (const auto &property : properties) { if (property.first.empty()) { - setError(error, "HMI control property names must not be empty"); + setError(error, "HMI 控件属性名称不能为空"); return false; } } @@ -51,7 +51,7 @@ bool HmiControl::validate(std::string *error) const { if (binding.has_value() && binding->area() != RegisterArea::M) { - setError(error, "button and indicator controls require an M address"); + setError(error, "按钮和指示灯必须绑定 M 区地址"); return false; } } @@ -59,13 +59,13 @@ bool HmiControl::validate(std::string *error) const { if (binding.has_value() && binding->area() != RegisterArea::D) { - setError(error, "numeric controls require a D address"); + setError(error, "数值控件必须绑定 D 区地址"); return false; } } if (binding.has_value() && !binding->isValid()) { - setError(error, "HMI control binding has an invalid address"); + setError(error, "HMI 控件绑定了无效地址"); return false; } return true; @@ -92,12 +92,12 @@ bool HmiPage::validate(std::string *error) const { if (id.empty() || name.empty()) { - setError(error, "HMI page id and name must not be empty"); + setError(error, "HMI 页面 ID 和名称不能为空"); return false; } if (width <= 0 || height <= 0) { - setError(error, "HMI page size must be positive"); + setError(error, "HMI 页面尺寸必须大于 0"); return false; } @@ -113,13 +113,13 @@ bool HmiPage::validate(std::string *error) const || control.bounds.x > width - control.bounds.width || control.bounds.y > height - control.bounds.height) { - setError(error, "HMI control bounds must stay within the page"); + setError(error, "HMI 控件不能超出页面范围"); return false; } // 检查控件 id 是否唯一 if (std::find(ids.cbegin(), ids.cend(), control.id) != ids.cend()) { - setError(error, "HMI control ids must be unique within a page"); + setError(error, "同一 HMI 页面内的控件 ID 必须唯一"); return false; } ids.push_back(control.id); @@ -137,7 +137,7 @@ bool HmiPage::validateForRunning(std::string *error) const { if (!control.isConfigured()) { - setError(error, "HMI control " + control.id + " is not bound to a register"); + setError(error, "HMI 控件 " + control.id + " 尚未绑定寄存器"); return false; } } diff --git a/app/src/domain/project_model.cpp b/app/src/domain/project_model.cpp index 4d6d118..2d12601 100644 --- a/app/src/domain/project_model.cpp +++ b/app/src/domain/project_model.cpp @@ -39,17 +39,17 @@ bool Project::validate(std::string *error) const { if (metadata.id.empty() || metadata.name.empty() || metadata.formatVersion.empty()) { - setError(error, "project id, name and format version must not be empty"); + setError(error, "工程 ID、名称和格式版本不能为空"); return false; } if (containsDuplicateId(hmiPages)) { - setError(error, "HMI page ids must be unique within a project"); + setError(error, "工程内的 HMI 页面 ID 必须唯一"); return false; } if (containsDuplicateId(controlLogics)) { - setError(error, "control logic ids must be unique within a project"); + setError(error, "工程内的控制逻辑 ID 必须唯一"); return false; } for (const HmiPage &page : hmiPages) diff --git a/app/src/infrastructure/json_project_storage.cpp b/app/src/infrastructure/json_project_storage.cpp index ebf7368..f3460a1 100644 --- a/app/src/infrastructure/json_project_storage.cpp +++ b/app/src/infrastructure/json_project_storage.cpp @@ -67,7 +67,7 @@ bool readValue( { return state->fail( ProjectStorageError::MissingField, - "missing required field " + fieldPath(context, field)); + "缺少必填字段:" + fieldPath(context, field)); } *value = object.value(key); return true; @@ -90,7 +90,7 @@ bool readString( { return state->fail( ProjectStorageError::InvalidField, - fieldPath(context, field) + " must be a string"); + fieldPath(context, field) + " 必须是字符串"); } *value = toUtf8(json_value.toString()); return true; @@ -113,7 +113,7 @@ bool readBool( { return state->fail( ProjectStorageError::InvalidField, - fieldPath(context, field) + " must be a boolean"); + fieldPath(context, field) + " 必须是布尔值"); } *value = json_value.toBool(); return true; @@ -138,7 +138,7 @@ bool readInt( { return state->fail( ProjectStorageError::InvalidField, - fieldPath(context, field) + " must be an integer"); + fieldPath(context, field) + " 必须是整数"); } // Qt JSON 统一用 double 表示数值,需要额外确认它能无损转换为 int @@ -148,7 +148,7 @@ bool readInt( { return state->fail( ProjectStorageError::InvalidField, - fieldPath(context, field) + " is outside the supported integer range"); + fieldPath(context, field) + " 超出支持的整数范围"); } *value = static_cast(number); return true; @@ -171,7 +171,7 @@ bool readObject( { return state->fail( ProjectStorageError::InvalidField, - fieldPath(context, field) + " must be an object"); + fieldPath(context, field) + " 必须是对象"); } *value = json_value.toObject(); return true; @@ -194,7 +194,7 @@ bool readArray( { return state->fail( ProjectStorageError::InvalidField, - fieldPath(context, field) + " must be an array"); + fieldPath(context, field) + " 必须是数组"); } *value = json_value.toArray(); return true; @@ -246,7 +246,7 @@ bool parseAddress( { return state->fail( ProjectStorageError::InvalidField, - context + ".area must be M or D"); + context + ".area 必须是 M 或 D"); } *address = RegisterAddress{area, index}; @@ -313,7 +313,7 @@ bool parseHmiControlType( { return state->fail( ProjectStorageError::InvalidField, - "unsupported HMI control type " + value); + "不支持的 HMI 控件类型:" + value); } return true; } @@ -393,7 +393,7 @@ bool parseProperties( { return state->fail( ProjectStorageError::InvalidField, - "HMI control property values must be strings"); + "HMI 控件属性值必须是字符串"); } properties->emplace(toUtf8(current.key()), toUtf8(current.value().toString())); } @@ -458,7 +458,7 @@ bool parseHmiControl( { return state->fail( ProjectStorageError::InvalidField, - context + ".binding must be an object or null"); + context + ".binding 必须是对象或 null"); } RegisterAddress address{RegisterArea::M, 0}; @@ -515,7 +515,7 @@ bool parseHmiPage( { return state->fail( ProjectStorageError::InvalidField, - context + ".controls items must be objects"); + context + ".controls 的元素必须是对象"); } HmiControl control; if (!parseHmiControl( @@ -555,7 +555,7 @@ bool parseContactMode( { return state->fail( ProjectStorageError::InvalidField, - "unsupported contact mode " + value); + "不支持的触点模式:" + value); } return true; } @@ -603,7 +603,7 @@ bool parseCoilMode(const std::string &value, CoilMode *mode, ParseState *state) { return state->fail( ProjectStorageError::InvalidField, - "unsupported coil mode " + value); + "不支持的线圈模式:" + value); } return true; } @@ -678,7 +678,7 @@ bool parseComparison( { return state->fail( ProjectStorageError::InvalidField, - "unsupported comparison operator " + value); + "不支持的比较运算符:" + value); } return true; } @@ -804,7 +804,7 @@ bool parseNodeConfig( return state->fail( ProjectStorageError::InvalidField, - "unsupported logic node type " + type); + "不支持的逻辑节点类型:" + type); } // 解析逻辑节点标识及其多态配置 @@ -892,7 +892,7 @@ bool parseConditionExpression( { return state->fail( ProjectStorageError::InvalidField, - context + ".kind must be node, series or parallel"); + context + ".kind 必须是 node、series 或 parallel"); } QJsonArray children; if (!readArray(object, "children", context, &children, state)) @@ -908,7 +908,7 @@ bool parseConditionExpression( { return state->fail( ProjectStorageError::InvalidField, - context + ".children items must be objects"); + context + ".children 的元素必须是对象"); } ConditionExpression child; if (!parseConditionExpression( @@ -967,7 +967,7 @@ bool parseLadderRung( { return state->fail( ProjectStorageError::InvalidField, - context + ".condition must be an object or null"); + context + ".condition 必须是对象或 null"); } else { @@ -988,7 +988,7 @@ bool parseLadderRung( { return state->fail( ProjectStorageError::InvalidField, - context + ".output must be an object or null"); + context + ".output 必须是对象或 null"); } LogicNode node; if (!parseLogicNode(output.toObject(), context + ".output", &node, state)) @@ -1035,7 +1035,7 @@ bool parseControlLogic( { return state->fail( ProjectStorageError::InvalidField, - context + ".rungs items must be objects"); + context + ".rungs 的元素必须是对象"); } LadderRung rung; if (!parseLadderRung( @@ -1095,7 +1095,7 @@ bool parseProject( { return state->fail( ProjectStorageError::UnsupportedVersion, - "unsupported project format version " + project->metadata.formatVersion); + "不支持的工程格式版本:" + project->metadata.formatVersion); } if (!readString(object, "id", "project", &project->metadata.id, state) @@ -1114,7 +1114,7 @@ bool parseProject( { return state->fail( ProjectStorageError::InvalidField, - "project.hmiPages items must be objects"); + "project.hmiPages 的元素必须是对象"); } HmiPage page; if (!parseHmiPage( @@ -1135,7 +1135,7 @@ bool parseProject( { return state->fail( ProjectStorageError::InvalidField, - "project.controlLogics items must be objects"); + "project.controlLogics 的元素必须是对象"); } ControlLogic logic; if (!parseControlLogic( @@ -1174,7 +1174,7 @@ ProjectSaveResult JsonProjectStorage::save( { return {false, ProjectStorageError::UnsupportedVersion, - "unsupported project format version " + project.metadata.formatVersion}; + "不支持的工程格式版本:" + project.metadata.formatVersion}; } // QSaveFile 先写临时文件,仅在 commit 成功后替换目标文件 @@ -1226,7 +1226,7 @@ ProjectLoadResult JsonProjectStorage::load(const std::string &file_path) if (parse_error.error != QJsonParseError::NoError || !document.isObject()) { const QString message = parse_error.error == QJsonParseError::NoError - ? QStringLiteral("project JSON root must be an object") + ? QStringLiteral("工程 JSON 根节点必须是对象") : parse_error.errorString(); return {false, {}, diff --git a/app/src/services/hmi_editor_service.cpp b/app/src/services/hmi_editor_service.cpp index 1c18f1d..7e32b7d 100644 --- a/app/src/services/hmi_editor_service.cpp +++ b/app/src/services/hmi_editor_service.cpp @@ -147,7 +147,7 @@ HmiEditorResult HmiEditorService::addControl( const HmiPage *page = findPage(page_id); if (page == nullptr) { - return failure(HmiEditorError::PageNotFound, "HMI page was not found"); + return failure(HmiEditorError::PageNotFound, "未找到 HMI 页面"); } // 新控件初始不绑定寄存器,避免自动分配地址造成误写风险 @@ -172,11 +172,11 @@ HmiEditorResult HmiEditorService::removeControl( { if (findPage(page_id) == nullptr) { - return failure(HmiEditorError::PageNotFound, "HMI page was not found"); + return failure(HmiEditorError::PageNotFound, "未找到 HMI 页面"); } if (findControl(page_id, control_id) == nullptr) { - return failure(HmiEditorError::ControlNotFound, "HMI control was not found"); + return failure(HmiEditorError::ControlNotFound, "未找到 HMI 控件"); } Project &project = project_service_.editProject(); @@ -209,11 +209,11 @@ HmiEditorResult HmiEditorService::moveControl( const HmiControl *control = findControl(page_id, control_id); if (page == nullptr) { - return failure(HmiEditorError::PageNotFound, "HMI page was not found"); + return failure(HmiEditorError::PageNotFound, "未找到 HMI 页面"); } if (control == nullptr) { - return failure(HmiEditorError::ControlNotFound, "HMI control was not found"); + return failure(HmiEditorError::ControlNotFound, "未找到 HMI 控件"); } // 先校验候选位置,失败时不修改工程模型 @@ -247,15 +247,15 @@ HmiEditorResult HmiEditorService::updateControl( const HmiControl *existing = findControl(page_id, control_id); if (page == nullptr) { - return failure(HmiEditorError::PageNotFound, "HMI page was not found"); + return failure(HmiEditorError::PageNotFound, "未找到 HMI 页面"); } if (existing == nullptr) { - return failure(HmiEditorError::ControlNotFound, "HMI control was not found"); + return failure(HmiEditorError::ControlNotFound, "未找到 HMI 控件"); } if (control.type != existing->type) { - return failure(HmiEditorError::InvalidControl, "HMI control type cannot be changed"); + return failure(HmiEditorError::InvalidControl, "不能修改已创建 HMI 控件的类型"); } std::string error; @@ -265,7 +265,7 @@ HmiEditorResult HmiEditorService::updateControl( } if (hasDuplicateControlId(*page, control_id, control.id)) { - return failure(HmiEditorError::DuplicateId, "HMI control id must be unique within a page"); + return failure(HmiEditorError::DuplicateId, "同一 HMI 页面内的控件 ID 必须唯一"); } Project &project = project_service_.editProject(); @@ -284,7 +284,7 @@ bool HmiEditorService::validateEditableControl( { if (control.id.empty()) { - setError(error, "HMI control id must not be empty"); + setError(error, "HMI 控件 ID 不能为空"); return false; } if (control.bounds.width <= 0 || control.bounds.height <= 0 @@ -293,20 +293,20 @@ bool HmiEditorService::validateEditableControl( || control.bounds.x > page.width - control.bounds.width || control.bounds.y > page.height - control.bounds.height) { - setError(error, "HMI control bounds must stay within the page"); + setError(error, "HMI 控件不能超出页面范围"); return false; } for (const auto &property : control.properties) { if (property.first.empty()) { - setError(error, "HMI control property names must not be empty"); + setError(error, "HMI 控件属性名称不能为空"); return false; } } if (control.binding.has_value() && !control.binding->isValid()) { - setError(error, "HMI control binding has an invalid address"); + setError(error, "HMI 控件绑定了无效地址"); return false; } if (control.binding.has_value() @@ -314,7 +314,7 @@ bool HmiEditorService::validateEditableControl( || control.type == HmiControlType::Indicator) && control.binding->area() != RegisterArea::M) { - setError(error, "button and indicator controls require an M address"); + setError(error, "按钮和指示灯必须绑定 M 区地址"); return false; } if (control.binding.has_value() @@ -322,7 +322,7 @@ bool HmiEditorService::validateEditableControl( || control.type == HmiControlType::NumericInput) && control.binding->area() != RegisterArea::D) { - setError(error, "numeric controls require a D address"); + setError(error, "数值控件必须绑定 D 区地址"); return false; } return true; diff --git a/app/src/services/logic_editor_service.cpp b/app/src/services/logic_editor_service.cpp index d9beceb..fce5e83 100644 --- a/app/src/services/logic_editor_service.cpp +++ b/app/src/services/logic_editor_service.cpp @@ -346,7 +346,7 @@ LogicEditorResult LogicEditorService::addRung(const std::string &logic_id) const ControlLogic *logic = findLogic(logic_id); if (logic == nullptr) { - return failure(LogicEditorError::LogicNotFound, "control logic was not found"); + return failure(LogicEditorError::LogicNotFound, "未找到控制逻辑"); } LadderRung rung; rung.id = makeUniqueRungId(*logic); @@ -365,15 +365,15 @@ LogicEditorResult LogicEditorService::removeRung( const ControlLogic *logic = findLogic(logic_id); if (logic == nullptr) { - return failure(LogicEditorError::LogicNotFound, "control logic was not found"); + return failure(LogicEditorError::LogicNotFound, "未找到控制逻辑"); } if (findRung(logic_id, rung_id) == nullptr) { - return failure(LogicEditorError::RungNotFound, "ladder rung was not found"); + return failure(LogicEditorError::RungNotFound, "未找到梯形图网络"); } if (logic->rungs.size() == 1U) { - return failure(LogicEditorError::InvalidOperation, "control logic requires one rung"); + return failure(LogicEditorError::InvalidOperation, "控制逻辑至少需要保留一个网络"); } Project &project = project_service_.editProject(); auto target = std::find_if( @@ -397,11 +397,11 @@ LogicEditorResult LogicEditorService::appendCondition( { return failure( logic == nullptr ? LogicEditorError::LogicNotFound : LogicEditorError::RungNotFound, - logic == nullptr ? "control logic was not found" : "ladder rung was not found"); + logic == nullptr ? "未找到控制逻辑" : "未找到梯形图网络"); } if (!isConditionConfig(config)) { - return failure(LogicEditorError::InvalidNode, "ladder condition cannot be a coil"); + return failure(LogicEditorError::InvalidNode, "梯形图条件不能使用线圈节点"); } const std::string node_id = makeUniqueNodeId(*logic, nodePrefix(config)); ConditionExpression leaf = ConditionExpression::fromNode(makeNode(node_id, config)); @@ -435,7 +435,7 @@ LogicEditorResult LogicEditorService::insertConditionAfter( const ControlLogic *logic = findLogic(logic_id); if (logic == nullptr || findRung(logic_id, rung_id) == nullptr) { - return failure(LogicEditorError::RungNotFound, "ladder network was not found"); + return failure(LogicEditorError::RungNotFound, "未找到梯形图网络"); } const LadderRung *existing_rung = findRung(logic_id, rung_id); if (!isConditionConfig(config) @@ -443,7 +443,7 @@ LogicEditorResult LogicEditorService::insertConditionAfter( || !existing_rung->condition.has_value() || findConditionNode(*existing_rung->condition, target_node_id) == nullptr) { - return failure(LogicEditorError::NodeNotFound, "series insertion target was not found"); + return failure(LogicEditorError::NodeNotFound, "未找到串联插入目标"); } const std::string node_id = makeUniqueNodeId(*logic, nodePrefix(config)); ConditionExpression leaf = ConditionExpression::fromNode(makeNode(node_id, config)); @@ -482,30 +482,30 @@ LogicEditorResult LogicEditorService::addParallelBranch( const ControlLogic *logic = findLogic(logic_id); if (logic == nullptr || findRung(logic_id, rung_id) == nullptr) { - return failure(LogicEditorError::RungNotFound, "ladder network was not found"); + return failure(LogicEditorError::RungNotFound, "未找到梯形图网络"); } if (!isConditionConfig(config) || selected_node_ids.empty()) { - return failure(LogicEditorError::InvalidOperation, "parallel branch requires a selection"); + return failure(LogicEditorError::InvalidOperation, "建立并联支路前必须选择节点"); } const LadderRung *existing_rung = findRung(logic_id, rung_id); if (!existing_rung->condition.has_value()) { - return failure(LogicEditorError::InvalidOperation, "ladder network has no condition"); + return failure(LogicEditorError::InvalidOperation, "梯形图网络尚无条件节点"); } NodeIdSet selected_ids(selected_node_ids.cbegin(), selected_node_ids.cend()); if (selected_ids.size() != selected_node_ids.size()) { return failure( LogicEditorError::InvalidOperation, - "parallel selection contains duplicates"); + "并联选择中存在重复节点"); } const NodeIdSet available_ids = conditionNodeIds(*existing_rung->condition); if (!isSubset(selected_ids, available_ids)) { return failure( LogicEditorError::NodeNotFound, - "parallel selection contains an unknown node"); + "并联选择中包含未知节点"); } const std::string node_id = makeUniqueNodeId(*logic, nodePrefix(config)); ConditionExpression leaf = ConditionExpression::fromNode(makeNode(node_id, config)); @@ -526,7 +526,7 @@ LogicEditorResult LogicEditorService::addParallelBranch( { return failure( LogicEditorError::InvalidOperation, - "parallel selection must be one continuous logic range"); + "并联选择必须是一个连续的逻辑范围"); } return {true, LogicEditorError::None, {}, node_id}; } @@ -540,7 +540,7 @@ LogicEditorResult LogicEditorService::setOutput( const LadderRung *existing_rung = findRung(logic_id, rung_id); if (logic == nullptr || existing_rung == nullptr || !isOutputConfig(config)) { - return failure(LogicEditorError::InvalidNode, "ladder output requires a valid coil"); + return failure(LogicEditorError::InvalidNode, "梯形图输出必须使用有效线圈"); } const std::string node_id = existing_rung->output.has_value() ? existing_rung->output->id : makeUniqueNodeId(*logic, nodePrefix(config)); @@ -557,13 +557,13 @@ LogicEditorResult LogicEditorService::updateNodeConfig( const LogicNode *node = findNode(logic_id, node_id); if (node == nullptr) { - return failure(LogicEditorError::NodeNotFound, "logic node was not found"); + return failure(LogicEditorError::NodeNotFound, "未找到逻辑节点"); } if (node->config.index() != config.index()) { return failure( LogicEditorError::UnsupportedNodeChange, - "node category cannot be changed after creation"); + "节点创建后不能修改节点类别"); } LogicNode candidate{node_id, config, true}; std::string error; @@ -595,7 +595,7 @@ LogicEditorResult LogicEditorService::updateNodeConfig( } } } - return failure(LogicEditorError::NodeNotFound, "logic node was not found"); + return failure(LogicEditorError::NodeNotFound, "未找到逻辑节点"); } LogicEditorResult LogicEditorService::removeNode( @@ -604,7 +604,7 @@ LogicEditorResult LogicEditorService::removeNode( const std::string rung_id = rungIdForNode(logic_id, node_id); if (rung_id.empty()) { - return failure(LogicEditorError::NodeNotFound, "logic node was not found"); + return failure(LogicEditorError::NodeNotFound, "未找到逻辑节点"); } const LadderRung *rung = findRung(logic_id, rung_id); if (rung->output.has_value() && rung->output->id == node_id) @@ -623,7 +623,7 @@ LogicEditorResult LogicEditorService::removeExpression( { if (findExpression(logic_id, rung_id, expression_id) == nullptr) { - return failure(LogicEditorError::ExpressionNotFound, "condition branch was not found"); + return failure(LogicEditorError::ExpressionNotFound, "未找到条件支路"); } Project &project = project_service_.editProject(); LadderRung *rung = findEditableRung(project, logic_id, rung_id); diff --git a/app/src/services/offline_simulation_service.cpp b/app/src/services/offline_simulation_service.cpp index 55d78a5..46910f2 100644 --- a/app/src/services/offline_simulation_service.cpp +++ b/app/src/services/offline_simulation_service.cpp @@ -61,7 +61,7 @@ LogicScanResult OfflineSimulationService::executeOnce() { return {false, LogicScanError::InvalidLogic, - "offline simulation is not running", + "离线仿真尚未运行", {}, {}, {}}; diff --git a/app/src/services/project_service.cpp b/app/src/services/project_service.cpp index 9fdaab8..e519134 100644 --- a/app/src/services/project_service.cpp +++ b/app/src/services/project_service.cpp @@ -26,7 +26,7 @@ std::string generateProjectId() ProjectService::ProjectService(ProjectStorage &storage) : storage_(storage), - project_(makeNewProject("Untitled")) + project_(makeNewProject("未命名工程")) { } @@ -64,7 +64,7 @@ ProjectOperationResult ProjectService::createNewProject(const std::string &name) return {false, ProjectServiceError::InvalidProjectName, ProjectStorageError::None, - "project name must not be empty"}; + "工程名称不能为空"}; } // 新工程创建成功后清除原文件关联,并标记为待保存 @@ -81,7 +81,7 @@ ProjectOperationResult ProjectService::save() return {false, ProjectServiceError::FilePathRequired, ProjectStorageError::None, - "project file path is required"}; + "必须指定工程文件路径"}; } // 复用另存为流程,确保两种保存方式拥有相同的校验和错误处理 return saveAs(current_file_path_); @@ -94,7 +94,7 @@ ProjectOperationResult ProjectService::saveAs(const std::string &file_path) return {false, ProjectServiceError::FilePathRequired, ProjectStorageError::None, - "project file path is required"}; + "必须指定工程文件路径"}; } std::string validation_error; @@ -126,7 +126,7 @@ ProjectOperationResult ProjectService::load(const std::string &file_path) return {false, ProjectServiceError::FilePathRequired, ProjectStorageError::None, - "project file path is required"}; + "必须指定工程文件路径"}; } ProjectLoadResult result = storage_.load(file_path); diff --git a/app/src/services/runtime_mode_service.cpp b/app/src/services/runtime_mode_service.cpp index ba19126..bf263aa 100644 --- a/app/src/services/runtime_mode_service.cpp +++ b/app/src/services/runtime_mode_service.cpp @@ -176,7 +176,7 @@ PlcCommunicationResult RuntimeModeService::connectPlc( { if (plc_gateway_ == nullptr) { - return {false, "PLC communication is not configured"}; + return {false, "PLC 通信服务尚未配置"}; } std::vector addresses; const Project &project = project_service_.project(); diff --git a/app/src/services/software_logic_executor.cpp b/app/src/services/software_logic_executor.cpp index 4ca53e8..6f176c8 100644 --- a/app/src/services/software_logic_executor.cpp +++ b/app/src/services/software_logic_executor.cpp @@ -96,7 +96,7 @@ LogicScanResult SoftwareLogicExecutor::validate( { return failure( LogicScanError::InvalidLogic, - "ladder output is not a coil", + "梯形图输出不是线圈节点", logic.id, rung.id, rung.output->id); @@ -106,7 +106,7 @@ LogicScanResult SoftwareLogicExecutor::validate( { return failure( LogicScanError::ConflictingOutput, - "mixed coil modes target " + output->address.toString(), + "同一地址使用了不同线圈模式:" + output->address.toString(), logic.id, rung.id, rung.output->id); @@ -180,7 +180,7 @@ LogicScanResult SoftwareLogicExecutor::evaluateExpression( { if (value == nullptr) { - return failure(LogicScanError::InvalidLogic, "expression result target is missing"); + return failure(LogicScanError::InvalidLogic, "缺少表达式结果接收对象"); } if (expression.kind == ConditionExpressionKind::Node) { @@ -222,7 +222,7 @@ LogicScanResult SoftwareLogicExecutor::evaluateCondition( { return failure( LogicScanError::InvalidLogic, - "condition result target is missing", + "缺少条件结果接收对象", {}, {}, node.id); @@ -239,7 +239,7 @@ LogicScanResult SoftwareLogicExecutor::evaluateCondition( { return failure( LogicScanError::RegisterReadFailed, - "failed to read " + config.address.toString(), + "读取寄存器失败:" + config.address.toString(), {}, {}, node.id); @@ -255,7 +255,7 @@ LogicScanResult SoftwareLogicExecutor::evaluateCondition( { return failure( LogicScanError::RegisterReadFailed, - "failed to read " + config.address.toString(), + "读取寄存器失败:" + config.address.toString(), {}, {}, node.id); @@ -267,7 +267,7 @@ LogicScanResult SoftwareLogicExecutor::evaluateCondition( { return failure( LogicScanError::InvalidLogic, - "condition node contains an output coil", + "条件节点不能包含输出线圈", {}, {}, node.id); @@ -286,7 +286,7 @@ LogicScanResult SoftwareLogicExecutor::writeOutput( { return failure( LogicScanError::InvalidLogic, - "ladder output is not a coil", + "梯形图输出不是线圈节点", {}, {}, node.id); @@ -316,7 +316,7 @@ LogicScanResult SoftwareLogicExecutor::writeOutput( { return failure( LogicScanError::InvalidLogic, - "unsupported coil mode", + "不支持的线圈模式", {}, {}, node.id); @@ -333,7 +333,7 @@ LogicScanResult SoftwareLogicExecutor::writeOutput( { return failure( LogicScanError::RegisterWriteFailed, - "failed to write " + config->address.toString(), + "写入寄存器失败:" + config->address.toString(), {}, {}, node.id);