diff --git a/backend/app/api/routes/config.py b/backend/app/api/routes/config.py index 6190b0c..56644bc 100644 --- a/backend/app/api/routes/config.py +++ b/backend/app/api/routes/config.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List +from typing import Any, Dict, List, Union from fastapi import APIRouter, Depends, Query @@ -32,7 +32,7 @@ def get_net_config(nic: str = Query(..., min_length=1)) -> Dict[str, Any]: @router.post("/device/net", dependencies=[Depends(verify_api_token)]) -def save_net_config(payload: NetConfigItem) -> Dict[str, Any]: +def save_net_config(payload: Union[NetConfigItem, List[NetConfigItem]]) -> Dict[str, Any]: return success_response(platform_service.save_net_config(payload), msg="保存网卡配置成功") @@ -42,7 +42,7 @@ def get_uart_config(port: str = Query(..., min_length=1)) -> Dict[str, Any]: @router.post("/device/uart", dependencies=[Depends(verify_api_token)]) -def save_uart_config(payload: UartConfigItem) -> Dict[str, Any]: +def save_uart_config(payload: Union[UartConfigItem, List[UartConfigItem]]) -> Dict[str, Any]: return success_response(platform_service.save_uart_config(payload), msg="保存串口配置成功") diff --git a/backend/app/services/platform_service.py b/backend/app/services/platform_service.py index 7435b8c..cfee0a1 100644 --- a/backend/app/services/platform_service.py +++ b/backend/app/services/platform_service.py @@ -352,7 +352,10 @@ class PlatformService: def get_net_config(self, nic: str) -> Dict[str, Any]: return self.device_client.read_net_config(nic) - def save_net_config(self, payload: NetConfigItem) -> Dict[str, Any]: + def save_net_config(self, payload: NetConfigItem | List[NetConfigItem]) -> Dict[str, Any]: + if isinstance(payload, list): + results = [self.device_client.send_net_config(item) for item in payload] + return {"send_status": "成功", "target": "net_batch", "items": len(results), "results": results} return self.device_client.send_net_config(payload) def get_uart_config(self, port: str) -> Dict[str, Any]: @@ -362,8 +365,21 @@ class PlatformService: return item return {"port": port, "baud": 9600, "parity": "NONE", "data_bits": 8, "stop_bits": 1, "protocol": ""} - def save_uart_config(self, payload: UartConfigItem) -> Dict[str, Any]: + def save_uart_config(self, payload: UartConfigItem | List[UartConfigItem]) -> Dict[str, Any]: device_config = self._load_device_config_with_defaults() + if isinstance(payload, list): + results = [] + for item in payload: + device_config["uart"] = self._upsert_keyed_item(device_config["uart"], item.model_dump(), "port") + results.append({"target": "uart", "port": item.port, "send_status": "成功"}) + path = self.config_repo.write_device_config(device_config) + return { + "save_path": f"/config/{path.name}", + "target": "uart_batch", + "items": len(results), + "send_status": "成功", + "results": results, + } device_config["uart"] = self._upsert_keyed_item(device_config["uart"], payload.model_dump(), "port") path = self.config_repo.write_device_config(device_config) return {"save_path": f"/config/{path.name}", "target": "uart", "port": payload.port, "send_status": "成功"} diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py index cd8a18b..4efffd8 100644 --- a/backend/tests/test_api.py +++ b/backend/tests/test_api.py @@ -407,6 +407,52 @@ def test_save_device_net_and_uart_by_key(tmp_path) -> None: platform_service.config_repo = old_repo +def test_save_device_net_and_uart_batch(tmp_path) -> None: + old_repo = platform_service.config_repo + old_client = platform_service.device_client + platform_service.config_repo = JsonConfigRepository(tmp_path) + platform_service.device_client = MockDeviceClient() + + try: + headers = {"X-API-Token": settings.auth_password} + + net_save = client.post( + "/api/config/device/net", + headers=headers, + json=[ + {"nic": "网卡一", "ip": "192.168.1.10", "mask": "255.255.255.0", "gateway": "192.168.1.1", "protocol": "Modbus TCP"}, + {"nic": "网卡二", "ip": "192.168.2.10", "mask": "255.255.255.0", "gateway": "192.168.2.1", "protocol": "Modbus TCP"}, + ], + ) + uart_save = client.post( + "/api/config/device/uart", + headers=headers, + json=[ + {"port": "COM1", "baud": 9600, "parity": "NONE", "data_bits": 8, "stop_bits": 1, "protocol": "Modbus RTU"}, + {"port": "COM2", "baud": 115200, "parity": "EVEN", "data_bits": 8, "stop_bits": 2, "protocol": "DLT645"}, + ], + ) + net_one = client.get("/api/config/device/net", headers=headers, params={"nic": "网卡一"}) + net_two = client.get("/api/config/device/net", headers=headers, params={"nic": "网卡二"}) + uart_one = client.get("/api/config/device/uart", headers=headers, params={"port": "COM1"}) + uart_two = client.get("/api/config/device/uart", headers=headers, params={"port": "COM2"}) + + assert net_save.status_code == 200 + assert uart_save.status_code == 200 + assert net_save.json()["data"]["target"] == "net_batch" + assert net_save.json()["data"]["items"] == 2 + assert uart_save.json()["data"]["target"] == "uart_batch" + assert uart_save.json()["data"]["items"] == 2 + assert net_one.json()["data"]["ip"] == "192.168.1.10" + assert net_two.json()["data"]["gateway"] == "192.168.2.1" + assert uart_one.json()["data"]["protocol"] == "Modbus RTU" + assert uart_two.json()["data"]["baud"] == 115200 + assert uart_two.json()["data"]["stop_bits"] == 2 + finally: + platform_service.device_client = old_client + platform_service.config_repo = old_repo + + def test_save_device_password_only_updates_password(tmp_path) -> None: old_repo = platform_service.config_repo platform_service.config_repo = JsonConfigRepository(tmp_path)