PLCÄ£ÄâÖ¸ÁîϵͳÉè¼ÆÓëʵÏÖ.docxBinary files differ
gateway/src/main/resources/application.yml
@@ -17,68 +17,4 @@ predicates: - Path=/api/plcSend/** filters: - StripPrefix=2 - id: glassStorage uri: lb://glassStorage predicates: - Path=/api/glassStorage/** - filters: - StripPrefix=2 - id: loadGlass uri: lb://loadGlass predicates: - Path=/api/loadGlass/** filters: - StripPrefix=2 - id: cutting uri: lb://cutting predicates: - Path=/api/cutting/** filters: - StripPrefix=2 - id: horizontal uri: lb://horizontal predicates: - Path=/api/horizontal/** filters: - StripPrefix=2 - id: edging uri: lb://edging predicates: - Path=/api/edging/** filters: - StripPrefix=2 - id: verticalGlass uri: lb://verticalGlass predicates: - Path=/api/verticalGlass/** filters: - StripPrefix=2 - id: temperingGlass uri: lb://temperingGlass predicates: - Path=/api/temperingGlass/** filters: - StripPrefix=2 - id: unLoadGlass uri: lb://unLoadGlass predicates: - Path=/api/unLoadGlass/** filters: - StripPrefix=2 - id: hollowGlass uri: lb://hollowGlass predicates: - Path=/api/hollowGlass/** filters: - StripPrefix=2 gateway/target/classes/application.yml
File was deleted gateway/target/classes/com/mes/GatewayApplication.classBinary files differ
gateway/target/classes/com/mes/config/MyCorsConfig.classBinary files differ
gateway/target/config/application.yml
File was deleted gateway/target/gateway-1.0.0.jarBinary files differ
gateway/target/gateway-1.0.0.jar.originalBinary files differ
gateway/target/lib/HdrHistogram-2.1.9.jarBinary files differ
gateway/target/lib/archaius-core-0.7.6.jarBinary files differ
gateway/target/lib/bcpkix-jdk15on-1.60.jarBinary files differ
gateway/target/lib/bcprov-jdk15on-1.60.jarBinary files differ
gateway/target/lib/classmate-1.4.0.jarBinary files differ
gateway/target/lib/commons-codec-1.11.jarBinary files differ
gateway/target/lib/commons-collections-3.2.2.jarBinary files differ
gateway/target/lib/commons-configuration-1.8.jarBinary files differ
gateway/target/lib/commons-io-2.2.jarBinary files differ
gateway/target/lib/commons-lang-2.6.jarBinary files differ
gateway/target/lib/commons-lang3-3.8.1.jarBinary files differ
gateway/target/lib/fastjson-1.2.47.jarBinary files differ
gateway/target/lib/guava-19.0.jarBinary files differ
gateway/target/lib/hibernate-validator-6.0.17.Final.jarBinary files differ
gateway/target/lib/httpclient-4.5.9.jarBinary files differ
gateway/target/lib/httpcore-4.4.12.jarBinary files differ
gateway/target/lib/hystrix-core-1.5.18.jarBinary files differ
gateway/target/lib/jackson-annotations-2.9.0.jarBinary files differ
gateway/target/lib/jackson-core-2.9.9.jarBinary files differ
gateway/target/lib/jackson-databind-2.9.9.3.jarBinary files differ
gateway/target/lib/jackson-datatype-jdk8-2.9.9.jarBinary files differ
gateway/target/lib/jackson-datatype-jsr310-2.9.9.jarBinary files differ
gateway/target/lib/jackson-module-parameter-names-2.9.9.jarBinary files differ
gateway/target/lib/javax.annotation-api-1.3.2.jarBinary files differ
gateway/target/lib/javax.el-3.0.0.jarBinary files differ
gateway/target/lib/javax.inject-1.jarBinary files differ
gateway/target/lib/jboss-logging-3.3.3.Final.jarBinary files differ
gateway/target/lib/jersey-apache-client4-1.19.1.jarBinary files differ
gateway/target/lib/jersey-client-1.19.1.jarBinary files differ
gateway/target/lib/jersey-core-1.19.1.jarBinary files differ
gateway/target/lib/jsr305-3.0.1.jarBinary files differ
gateway/target/lib/jsr311-api-1.1.1.jarBinary files differ
gateway/target/lib/jul-to-slf4j-1.7.28.jarBinary files differ
gateway/target/lib/log4j-api-2.11.2.jarBinary files differ
gateway/target/lib/log4j-to-slf4j-2.11.2.jarBinary files differ
gateway/target/lib/logback-classic-1.2.3.jarBinary files differ
gateway/target/lib/logback-core-1.2.3.jarBinary files differ
gateway/target/lib/nacos-api-1.1.1.jarBinary files differ
gateway/target/lib/nacos-client-1.1.1.jarBinary files differ
gateway/target/lib/nacos-common-1.1.1.jarBinary files differ
gateway/target/lib/netflix-commons-util-0.3.0.jarBinary files differ
gateway/target/lib/netflix-statistics-0.1.1.jarBinary files differ
gateway/target/lib/netty-buffer-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-codec-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-codec-http-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-codec-http2-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-codec-socks-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-common-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-handler-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-handler-proxy-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-resolver-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-transport-4.1.39.Final.jarBinary files differ
gateway/target/lib/netty-transport-native-epoll-4.1.39.Final-linux-x86_64.jarBinary files differ
gateway/target/lib/netty-transport-native-unix-common-4.1.39.Final.jarBinary files differ
gateway/target/lib/nio-multipart-parser-1.1.0.jarBinary files differ
gateway/target/lib/nio-stream-storage-1.1.3.jarBinary files differ
gateway/target/lib/reactive-streams-1.0.3.jarBinary files differ
gateway/target/lib/reactor-core-3.2.12.RELEASE.jarBinary files differ
gateway/target/lib/reactor-extra-3.2.3.RELEASE.jarBinary files differ
gateway/target/lib/reactor-netty-0.8.11.RELEASE.jarBinary files differ
gateway/target/lib/ribbon-2.3.0.jarBinary files differ
gateway/target/lib/ribbon-core-2.3.0.jarBinary files differ
gateway/target/lib/ribbon-httpclient-2.3.0.jarBinary files differ
gateway/target/lib/ribbon-loadbalancer-2.3.0.jarBinary files differ
gateway/target/lib/ribbon-transport-2.3.0.jarBinary files differ
gateway/target/lib/rxjava-1.3.8.jarBinary files differ
gateway/target/lib/rxnetty-0.4.9.jarBinary files differ
gateway/target/lib/rxnetty-contexts-0.4.9.jarBinary files differ
gateway/target/lib/rxnetty-servo-0.4.9.jarBinary files differ
gateway/target/lib/servo-core-0.12.21.jarBinary files differ
gateway/target/lib/simpleclient-0.5.0.jarBinary files differ
gateway/target/lib/slf4j-api-1.7.28.jarBinary files differ
gateway/target/lib/snakeyaml-1.23.jarBinary files differ
gateway/target/lib/spring-aop-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/spring-beans-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/spring-boot-2.1.8.RELEASE.jarBinary files differ
gateway/target/lib/spring-boot-autoconfigure-2.1.8.RELEASE.jarBinary files differ
gateway/target/lib/spring-boot-starter-2.1.8.RELEASE.jarBinary files differ
gateway/target/lib/spring-boot-starter-json-2.1.8.RELEASE.jarBinary files differ
gateway/target/lib/spring-boot-starter-logging-2.1.8.RELEASE.jarBinary files differ
gateway/target/lib/spring-boot-starter-reactor-netty-2.1.8.RELEASE.jarBinary files differ
gateway/target/lib/spring-boot-starter-webflux-2.1.8.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-alibaba-nacos-discovery-2.1.0.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-commons-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-context-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-gateway-core-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-netflix-archaius-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-netflix-ribbon-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-starter-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-starter-alibaba-nacos-discovery-2.1.0.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-starter-gateway-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-starter-netflix-archaius-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-cloud-starter-netflix-ribbon-2.1.3.RELEASE.jarBinary files differ
gateway/target/lib/spring-context-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/spring-core-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/spring-expression-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/spring-jcl-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/spring-security-crypto-5.1.6.RELEASE.jarBinary files differ
gateway/target/lib/spring-security-rsa-1.0.7.RELEASE.jarBinary files differ
gateway/target/lib/spring-web-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/spring-webflux-5.1.9.RELEASE.jarBinary files differ
gateway/target/lib/validation-api-2.0.1.Final.jarBinary files differ
gateway/target/maven-archiver/pom.properties
File was deleted gateway/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
File was deleted gateway/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
File was deleted mes-common/communication/target/classes/JsonFile/Edg.json
File was deleted mes-common/communication/target/classes/JsonFile/EdgLogicHttp.json
File was deleted mes-common/communication/target/classes/JsonFile/EdgLogicProcedure.json
File was deleted mes-common/communication/target/classes/JsonFile/EdgLogicView.json
File was deleted mes-common/communication/target/classes/JsonFile/ShelfModbusTcp.json
File was deleted mes-common/communication/target/classes/JsonFile/ShelfS7.json
File was deleted mes-common/communication/target/classes/application-cz.yml
File was deleted mes-common/communication/target/classes/application-dev.yml
File was deleted mes-common/communication/target/classes/application-prod.yml
File was deleted mes-common/communication/target/classes/application.yml
File was deleted mes-common/communication/target/classes/com/mes/AppRunnerConfig.classBinary files differ
mes-common/communication/target/classes/com/mes/PlcConnectModuleApplication.classBinary files differ
mes-common/communication/target/classes/com/mes/common/JsonConversion.classBinary files differ
mes-common/communication/target/classes/com/mes/common/ReadFile.classBinary files differ
mes-common/communication/target/classes/com/mes/common/RestTemplateConfig.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/ExampleDataHandler.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/addressparser/ModbusAddressParser.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/addressparser/ModbusIpAddressParser.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/addressparser/ModbusRtuAddressParser.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/addressparser/S7OldAddressParser.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/entity/ApiConfig.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/entity/Logic.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/entity/LogicConfig.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/entity/LogicItem.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/entity/Parameters.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/entity/PlcParameters.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/entity/ReturnValue.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/industrialinterface/AddressParser.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/industrialinterface/ApiImpl.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/industrialinterface/ApiService.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/industrialinterface/IndustrialClient.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/industrialinterface/IndustrialDataHandler.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/industrialinterface/IndustrialServer.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/modbus/ModbusIpClient.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/modbus/ModbusIpServer.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/modbus/ModbusTcpClient.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/modbus/ModbusTcpServer.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/protocol/ProtocolAddress.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/protocol/ProtocolType.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/s7/S7ClientOld.classBinary files differ
mes-common/communication/target/classes/com/mes/connect/thread/MachineThread.classBinary files differ
mes-common/communication/target/classes/com/mes/model/controller/AccountController.classBinary files differ
mes-common/communication/target/classes/com/mes/model/entity/Account.classBinary files differ
mes-common/communication/target/classes/com/mes/model/entity/Machine.classBinary files differ
mes-common/communication/target/classes/com/mes/model/entity/PlcType.classBinary files differ
mes-common/communication/target/classes/com/mes/model/entity/ProtocolType.classBinary files differ
mes-common/communication/target/classes/com/mes/model/mapper/AccountMapper.classBinary files differ
mes-common/communication/target/classes/com/mes/model/mapper/MachineMapper.classBinary files differ
mes-common/communication/target/classes/com/mes/model/mapper/PlcTypeMapper.classBinary files differ
mes-common/communication/target/classes/com/mes/model/mapper/ProtocolTypeMapper.classBinary files differ
mes-common/communication/target/classes/com/mes/model/mapper/xml/AccountMapper.xml
File was deleted mes-common/communication/target/classes/com/mes/model/mapper/xml/MachineMapper.xml
File was deleted mes-common/communication/target/classes/com/mes/model/mapper/xml/PlcTypeMapper.xml
File was deleted mes-common/communication/target/classes/com/mes/model/mapper/xml/ProtocolTypeMapper.xml
File was deleted mes-common/communication/target/classes/com/mes/model/service/AccountService.classBinary files differ
mes-common/communication/target/classes/com/mes/model/service/MachineService.classBinary files differ
mes-common/communication/target/classes/com/mes/model/service/PlcTypeService.classBinary files differ
mes-common/communication/target/classes/com/mes/model/service/ProtocolTypeService.classBinary files differ
mes-common/communication/target/classes/com/mes/model/service/impl/AccountServiceImpl.classBinary files differ
mes-common/communication/target/classes/com/mes/model/service/impl/MachineServiceImpl.classBinary files differ
mes-common/communication/target/classes/com/mes/model/service/impl/PlcTypeServiceImpl.classBinary files differ
mes-common/communication/target/classes/com/mes/model/service/impl/ProtocolTypeServiceImpl.classBinary files differ
mes-common/communication/target/classes/logback-spring.xml
File was deleted mes-common/communication/target/communication-1.0.0.jarBinary files differ
mes-common/communication/target/maven-archiver/pom.properties
File was deleted mes-common/communication/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
File was deleted mes-common/communication/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
File was deleted mes-common/model/target/classes/com/mes/base/request/BaseRequest.classBinary files differ
mes-common/model/target/classes/com/mes/base/request/PageRequest.classBinary files differ
mes-common/model/target/classes/com/mes/base/request/TimeRequest.classBinary files differ
mes-common/model/target/classes/com/mes/cutting/history/CutHistoryTask.classBinary files differ
mes-common/model/target/classes/com/mes/cutting/history/requst/CutTerritoryRequest.classBinary files differ
mes-common/model/target/classes/com/mes/cutting/history/vo/CutTerritoryVO.classBinary files differ
mes-common/model/target/classes/com/mes/cutting/history/vo/CuttingIndexMessageVO.classBinary files differ
mes-common/model/target/classes/com/mes/damage/Damage.classBinary files differ
mes-common/model/target/classes/com/mes/damage/dto/DamageDTO.classBinary files differ
mes-common/model/target/classes/com/mes/damage/request/DamageReportRequest.classBinary files differ
mes-common/model/target/classes/com/mes/damage/request/DamageRequest.classBinary files differ
mes-common/model/target/classes/com/mes/damagedetails/DamageDetails.classBinary files differ
mes-common/model/target/classes/com/mes/edging/history/request/EdgHistoryTaskRequest.classBinary files differ
mes-common/model/target/classes/com/mes/edging/history/request/EdgingRequest.classBinary files differ
mes-common/model/target/classes/com/mes/edging/job/request/EdgJobRequest.classBinary files differ
mes-common/model/target/classes/com/mes/edging/queue/EdgQueueInfo.classBinary files differ
mes-common/model/target/classes/com/mes/edging/queue/request/EdgQueueInfoRequest.classBinary files differ
mes-common/model/target/classes/com/mes/edging/queue/request/EdgUpdateQueueInfoRequest.classBinary files differ
mes-common/model/target/classes/com/mes/edging/queue/vo/EdgIndexMessageVO.classBinary files differ
mes-common/model/target/classes/com/mes/engineering/Engineering.classBinary files differ
mes-common/model/target/classes/com/mes/engineering/request/EngineerRequest.classBinary files differ
mes-common/model/target/classes/com/mes/erp/DamageDetailsList.classBinary files differ
mes-common/model/target/classes/com/mes/erp/RawInventory.classBinary files differ
mes-common/model/target/classes/com/mes/erp/ReportingWork.classBinary files differ
mes-common/model/target/classes/com/mes/erp/ReportingWorkDetail.classBinary files differ
mes-common/model/target/classes/com/mes/flowcard/FlowCardInfo.classBinary files differ
mes-common/model/target/classes/com/mes/flowcard/request/FlowCardInfoImportRequest.classBinary files differ
mes-common/model/target/classes/com/mes/glassinfo/GlassInfo.classBinary files differ
mes-common/model/target/classes/com/mes/glassinfo/request/EngineerUnreportedRequest.classBinary files differ
mes-common/model/target/classes/com/mes/glassinfo/request/GlassInfoImportRequest.classBinary files differ
mes-common/model/target/classes/com/mes/glassinfo/request/NotReportRequest.classBinary files differ
mes-common/model/target/classes/com/mes/glassinfo/vo/ConfigVO.classBinary files differ
mes-common/model/target/classes/com/mes/glassinfo/vo/GlassInfoFlowCardVO.classBinary files differ
mes-common/model/target/classes/com/mes/glassinfo/vo/WorkLineConfigVO.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/formula/HollowFormulaDetails.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/formula/dto/HollowGlassFormulaDTO.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/formula/request/HollowFormulaDetailsImportRequest.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/formula/request/HollowGlassFormulaRequest.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/HollowGlassTaskHistory.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/dto/LisecHollowDetailsDTO.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/dto/LisecHollowFrameDetailsDTO.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/dto/LisecHollowGlassAndFrameDetailsDTO.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/dto/LisecHollowGlassDetailsDTO.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/dto/OrderDTO.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/request/HollowHistoryTaskRequest.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/history/request/HollowTaskRequest.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/queue/HollowGlassQueueInfo.classBinary files differ
mes-common/model/target/classes/com/mes/hollow/queue/request/HollowQueueRequest.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/details/HorizontalSheetCageDetails.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/details/request/HorizontalCageVO.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/details/request/HorizontalDetailsRequest.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/history/HorizontalSheetCageHistoryTask.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/history/request/HorizontalHistoryRequest.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/history/vo/HorizontalHistoryVO.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/station/HorizontalSheetCage.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/station/request/StationRequest.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/station/vo/HorizontalIndexMessageVO.classBinary files differ
mes-common/model/target/classes/com/mes/horizontal/station/vo/HorizontalSheetCageVO.classBinary files differ
mes-common/model/target/classes/com/mes/load/details/LoadStationDetails.classBinary files differ
mes-common/model/target/classes/com/mes/load/details/entity/request/CancelRequest.classBinary files differ
mes-common/model/target/classes/com/mes/load/details/entity/request/LoadStationDetailsRequest.classBinary files differ
mes-common/model/target/classes/com/mes/load/details/entity/request/StationRequest.classBinary files differ
mes-common/model/target/classes/com/mes/load/history/LoadGlassHistoryTask.classBinary files differ
mes-common/model/target/classes/com/mes/load/job/vo/LoadIndexMessageVO.classBinary files differ
mes-common/model/target/classes/com/mes/load/station/entity/LoadStation.classBinary files differ
mes-common/model/target/classes/com/mes/load/station/entity/vo/LoadStationInfoVo.classBinary files differ
mes-common/model/target/classes/com/mes/menu/SysMenu.classBinary files differ
mes-common/model/target/classes/com/mes/optimize/OptimizeProject.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/RawGlassStorageDetails.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/dto/EngineeringDetailDTO.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/dto/RawGlassDetailsDTO.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/request/DetailsRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/request/RawGlassDetailsRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/request/RawGlassQuantityRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/request/RawLoadRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/vo/RawGlassCountVO.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/vo/RawGlassDetailsVO.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/vo/RawIndexMessageVO.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/details/vo/RawLoadDetailsVO.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/history/RawGlassStorageHistoryTask.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/history/dto/GlassStorageTaskDTO.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/history/request/LoadGlassHistoryTaskRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/history/request/LoadGlassHistoryTaskUpdateRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/history/request/RawGlassTaskRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/station/RawGlassStorageStation.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/station/request/LoadStationEnableRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/station/request/LoadStationRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/station/request/StationRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawglass/station/request/UpdateStorageRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawqueue/EngineeringRawQueue.classBinary files differ
mes-common/model/target/classes/com/mes/rawqueue/request/EngineeringRawQueueImportRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawqueue/request/EngineeringRawQueueRequest.classBinary files differ
mes-common/model/target/classes/com/mes/rawqueue/vo/EngineeringRawQueueVO.classBinary files differ
mes-common/model/target/classes/com/mes/reportinfo/ReportInfo.classBinary files differ
mes-common/model/target/classes/com/mes/reportinfo/dto/ReportInfoDTO.classBinary files differ
mes-common/model/target/classes/com/mes/reportinfo/request/ReportQueryRequest.classBinary files differ
mes-common/model/target/classes/com/mes/role/SysRole.classBinary files differ
mes-common/model/target/classes/com/mes/role/SysRoleMenu.classBinary files differ
mes-common/model/target/classes/com/mes/role/vo/SysRoleVO.classBinary files differ
mes-common/model/target/classes/com/mes/sysconfig/SysConfig.classBinary files differ
mes-common/model/target/classes/com/mes/sysconfig/request/SysConfigRequest.classBinary files differ
mes-common/model/target/classes/com/mes/sysdict/SysDictData.classBinary files differ
mes-common/model/target/classes/com/mes/sysdict/SysDictType.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/TemperingComputeGlassInfo.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/TemperingComputeRecord.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/request/GlassDetailsRequest.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/request/ProcessCardsRequest.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/request/TemperingComputeIndexRequest.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/request/TemperingComputeRequest.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/request/TemperingFlowCardIdRequest.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/vo/TemperingComputeResultVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/vo/TemperingFlowCardIdCountVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/vo/TemperingFlowCardIdVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/vo/TemperingGlassDetailsVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/vo/TemperingRatioVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/compute/vo/TempingComputeIndexMessageAllVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/param/TemperingParameter.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/queue/TemperingGlassQueueInfo.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/queue/request/TemperingJobRequest.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/queue/vo/TempIndexMessageAllVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/queue/vo/TemperingLayoutMessageVO.classBinary files differ
mes-common/model/target/classes/com/mes/tempering/request/TemperingParameterImportRequest.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/VerticalSheetCageDetails.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/dto/FlowCardGlassInfoDTO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/dto/VerticalSequenceDTO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/dto/VerticalSheetCageDetailsDTO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/request/HollowRequest.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/request/UpdateVerticalSheetCageStateRequest.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/request/VerticalSheetCageDetailsRequest.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/HollowAllFlowCardVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/TemperingGlassCountVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/TemperingGlassLackVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/VerticalSheetCageAndDetailsVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/VerticalSheetCageDetailsVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/VerticalSheetCageIndexMessageVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/VerticalSheetCageSummaryVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/details/vo/VerticalSheetCageVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/history/VerticalSheetCageHistoryTask.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/history/dto/VerticalSheetCarTaskDTO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/history/request/VerticalSheetCageHistoryRequest.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/hollowrelation/HollowGlassRelationInfo.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/hollowrelation/vo/LackDetailsVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/queue/VerticalSheetCageQueueInfo.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/station/VerticalSheetCage.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/station/dto/VerticalSheetDTO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/temperingtask/TemperingTask.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/temperingtask/dto/TemperingTaskDTO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/temperingtask/request/TemperingTaskRequest.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/temperingtask/vo/TemperingTaskVO.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/temprelation/TemperingGlassRelationInfo.classBinary files differ
mes-common/model/target/classes/com/mes/vertical/temprelation/dto/FlowCardVirtualSlotDTO.classBinary files differ
mes-common/model/target/classes/com/mes/work/WorkAssignment.classBinary files differ
mes-common/model/target/maven-archiver/pom.properties
File was deleted mes-common/model/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
File was deleted mes-common/model/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
File was deleted mes-common/model/target/model-1.0.0.jarBinary files differ
mes-common/serverBase/target/classes/application-common.yml
File was deleted mes-common/serverBase/target/classes/application.yml
File was deleted mes-common/serverBase/target/classes/com/kangaroohy/milo/configuration/MiloAutoConfiguration.classBinary files differ
mes-common/serverBase/target/classes/com/kangaroohy/milo/pool/MiloConnectFactory.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/bigstorage/BigStorageCageBaseInfo.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/damage/controller/DamageController.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/damage/mapper/DamageMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/damage/service/DamageService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/damage/service/impl/DamageServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/damagedetails/mapper/DamageDetailsMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/damagedetails/service/DamageDetailsService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/damagedetails/service/impl/DamageDetailsServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/controller/EngineeringController.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/entity/request/EngineerImportRequest.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/entity/request/EngineerRequest.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/entity/vo/CutDrawingInfoVO.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/mapper/EngineeringMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/service/AbstractEngineeringService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/service/EngineeringService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/service/impl/EngineeringServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/engineering/service/impl/LmEngineeringServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/flowcard/mapper/FlowCardInfoMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/flowcard/service/FlowCardInfoService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/flowcard/service/impl/FlowCardInfoServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/formula/controller/HollowFormulaDetailsController.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/formula/mapper/HollowFormulaDetailsMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/formula/service/HollowFormulaDetailsService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/formula/service/impl/HollowFormulaDetailsServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/glassinfo/controller/GlassInfoController.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/glassinfo/mapper/GlassInfoMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/glassinfo/service/GlassInfoService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/glassinfo/service/impl/GlassInfoServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/rawqueue/controller/EngineeringRawQueueController.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/rawqueue/mapper/EngineeringRawQueueMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/rawqueue/service/EngineeringRawQueueService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/rawqueue/service/impl/EngineeringRawQueueServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/report/controller/ReportController.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/report/mapper/ReportInfoMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/report/service/ReportInfoService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/report/service/impl/ReportInfoServiceImpl$1.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/report/service/impl/ReportInfoServiceImpl$2.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/report/service/impl/ReportInfoServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysconfig/controller/SysConfigController.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysconfig/mapper/SysConfigMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysconfig/service/SysConfigService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysconfig/service/impl/SysConfigServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysdict/mapper/SysDictDataMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysdict/mapper/SysDictTypeMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysdict/service/SysDictDataService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysdict/service/SysDictTypeService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysdict/service/impl/SysDictDataServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/sysdict/service/impl/SysDictTypeServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/tempparameter/mapper/TemperingParameterMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/tempparameter/service/TemperingParameterService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/tempparameter/service/impl/TemperingParameterServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/work/mapper/WorkAssignmentMapper.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/work/service/WorkAssignmentService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/base/work/service/impl/WorkAssignmentServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/config/MybatisPlusConfig.classBinary files differ
mes-common/serverBase/target/classes/com/mes/config/SchedulerConfig.classBinary files differ
mes-common/serverBase/target/classes/com/mes/config/Swagger2Config.classBinary files differ
mes-common/serverBase/target/classes/com/mes/config/WebSocketConfig.classBinary files differ
mes-common/serverBase/target/classes/com/mes/erp/service/ErpService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/erp/service/impl/ErpServiceImpl.classBinary files differ
mes-common/serverBase/target/classes/com/mes/exception/GlobalExceptionHandler.classBinary files differ
mes-common/serverBase/target/classes/com/mes/exception/ServiceException.classBinary files differ
mes-common/serverBase/target/classes/com/mes/feign/ErpUrlOpenFeignService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/feign/MesHubOpenFeignService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/feign/OpenFeignService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/feign/TemperingOpenFeignService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/feign/TemperingTaskOpenFeignService.classBinary files differ
mes-common/serverBase/target/classes/com/mes/request/TimeRequest.classBinary files differ
mes-common/serverBase/target/classes/com/mes/result/ResponseUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/result/Result.classBinary files differ
mes-common/serverBase/target/classes/com/mes/result/ResultCodeEnum.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/InitUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/S7control.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/device/PlcBitInfo.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/device/PlcBitObject.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/device/PlcParameterInfo.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/device/PlcParameterObject.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/enhanced/EnhancedS7Serializer.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/enhanced/S7AddressProperties.classBinary files differ
mes-common/serverBase/target/classes/com/mes/s7/enhanced/S7AnnotationProcessor.classBinary files differ
mes-common/serverBase/target/classes/com/mes/sysconst/Const.classBinary files differ
mes-common/serverBase/target/classes/com/mes/sysconst/ConstRequest.classBinary files differ
mes-common/serverBase/target/classes/com/mes/sysconst/ConstSwitch.classBinary files differ
mes-common/serverBase/target/classes/com/mes/sysconst/ConstSysConfig.classBinary files differ
mes-common/serverBase/target/classes/com/mes/sysconst/ConstWebSocket.classBinary files differ
mes-common/serverBase/target/classes/com/mes/tools/CodeGet.classBinary files differ
mes-common/serverBase/target/classes/com/mes/tools/DatabaseDesignDoc.classBinary files differ
mes-common/serverBase/target/classes/com/mes/tools/EntityTool.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/DateUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/FileUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/JsonUtils.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/MD5.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/NbUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/PageUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/RedisUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/S7ParameterUtils.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/WebNbUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/excel/CustomCellStyleHandler.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/excel/CustomCellWriteWidthConfig.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/excel/ExcelMerge.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/excel/ExcelMergeStrategy.classBinary files differ
mes-common/serverBase/target/classes/com/mes/utils/excel/ExcelUtil.classBinary files differ
mes-common/serverBase/target/classes/com/mes/websocket/WebSocketServer.classBinary files differ
mes-common/serverBase/target/classes/com/mes/websocket/WebSocketUtils.classBinary files differ
mes-common/serverBase/target/classes/mapper/DamageMapper.xml
File was deleted mes-common/serverBase/target/classes/mapper/EngineeringMapper.xml
File was deleted mes-common/serverBase/target/classes/mapper/EngineeringRawQueueMapper.xml
File was deleted mes-common/serverBase/target/classes/mapper/GlassInfoMapper.xml
File was deleted mes-common/serverBase/target/maven-archiver/pom.properties
File was deleted mes-common/serverBase/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
File was deleted mes-common/serverBase/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
File was deleted mes-common/serverBase/target/serverBase-1.0.0.jarBinary files differ
mes-common/springSecurity/target/classes/application-dev.yml
File was deleted mes-common/springSecurity/target/classes/application-loc.yml
File was deleted mes-common/springSecurity/target/classes/application-prod.yml
File was deleted mes-common/springSecurity/target/classes/com/mes/common/config/RedisConfig.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/config/TokenWebSecurityConfig.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/filter/JwtAuthenticationTokenFilter.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/handler/JwtAccessDeniedHandler.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/handler/JwtAuthenticationEntryPoint.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/handler/JwtLogoutSuccessHandler.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/handler/LoginFailureHandler.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/handler/LoginSuccessHandler.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/utils/FastJsonRedisSerializer.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/utils/JwtUtil.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/utils/UserInfoUtils.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/common/utils/WebUtils.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/menu/controller/SysMenuController.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/menu/mapper/SysMenuMapper.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/menu/service/SysMenuService.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/menu/service/impl/SysMenuServiceImpl.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/role/controller/SysRoleController.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/role/mapper/SysRoleMapper.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/role/mapper/SysRoleMenuMapper.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/role/mapper/xml/SysRoleMapper.xml
File was deleted mes-common/springSecurity/target/classes/com/mes/role/mapper/xml/SysRoleMenuMapper.xml
File was deleted mes-common/springSecurity/target/classes/com/mes/role/service/SysRoleMenuService.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/role/service/SysRoleService.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/role/service/impl/SysRoleMenuServiceImpl.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/role/service/impl/SysRoleServiceImpl.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/controller/SysUserController.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/entity/LoginUser.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/entity/SysUser.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/entity/SysUserRole.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/entity/vo/SysUserVO.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/mapper/SysUserMapper.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/mapper/SysUserRoleMapper.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/service/SysUserRoleService.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/service/SysUserService.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/service/impl/SysUserRoleServiceImpl.classBinary files differ
mes-common/springSecurity/target/classes/com/mes/userinfo/service/impl/SysUserServiceImpl.classBinary files differ
mes-common/springSecurity/target/classes/mapper/SysMenuMapper.xml
File was deleted mes-common/springSecurity/target/classes/mapper/SysUserMapper.xml
File was deleted mes-common/springSecurity/target/classes/mapper/SysUserRoleMapper.xml
File was deleted mes-common/springSecurity/target/maven-archiver/pom.properties
File was deleted mes-common/springSecurity/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
File was deleted mes-common/springSecurity/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
File was deleted mes-common/springSecurity/target/springSecurity-1.0.0.jarBinary files differ
mes-processes/mes-plcSend/README_PLC_ADDRESS_MAPPING.md
@@ -20,16 +20,16 @@ - æ¯æä»é ç½®æä»¶å è½½é»è®¤é ç½® ### 2. PlcAddressMapping - ä½ç½®ï¼`com.mes.entity.PlcAddressMapping` - ä½ç½®ï¼`com.mes.entity.PlcAddress` - åè½ï¼å®ä½ç±»ï¼å¯¹åºæ°æ®åºè¡¨ç»æ - åå¨é¡¹ç®PLCå°åæ å°é ç½® ### 3. PlcAddressMappingMapper - ä½ç½®ï¼`com.mes.mapper.PlcAddressMappingMapper` - ä½ç½®ï¼`com.mes.mapper.PlcAddressMapper` - åè½ï¼MyBatis Mapperæ¥å£ï¼æä¾æ°æ®åºæä½ ### 4. PlcAddressMappingService - ä½ç½®ï¼`com.mes.service.PlcAddressMappingService` - ä½ç½®ï¼`com.mes.service.PlcAddressService` - åè½ï¼æå¡ç±»ï¼æä¾PLCå°åæ å°é ç½®çå¢å æ¹æ¥åè½ - æ¯æä»æ°æ®åºåé ç½®æä»¶å è½½é ç½® @@ -39,7 +39,7 @@ - ç¼åä¸å项ç®çS7Serializerå®ä¾ ### 6. PlcAddressMappingController - ä½ç½®ï¼`com.mes.controller.PlcAddressMappingController` - ä½ç½®ï¼`com.mes.controller.PlcAddressController` - åè½ï¼æ§å¶å¨ï¼æä¾REST APIæ¥å£ ## APIæ¥å£ mes-processes/mes-plcSend/src/main/java/com/mes/controller/PlcAddressController.java
@@ -1,9 +1,8 @@ package com.mes.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.mes.config.PlcAddressMappingConfig; import com.mes.entity.PlcAddressMapping; import com.mes.service.PlcAddressMappingService; import com.mes.entity.PlcAddress; import com.mes.service.PlcAddressService; import com.mes.vo.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -20,26 +19,26 @@ * PLCå°åæ å°é ç½®æ§å¶å¨ * æä¾PLCå°åæ å°é ç½®çå¢å æ¹æ¥æ¥å£ * * @author zhoush * @author huang * @date 2025/10/29 */ @Slf4j @RestController @RequestMapping("address-mapping") @Api(tags = "PLCå°åæ å°é 置管ç") public class PlcAddressMappingController { public class PlcAddressController { @Resource private PlcAddressMappingService plcAddressMappingService; private PlcAddressService plcAddressService; /** * è·åææPLCå°åæ å°é ç½® */ @GetMapping("/list") @ApiOperation("è·åææPLCå°åæ å°é ç½®") public Result<List<PlcAddressMapping>> getAllMappings() { public Result<List<PlcAddress>> getAllMappings() { try { List<PlcAddressMapping> mappings = plcAddressMappingService.getAllMappings(); List<PlcAddress> mappings = plcAddressService.getAllMappings(); return Result.success(mappings); } catch (Exception e) { log.error("è·åPLCå°åæ å°é ç½®å表失败", e); @@ -52,13 +51,13 @@ */ @GetMapping("/page") @ApiOperation("å页è·åPLCå°åæ å°é ç½®") public Result<IPage<PlcAddressMapping>> getMappingsByPage( public Result<IPage<PlcAddress>> getMappingsByPage( @ApiParam("页ç ï¼ä»1å¼å§") @RequestParam(defaultValue = "1") int page, @ApiParam("æ¯é¡µæ¡æ°") @RequestParam(defaultValue = "10") int size, @ApiParam("é¡¹ç®æ è¯ï¼æ¯ææ¨¡ç³æ¥è¯¢") @RequestParam(required = false) String projectId, @ApiParam("PLC IPå°åï¼æ¯ææ¨¡ç³æ¥è¯¢") @RequestParam(required = false) String plcIp) { try { IPage<PlcAddressMapping> pageResult = plcAddressMappingService.getMappingsByPage(page, size, projectId, plcIp); IPage<PlcAddress> pageResult = plcAddressService.getMappingsByPage(page, size, projectId, plcIp); return Result.success(pageResult); } catch (Exception e) { log.error("å页è·åPLCå°åæ å°é 置失败", e); @@ -69,12 +68,12 @@ /** * æ ¹æ®IDè·åPLCå°åæ å°é ç½® */ @GetMapping("/{id}") @GetMapping("/detail") @ApiOperation("æ ¹æ®IDè·åPLCå°åæ å°é ç½®") public Result<PlcAddressMapping> getMappingById( @ApiParam("é ç½®ID") @PathVariable Long id) { public Result<PlcAddress> getMappingById( @ApiParam("é ç½®ID") @RequestParam Long id) { try { PlcAddressMapping mapping = plcAddressMappingService.getMappingById(id); PlcAddress mapping = plcAddressService.getMappingById(id); if (mapping != null) { return Result.success(mapping); } else { @@ -89,12 +88,12 @@ /** * æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é ç½® */ @GetMapping("/project/{projectId}") @GetMapping("/project") @ApiOperation("æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é ç½®") public Result<PlcAddressMapping> getMappingByProjectId( @ApiParam("é¡¹ç®æ è¯") @PathVariable String projectId) { public Result<PlcAddress> getMappingByProjectId( @ApiParam("é¡¹ç®æ è¯") @RequestParam String projectId) { try { PlcAddressMapping mapping = plcAddressMappingService.getMappingByProjectId(projectId); PlcAddress mapping = plcAddressService.getMappingByProjectId(projectId); if (mapping != null) { return Result.success(mapping); } else { @@ -114,22 +113,28 @@ @ApiOperation("æ ¹æ®é¡¹ç®IDè·å项ç®é ç½®ï¼å å«å°åæ å°ï¼") public Result<Map<String, Object>> getProjectConfig(String projectId) { try { // è·ååºç¡é ç½® PlcAddressMapping mapping = plcAddressMappingService.getMappingByProjectId(projectId); PlcAddress mapping = plcAddressService.getProjectConfig(projectId); // è·å宿´é¡¹ç®é ç½®ï¼å å«å°åæ å°ï¼ PlcAddressMappingConfig.ProjectPlcConfig projectConfig = plcAddressMappingService.getProjectConfigWithMapping(projectId); // åå¹¶åºç¡é ç½®ä¿¡æ¯ // ç»è£ è¾åºï¼ä» åºäºæ°æ®åºå®ä½ Map<String, Object> result = new HashMap<>(); result.put("projectId", projectId); result.put("dbArea", projectConfig.getDbArea()); result.put("beginIndex", projectConfig.getBeginIndex()); result.put("plcIp", projectConfig.getPlcIp()); result.put("plcType", projectConfig.getPlcType()); result.put("addressMapping", projectConfig.getAddressMapping()); result.put("dbArea", mapping != null ? mapping.getDbArea() : "DB1"); result.put("beginIndex", mapping != null ? mapping.getBeginIndex() : 0); result.put("plcIp", mapping != null ? mapping.getPlcIp() : null); result.put("plcType", mapping != null ? mapping.getPlcType() : null); // å¦ææ°æ®åºä¸æé ç½®ï¼æ·»å æ°æ®åºä¸çé¢å¤ä¿¡æ¯ // è§£æaddressMapping JSON为Map Map<String, Integer> addressMap = new HashMap<>(); if (mapping != null && mapping.getAddressMapping() != null && !mapping.getAddressMapping().trim().isEmpty()) { try { addressMap = new com.fasterxml.jackson.databind.ObjectMapper() .readValue(mapping.getAddressMapping(), new com.fasterxml.jackson.core.type.TypeReference<Map<String, Integer>>() {}); } catch (Exception parseEx) { log.warn("è§£æå°åæ å°JSON失败: {}", mapping.getAddressMapping()); } } result.put("addressMapping", addressMap); if (mapping != null) { result.put("id", mapping.getId()); result.put("projectName", mapping.getProjectName()); @@ -148,8 +153,8 @@ */ @PostMapping @ApiOperation("å建æ°çPLCå°åæ å°é ç½®") public Result<PlcAddressMapping> createMapping( @ApiParam("PLCå°åæ å°é ç½®") @RequestBody PlcAddressMapping mapping) { public Result<PlcAddress> createMapping( @ApiParam("PLCå°åæ å°é ç½®") @RequestBody PlcAddress mapping) { try { // åæ°éªè¯ if (mapping.getProjectId() == null || mapping.getProjectId().trim().isEmpty()) { @@ -163,7 +168,7 @@ mapping.setBeginIndex(0); // å¦æä¸ºè´æ°ï¼è®¾ç½®ä¸ºé»è®¤èµ·å§ç´¢å¼0 } PlcAddressMapping created = plcAddressMappingService.saveMapping(mapping); PlcAddress created = plcAddressService.saveMapping(mapping); log.info("å建PLCå°åæ å°é ç½®æåï¼ID: {}, é¡¹ç®æ è¯: {}", created.getId(), created.getProjectId()); return Result.success(created); } catch (Exception e) { @@ -175,11 +180,11 @@ /** * æ´æ°PLCå°åæ å°é ç½® */ @PutMapping("/{id}") @PutMapping("/update") @ApiOperation("æ´æ°PLCå°åæ å°é ç½®") public Result<PlcAddressMapping> updateMapping( @ApiParam("é ç½®ID") @PathVariable Long id, @ApiParam("æ´æ°çPLCå°åæ å°é ç½®") @RequestBody PlcAddressMapping mapping) { public Result<PlcAddress> updateMapping( @ApiParam("é ç½®ID") @RequestParam Long id, @ApiParam("æ´æ°çPLCå°åæ å°é ç½®") @RequestBody PlcAddress mapping) { try { // åæ°éªè¯ if (mapping.getProjectId() == null || mapping.getProjectId().trim().isEmpty()) { @@ -190,7 +195,7 @@ } mapping.setId(id); PlcAddressMapping updated = plcAddressMappingService.updateMapping(mapping); PlcAddress updated = plcAddressService.updateMapping(mapping); if (updated != null) { log.info("æ´æ°PLCå°åæ å°é ç½®æåï¼ID: {}, é¡¹ç®æ è¯: {}", updated.getId(), updated.getProjectId()); return Result.success(updated); @@ -207,11 +212,11 @@ * æ ¹æ®é¡¹ç®IDæ´æ°é ç½® * 对åºå端ï¼updateConfig */ @PutMapping("/project/{projectId}") @PutMapping("/project/update") @ApiOperation("æ ¹æ®é¡¹ç®IDæ´æ°é ç½®") public Result<PlcAddressMapping> updateMappingByProjectId( @ApiParam("é¡¹ç®æ è¯") @PathVariable String projectId, @ApiParam("æ´æ°çPLCå°åæ å°é ç½®") @RequestBody PlcAddressMapping mapping) { public Result<PlcAddress> updateMappingByProjectId( @ApiParam("é¡¹ç®æ è¯") @RequestParam String projectId, @ApiParam("æ´æ°çPLCå°åæ å°é ç½®") @RequestBody PlcAddress mapping) { try { // åæ°éªè¯ if (mapping.getDbArea() == null || mapping.getDbArea().trim().isEmpty()) { @@ -222,16 +227,16 @@ mapping.setProjectId(projectId); // æ¥æ¾ç°æé ç½® PlcAddressMapping existing = plcAddressMappingService.getMappingByProjectId(projectId); PlcAddress existing = plcAddressService.getMappingByProjectId(projectId); if (existing != null) { // æ´æ°ç°æé ç½® mapping.setId(existing.getId()); PlcAddressMapping updated = plcAddressMappingService.updateMapping(mapping); PlcAddress updated = plcAddressService.updateMapping(mapping); log.info("æ ¹æ®é¡¹ç®IDæ´æ°PLCå°åæ å°é ç½®æåï¼é¡¹ç®æ è¯: {}", projectId); return Result.success(updated); } else { // å建æ°é ç½® PlcAddressMapping created = plcAddressMappingService.saveMapping(mapping); PlcAddress created = plcAddressService.saveMapping(mapping); log.info("æ ¹æ®é¡¹ç®IDå建PLCå°åæ å°é ç½®æåï¼é¡¹ç®æ è¯: {}", projectId); return Result.success(created); } @@ -244,12 +249,12 @@ /** * å é¤PLCå°åæ å°é ç½® */ @DeleteMapping("/{id}") @DeleteMapping("/delete") @ApiOperation("å é¤PLCå°åæ å°é ç½®") public Result<Void> deleteMapping( @ApiParam("é ç½®ID") @PathVariable Long id) { @ApiParam("é ç½®ID") @RequestParam Long id) { try { boolean deleted = plcAddressMappingService.deleteMapping(id); boolean deleted = plcAddressService.deleteMapping(id); if (deleted) { log.info("å é¤PLCå°åæ å°é ç½®æåï¼ID: {}", id); return Result.success(); @@ -274,7 +279,7 @@ return Result.error("IDå表ä¸è½ä¸ºç©º"); } int deletedCount = plcAddressMappingService.deleteMappings(ids); int deletedCount = plcAddressService.deleteMappings(ids); log.info("æ¹éå é¤PLCå°åæ å°é ç½®æåï¼å 餿°é: {}, IDå表: {}", deletedCount, ids); return Result.success(); } catch (Exception e) { @@ -286,17 +291,17 @@ /** * æµè¯PLCè¿æ¥ */ @PostMapping("/{id}/test-connection") @PostMapping("/test-connection") @ApiOperation("æµè¯PLCè¿æ¥") public Result<String> testConnection( @ApiParam("é ç½®ID") @PathVariable Long id) { @ApiParam("é ç½®ID") @RequestParam Long id) { try { PlcAddressMapping mapping = plcAddressMappingService.getMappingById(id); PlcAddress mapping = plcAddressService.getMappingById(id); if (mapping == null) { return Result.error("æªæ¾å°ID为 " + id + " çPLCå°åæ å°é ç½®"); } boolean isConnected = plcAddressMappingService.testConnection(mapping); boolean isConnected = plcAddressService.testConnection(mapping); if (isConnected) { String message = String.format("PLCè¿æ¥æµè¯æå - 项ç®: %s, IP: %s, DBå: %s", mapping.getProjectId(), mapping.getPlcIp(), mapping.getDbArea()); @@ -321,7 +326,7 @@ @ApiOperation("éæ°å è½½é ç½®æä»¶ä¸çå°åæ å°") public Result<String> reloadConfig() { try { plcAddressMappingService.reloadConfigMappings(); plcAddressService.reloadConfigMappings(); String message = "é ç½®æä»¶ä¸çPLCå°åæ å°å·²éæ°å è½½"; log.info(message); return Result.success(message); mes-processes/mes-plcSend/src/main/java/com/mes/controller/PlcTestController.java
New file @@ -0,0 +1,376 @@ package com.mes.controller; import com.mes.service.PlcAutoTestService; import com.mes.service.PlcTestWriteService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * PLCæµè¯ä»»å¡æ§å¶å¨ * æä¾PLCæµè¯ä»»å¡ç®¡çç¸å ³çAPIæ¥å£ * <p> * å®ç°å端Test.vueç»ä»¶æéçææAPIæ¥å£ * * @author huang * @date 2025/10/30 */ @Slf4j @RestController @RequestMapping("/api/plc/test") @Api(tags = "PLCæµè¯ä»»å¡ç®¡ç") public class PlcTestController { @Resource private PlcTestWriteService plcTestWriteService; @Resource private PlcAutoTestService plcAutoTestService; // 模æä»»å¡æ°æ®åå¨ private final Map<String, Map<String, Object>> taskMap = new ConcurrentHashMap<>(); private final Map<String, Map<String, Object>> moduleStatusMap = new ConcurrentHashMap<>(); /** * æ§è¡æå®æ¨¡åçæµè¯ä»»å¡ * 对åºå端ï¼submitTest */ @PostMapping("/execute/{module}") @ApiOperation("æ§è¡æå®æ¨¡åçæµè¯ä»»å¡") public Map<String, Object> executeTest(@ApiParam("模ååç§°") @PathVariable String module) { log.info("æ§è¡æµè¯ä»»å¡ï¼æ¨¡å: {}", module); Map<String, Object> result = new HashMap<>(); try { // æ¨¡ææ§è¡æµè¯ä»»å¡ boolean success = plcTestWriteService.simulatePlcRequest(module); // å建任å¡è®°å½ String taskId = UUID.randomUUID().toString(); Map<String, Object> task = new HashMap<>(); task.put("id", taskId); task.put("module", module); task.put("status", success ? "running" : "failed"); task.put("createTime", new Date()); task.put("message", success ? "æµè¯ä»»å¡å·²å¯å¨" : "æµè¯ä»»å¡å¯å¨å¤±è´¥"); taskMap.put(taskId, task); // æ´æ°æ¨¡åç¶æ updateModuleStatus(module, "running"); result.put("success", success); result.put("data", taskId); result.put("message", success ? "æµè¯ä»»å¡å·²å¯å¨" : "æµè¯ä»»å¡å¯å¨å¤±è´¥"); } catch (Exception e) { log.error("æ§è¡æµè¯ä»»å¡å¼å¸¸ï¼æ¨¡å: {}", module, e); result.put("success", false); result.put("message", "æ§è¡æµè¯ä»»å¡å¼å¸¸: " + e.getMessage()); } return result; } /** * è·åæå®æ¨¡åçä»»å¡ç¶æ * 对åºå端ï¼getTaskStatus */ @GetMapping("/status/{module}") @ApiOperation("è·åæå®æ¨¡åçä»»å¡ç¶æ") public Map<String, Object> getTaskStatus(@ApiParam("模ååç§°") @PathVariable String module) { log.info("è·åä»»å¡ç¶æï¼æ¨¡å: {}", module); Map<String, Object> result = new HashMap<>(); try { // æ¥æ¾è¯¥æ¨¡åçææ°ä»»å¡ Optional<Map.Entry<String, Map<String, Object>>> latestTask = taskMap.entrySet().stream() .filter(entry -> module.equals(entry.getValue().get("module"))) .max(Map.Entry.comparingByKey()); if (latestTask.isPresent()) { Map<String, Object> task = latestTask.get().getValue(); // 模æä»»å¡ç¶æåå String status = (String) task.get("status"); if ("running".equals(status)) { // éæºå³å®ä»»å¡æ¯å¦å®æ if (Math.random() > 0.5) { task.put("status", "success"); task.put("message", "æµè¯ä»»å¡æ§è¡æå"); updateModuleStatus(module, "idle"); } } result.put("success", true); result.put("data", task); } else { result.put("success", false); result.put("message", "æªæ¾å°æ¨¡åçä»»å¡è®°å½"); } } catch (Exception e) { log.error("è·åä»»å¡ç¶æå¼å¸¸ï¼æ¨¡å: {}", module, e); result.put("success", false); result.put("message", "è·åä»»å¡ç¶æå¼å¸¸: " + e.getMessage()); } return result; } /** * æ¹éæµè¯ * 对åºå端ï¼batchTest */ @PostMapping("/batch") @ApiOperation("æ¹éæµè¯") public Map<String, Object> batchTest(@ApiParam("æ¹éæµè¯è¯·æ±") @RequestBody Map<String, Object> request) { List<String> modules = (List<String>) request.get("modules"); log.info("æ§è¡æ¹éæµè¯ï¼æ¨¡åå表: {}", modules); Map<String, Object> result = new HashMap<>(); List<Map<String, Object>> results = new ArrayList<>(); try { for (String module : modules) { Map<String, Object> moduleResult = new HashMap<>(); moduleResult.put("module", module); try { boolean success = plcTestWriteService.simulatePlcRequest(module); moduleResult.put("success", success); moduleResult.put("message", success ? "æµè¯ä»»å¡å·²å¯å¨" : "æµè¯ä»»å¡å¯å¨å¤±è´¥"); if (success) { updateModuleStatus(module, "running"); } } catch (Exception e) { moduleResult.put("success", false); moduleResult.put("message", "æ§è¡æµè¯å¼å¸¸: " + e.getMessage()); log.error("æ¹éæµè¯æ¨¡åå¼å¸¸ï¼æ¨¡å: {}", module, e); } results.add(moduleResult); } result.put("success", true); result.put("data", results); result.put("message", "æ¹éæµè¯ä»»å¡å·²æäº¤"); } catch (Exception e) { log.error("æ¹éæµè¯å¼å¸¸", e); result.put("success", false); result.put("message", "æ¹éæµè¯å¼å¸¸: " + e.getMessage()); } return result; } /** * å¯¼å ¥æµè¯ä»»å¡ * 对åºå端ï¼importTask */ @PostMapping("/import") @ApiOperation("å¯¼å ¥æµè¯ä»»å¡") public Map<String, Object> importTask(@ApiParam("任塿件") @RequestParam("file") MultipartFile file) { log.info("å¯¼å ¥æµè¯ä»»å¡æä»¶: {}", file.getOriginalFilename()); Map<String, Object> result = new HashMap<>(); try { // è¿éåªæ¯æ¨¡æå¯¼å ¥åè½ // å®é åºè¯¥è§£ææä»¶å 容ï¼å建æµè¯ä»»å¡ result.put("success", true); result.put("data", file.getOriginalFilename()); result.put("message", "æµè¯ä»»å¡å¯¼å ¥æå"); } catch (Exception e) { log.error("å¯¼å ¥æµè¯ä»»å¡å¼å¸¸", e); result.put("success", false); result.put("message", "å¯¼å ¥æµè¯ä»»å¡å¼å¸¸: " + e.getMessage()); } return result; } /** * è·åæææ¨¡åç¶æ * 对åºå端ï¼getModulesStatus */ @GetMapping("/modules/status") @ApiOperation("è·åæææ¨¡åç¶æ") public Map<String, Object> getModulesStatus() { log.info("è·åæææ¨¡åç¶æ"); Map<String, Object> result = new HashMap<>(); try { // åå§åé»è®¤æ¨¡åç¶æï¼å¦æä¸åå¨ï¼ initDefaultModuleStatus(); // æ´æ°æææ¨¡åç¶æ for (String module : moduleStatusMap.keySet()) { checkModuleStatus(module); } result.put("success", true); result.put("data", new ArrayList<>(moduleStatusMap.values())); } catch (Exception e) { log.error("è·å模åç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "è·å模åç¶æå¼å¸¸: " + e.getMessage()); } return result; } /** * éç½®æå®æ¨¡å * 对åºå端ï¼resetModule */ @PostMapping("/reset/{module}") @ApiOperation("éç½®æå®æ¨¡å") public Map<String, Object> resetModule(@ApiParam("模ååç§°") @PathVariable String module) { log.info("é置模å: {}", module); Map<String, Object> result = new HashMap<>(); try { boolean success = plcTestWriteService.resetPlc(module); if (success) { updateModuleStatus(module, "idle"); // æ¸ é¤è¯¥æ¨¡åçææä»»å¡ taskMap.entrySet().removeIf(entry -> module.equals(entry.getValue().get("module"))); } result.put("success", success); result.put("message", success ? "模åéç½®æå" : "模åé置失败"); } catch (Exception e) { log.error("é置模åå¼å¸¸ï¼æ¨¡å: {}", module, e); result.put("success", false); result.put("message", "é置模åå¼å¸¸: " + e.getMessage()); } return result; } /** * éè¯æå®æ¨¡åçä»»å¡ * 对åºå端ï¼retryTask */ @PostMapping("/retry/{module}") @ApiOperation("éè¯æå®æ¨¡åçä»»å¡") public Map<String, Object> retryTask(@ApiParam("模ååç§°") @PathVariable String module) { log.info("éè¯æ¨¡åä»»å¡: {}", module); Map<String, Object> result = new HashMap<>(); try { // å é置模å plcTestWriteService.resetPlc(module); // ç¶åéæ°æ§è¡æµè¯ boolean success = plcTestWriteService.simulatePlcRequest(module); // å建æ°ä»»å¡è®°å½ String taskId = UUID.randomUUID().toString(); Map<String, Object> task = new HashMap<>(); task.put("id", taskId); task.put("module", module); task.put("status", success ? "running" : "failed"); task.put("createTime", new Date()); task.put("message", success ? "æµè¯ä»»å¡å·²éå¯" : "æµè¯ä»»å¡éå¯å¤±è´¥"); taskMap.put(taskId, task); if (success) { updateModuleStatus(module, "running"); } result.put("success", success); result.put("data", taskId); result.put("message", success ? "æµè¯ä»»å¡å·²éå¯" : "æµè¯ä»»å¡éå¯å¤±è´¥"); } catch (Exception e) { log.error("éè¯æ¨¡åä»»å¡å¼å¸¸ï¼æ¨¡å: {}", module, e); result.put("success", false); result.put("message", "éè¯æ¨¡åä»»å¡å¼å¸¸: " + e.getMessage()); } return result; } /** * 忢æå®æ¨¡åçæµè¯ * 对åºå端ï¼stopTest */ @PostMapping("/stop/{module}") @ApiOperation("忢æå®æ¨¡åçæµè¯") public Map<String, Object> stopTest(@ApiParam("模ååç§°") @PathVariable String module) { log.info("åæ¢æ¨¡åæµè¯: {}", module); Map<String, Object> result = new HashMap<>(); try { // éç½®PLCç¶ææ¥åæ¢æµè¯ boolean success = plcTestWriteService.resetPlc(module); if (success) { updateModuleStatus(module, "idle"); // æ´æ°è¯¥æ¨¡åçææè¿è¡ä¸ä»»å¡ç¶æ taskMap.entrySet().stream() .filter(entry -> module.equals(entry.getValue().get("module")) && "running".equals(entry.getValue().get("status"))) .forEach(entry -> { entry.getValue().put("status", "stopped"); entry.getValue().put("message", "æµè¯ä»»å¡å·²æå¨åæ¢"); }); } result.put("success", success); result.put("message", success ? "æµè¯å·²åæ¢" : "忢æµè¯å¤±è´¥"); } catch (Exception e) { log.error("åæ¢æ¨¡åæµè¯å¼å¸¸ï¼æ¨¡å: {}", module, e); result.put("success", false); result.put("message", "åæ¢æ¨¡åæµè¯å¼å¸¸: " + e.getMessage()); } return result; } // åå§åé»è®¤æ¨¡åç¶æ private void initDefaultModuleStatus() { // å®ä¹é»è®¤ç模åå表 List<String> defaultModules = Arrays.asList( "gantryStorage", "upperModule", "lowerModule", "stackerModule", "shuttleModule", "verticalModule", "horizontalModule" ); for (String module : defaultModules) { moduleStatusMap.computeIfAbsent(module, k -> { Map<String, Object> status = new HashMap<>(); status.put("module", module); status.put("status", "idle"); status.put("updateTime", new Date()); return status; }); } } // æ´æ°æ¨¡åç¶æ private void updateModuleStatus(String module, String status) { Map<String, Object> moduleStatus = moduleStatusMap.computeIfAbsent(module, k -> new HashMap<>()); moduleStatus.put("module", module); moduleStatus.put("status", status); moduleStatus.put("updateTime", new Date()); } // æ£æ¥å¹¶æ´æ°æ¨¡åç¶æ private void checkModuleStatus(String module) { Map<String, Object> moduleStatus = moduleStatusMap.get(module); if (moduleStatus != null) { String status = (String) moduleStatus.get("status"); // å¦ææ¨¡åç¶æä¸ºrunningï¼å¯ä»¥å¨è¿éæ·»å é»è¾æ¥æ£æ¥å®é ç¶æ // è¿éç®å模æç¶æåå if ("running".equals(status) && Math.random() > 0.7) { moduleStatus.put("status", "idle"); moduleStatus.put("updateTime", new Date()); } } } } mes-processes/mes-plcSend/src/main/java/com/mes/controller/PlcTestWriteController.java
@@ -1,343 +1,128 @@ package com.mes.controller; import com.mes.entity.PlcBaseData; import com.mes.service.PlcAutoTestService; import com.mes.service.PlcTestWriteService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; /** * PLCæµè¯åå ¥æ§å¶å¨ * 为å端æä¾æ¨¡æPLCåå ¥æä½çæ¥å£ * æä¾PLCæµè¯åå ¥ç¸å ³çAPIæ¥å£ * * @author zhoush * @author huang * @date 2025/10/29 */ @Slf4j @RestController @RequestMapping("/plcTest/write") @RequestMapping("/api/plc/test") @Api(tags = "PLCæµè¯åå ¥æ¥å£") public class PlcTestWriteController { @Resource private PlcTestWriteService plcTestWriteService; @Resource private PlcAutoTestService plcAutoTestService; /** * 模æPLCåé请æ±å */ @PostMapping("/request") public Map<String, Object> simulateRequest(@RequestBody(required = false) Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { boolean success; if (params != null && params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); success = plcTestWriteService.simulatePlcRequest(dbBlock, beginIndex); } else { success = plcTestWriteService.simulatePlcRequest(); } result.put("success", success); result.put("message", success ? "PLC请æ±ååéæå" : "åé失败"); // è¿åå½åç¶æ PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("模æPLC请æ±å¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); @PostMapping("/simulate/request") @ApiOperation("模æPLCåé请æ±åï¼è§¦åMESä»»å¡ä¸åï¼") public boolean simulatePlcRequest( @ApiParam(value = "é¡¹ç®æ è¯ï¼å¦verticalãhorizontalçï¼ä¸æå®å使ç¨é»è®¤é¡¹ç®", example = "vertical") @RequestParam(required = false) String projectId) { if (projectId != null && !projectId.trim().isEmpty()) { return plcTestWriteService.simulatePlcRequest(projectId.trim()); } else { return plcTestWriteService.simulatePlcRequest(); } return result; } /** * 模æPLCä»»å¡å®ææ±æ¥ */ @PostMapping("/report") public Map<String, Object> simulateReport(@RequestBody(required = false) Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { boolean success; if (params != null && params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); success = plcTestWriteService.simulatePlcReport(dbBlock, beginIndex); } else { success = plcTestWriteService.simulatePlcReport(); } result.put("success", success); result.put("message", success ? "PLC任塿±æ¥æå" : "æ±æ¥å¤±è´¥"); PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("模æä¸çPLCæ±æ¥å¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); @PostMapping("/simulate/report") @ApiOperation("模æPLCä»»å¡å®ææ±æ¥") public boolean simulatePlcReport( @ApiParam(value = "é¡¹ç®æ è¯ï¼å¦verticalãhorizontalçï¼ä¸æå®å使ç¨é»è®¤é¡¹ç®", example = "vertical") @RequestParam(required = false) String projectId) { if (projectId != null && !projectId.trim().isEmpty()) { return plcTestWriteService.simulatePlcReport(projectId.trim()); } else { return plcTestWriteService.simulatePlcReport(); } return result; } /** * 模æPLCèæºç¶æ */ @PostMapping("/online") public Map<String, Object> simulateOnline(@RequestBody Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { int onlineState = (int) params.getOrDefault("onlineState", 1); boolean success; if (params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); success = plcTestWriteService.simulateOnlineStatus(onlineState, dbBlock, beginIndex); } else { success = plcTestWriteService.simulateOnlineStatus(onlineState); } result.put("success", success); result.put("message", success ? "PLCèæºç¶æè®¾ç½®æå: " + onlineState : "设置失败"); PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("模æPLCèæºç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); @PostMapping("/simulate/online") @ApiOperation("模æPLCåéèæºç¶æ") public boolean simulateOnlineStatus( @ApiParam(value = "èæºç¶æï¼1-èæºï¼0-è±æº", required = true, example = "1") @RequestParam int onlineState, @ApiParam(value = "é¡¹ç®æ è¯ï¼å¦verticalãhorizontalçï¼ä¸æå®å使ç¨é»è®¤é¡¹ç®", example = "vertical") @RequestParam(required = false) String projectId) { if (projectId != null && !projectId.trim().isEmpty()) { return plcTestWriteService.simulateOnlineStatus(onlineState, projectId.trim()); } else { return plcTestWriteService.simulateOnlineStatus(onlineState); } return result; } /** * éç½®PLCç¶æ */ @PostMapping("/reset") public Map<String, Object> resetPlc(@RequestBody(required = false) Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { boolean success; if (params != null && params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); success = plcTestWriteService.resetPlc(dbBlock, beginIndex); } else { success = plcTestWriteService.resetPlc(); } result.put("success", success); result.put("message", success ? "PLCç¶æéç½®æå" : "é置失败"); PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("éç½®ä¸çPLCç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); @ApiOperation("éç½®PLCææç¶æ") public boolean resetPlc( @ApiParam(value = "é¡¹ç®æ è¯ï¼å¦verticalãhorizontalçï¼ä¸æå®å使ç¨é»è®¤é¡¹ç®", example = "vertical") @RequestParam(required = false) String projectId) { if (projectId != null && !projectId.trim().isEmpty()) { return plcTestWriteService.resetPlc(projectId.trim()); } else { return plcTestWriteService.resetPlc(); } return result; } /** * 读åPLCå½åç¶æ */ @GetMapping("/status") public Map<String, Object> getPlcStatus(@RequestParam(required = false) String dbBlock, @RequestParam(required = false, defaultValue = "0") Integer beginIndex) { Map<String, Object> result = new HashMap<>(); try { PlcBaseData status; if (dbBlock != null) { status = plcTestWriteService.readPlcStatus(dbBlock, beginIndex); } else { status = plcTestWriteService.readPlcStatus(); } result.put("success", true); result.put("data", status); result.put("message", "è·åä¸çPLCç¶ææå"); } catch (Exception e) { log.error("读åä¸çPLCç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "è·åç¶æå¤±è´¥: " + e.getMessage()); @ApiOperation("读åPLCå½åç¶æ") public PlcBaseData readPlcStatus( @ApiParam(value = "é¡¹ç®æ è¯ï¼å¦verticalãhorizontalçï¼ä¸æå®å使ç¨é»è®¤é¡¹ç®", example = "vertical") @RequestParam(required = false) String projectId) { if (projectId != null && !projectId.trim().isEmpty()) { return plcTestWriteService.readPlcStatus(projectId.trim()); } else { return plcTestWriteService.readPlcStatus(); } return result; } /** * æ¹éæµè¯ - 模æå®æ´ä»»å¡æµç¨ */ @PostMapping("/batch/test") public Map<String, Object> batchTest(@RequestBody Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); @PostMapping("/current-project") @ApiOperation("设置å½åé¡¹ç®æ è¯") public boolean setCurrentProjectId( @ApiParam(value = "é¡¹ç®æ è¯ï¼å¦verticalãhorizontalç", required = true, example = "vertical") @RequestParam String projectId) { try { String protocolType = (String) params.get("protocolType"); int taskCount = (int) params.getOrDefault("taskCount", 1); log.info("å¼å§æ¹éæµè¯ï¼å议类å: {}, 任塿°é: {}", protocolType, taskCount); // 模æå®æ´ç任塿µç¨ for (int i = 1; i <= taskCount; i++) { log.info("æ§è¡ç¬¬{}个任å¡", i); if ("load".equals(protocolType)) { // æµç¨ plcTestWriteService.simulatePlcRequest(); // åéè¯·æ± // çå¾ MESååº Thread.sleep(1000); plcTestWriteService.simulatePlcReport(); // ä»»å¡å®æ } else if ("raw".equals(protocolType)) { // æµç¨ plcTestWriteService.simulatePlcRequest(); // åéè¯·æ± // çå¾ MESååº Thread.sleep(1000); plcTestWriteService.simulatePlcReport(); // ä»»å¡å®æ } // ä»»å¡é´é if (i < taskCount) { Thread.sleep(2000); } plcTestWriteService.setCurrentProjectId(projectId.trim()); return true; } catch (Exception e) { log.error("设置å½åé¡¹ç®æ è¯å¤±è´¥", e); return false; } } @GetMapping("/current-project") @ApiOperation("è·åå½åé¡¹ç®æ è¯") public String getCurrentProjectId() { return plcTestWriteService.getCurrentProjectId(); } @PostMapping("/cache/clear") @ApiOperation("æ¸ é¤S7Serializerç¼å") public boolean clearSerializerCache( @ApiParam(value = "é¡¹ç®æ è¯ï¼å¦verticalãhorizontalçï¼ä¸æå®åæ¸ é¤ææç¼å", example = "vertical") @RequestParam(required = false) String projectId) { try { if (projectId != null && !projectId.trim().isEmpty()) { plcTestWriteService.clearSerializerCache(projectId.trim()); } else { plcTestWriteService.clearAllSerializerCache(); } result.put("success", true); result.put("message", "æ¹éæµè¯å®æï¼å ±æ§è¡" + taskCount + "个任å¡"); return true; } catch (Exception e) { log.error("æ¹éæµè¯å¼å¸¸", e); result.put("success", false); result.put("message", "æ¹éæµè¯å¤±è´¥: " + e.getMessage()); log.error("æ¸ é¤S7Serializerç¼å失败", e); return false; } return result; } /** * 设置DBåå°å */ @PostMapping("/dbBlock") public Map<String, Object> setDbBlock(@RequestBody Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { String dbBlock = (String) params.get("dbBlock"); plcTestWriteService.setCurrentDbBlock(dbBlock); result.put("success", true); result.put("message", "DBåå°å设置æå: " + dbBlock); } catch (Exception e) { log.error("设置DBåå°åå¼å¸¸", e); result.put("success", false); result.put("message", "设置DBåå°å失败: " + e.getMessage()); } return result; } /** * è·åå½åDBåå°å */ @GetMapping("/dbBlock") public Map<String, Object> getDbBlock() { Map<String, Object> result = new HashMap<>(); try { String dbBlock = plcTestWriteService.getCurrentDbBlock(); result.put("success", true); result.put("data", dbBlock); result.put("message", "è·åDBåå°åæå"); } catch (Exception e) { log.error("è·åDBåå°åå¼å¸¸", e); result.put("success", false); result.put("message", "è·åDBåå°å失败: " + e.getMessage()); } return result; } /** * å¯ç¨èªå¨æµè¯æ¨¡å¼ */ @PostMapping("/auto/enable") public Map<String, Object> enableAutoTest() { Map<String, Object> result = new HashMap<>(); try { plcAutoTestService.enableAutoTest(); result.put("success", true); result.put("message", "èªå¨æµè¯æ¨¡å¼å·²å¯ç¨"); } catch (Exception e) { log.error("å¯ç¨èªå¨æµè¯æ¨¡å¼å¼å¸¸", e); result.put("success", false); result.put("message", "å¯ç¨èªå¨æµè¯æ¨¡å¼å¤±è´¥: " + e.getMessage()); } return result; } /** * ç¦ç¨èªå¨æµè¯æ¨¡å¼ */ @PostMapping("/auto/disable") public Map<String, Object> disableAutoTest() { Map<String, Object> result = new HashMap<>(); try { plcAutoTestService.disableAutoTest(); result.put("success", true); result.put("message", "èªå¨æµè¯æ¨¡å¼å·²ç¦ç¨"); } catch (Exception e) { log.error("ç¦ç¨èªå¨æµè¯æ¨¡å¼å¼å¸¸", e); result.put("success", false); result.put("message", "ç¦ç¨èªå¨æµè¯æ¨¡å¼å¤±è´¥: " + e.getMessage()); } return result; } /** * è·åèªå¨æµè¯æ¨¡å¼ç¶æ */ @GetMapping("/auto/status") public Map<String, Object> getAutoTestStatus() { Map<String, Object> result = new HashMap<>(); try { boolean isEnabled = plcAutoTestService.isAutoTestEnabled(); result.put("success", true); result.put("data", isEnabled); result.put("message", "è·åèªå¨æµè¯æ¨¡å¼ç¶ææå"); } catch (Exception e) { log.error("è·åèªå¨æµè¯æ¨¡å¼ç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "è·åèªå¨æµè¯æ¨¡å¼ç¶æå¤±è´¥: " + e.getMessage()); } return result; } } mes-processes/mes-plcSend/src/main/java/com/mes/controller/PlcTestWriteLegacyController.java
New file @@ -0,0 +1,352 @@ package com.mes.controller; import com.mes.entity.PlcBaseData; import com.mes.service.PlcAutoTestService; import com.mes.service.PlcTestWriteService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; /** * PLCæµè¯åå ¥æ§å¶å¨ï¼å ¼å®¹æ§APIï¼ * 为å端æä¾æ¨¡æPLCåå ¥æä½çæ¥å£ * * @author huang * @date 2025/10/29 */ @Slf4j @RestController @RequestMapping("/plcTest/write") public class PlcTestWriteLegacyController { @Resource private PlcTestWriteService plcTestWriteService; @Resource private PlcAutoTestService plcAutoTestService; /** * 模æPLCåé请æ±å */ @PostMapping("/request") public Map<String, Object> simulateRequest(@RequestBody(required = false) Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { boolean success; if (params != null && params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); // 使ç¨é»è®¤é¡¹ç®ï¼ä½è®°å½è¦å log.warn("ä½¿ç¨æ§APIåæ°dbBlock={}, beginIndex={}ï¼å»ºè®®ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼", dbBlock, beginIndex); success = plcTestWriteService.simulatePlcRequest(); } else { success = plcTestWriteService.simulatePlcRequest(); } result.put("success", success); result.put("message", success ? "PLC请æ±ååéæå" : "åé失败"); // è¿åå½åç¶æ PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("模æPLC请æ±å¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); } return result; } /** * 模æPLCä»»å¡å®ææ±æ¥ */ @PostMapping("/report") public Map<String, Object> simulateReport(@RequestBody(required = false) Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { boolean success; if (params != null && params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); // 使ç¨é»è®¤é¡¹ç®ï¼ä½è®°å½è¦å log.warn("ä½¿ç¨æ§APIåæ°dbBlock={}, beginIndex={}ï¼å»ºè®®ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼", dbBlock, beginIndex); success = plcTestWriteService.simulatePlcReport(); } else { success = plcTestWriteService.simulatePlcReport(); } result.put("success", success); result.put("message", success ? "PLC任塿±æ¥æå" : "æ±æ¥å¤±è´¥"); PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("模æä¸çPLCæ±æ¥å¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); } return result; } /** * 模æPLCèæºç¶æ */ @PostMapping("/online") public Map<String, Object> simulateOnline(@RequestBody Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { int onlineState = (int) params.getOrDefault("onlineState", 1); boolean success; if (params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); // 使ç¨é»è®¤é¡¹ç®ï¼ä½è®°å½è¦å log.warn("ä½¿ç¨æ§APIåæ°dbBlock={}, beginIndex={}ï¼å»ºè®®ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼", dbBlock, beginIndex); success = plcTestWriteService.simulateOnlineStatus(onlineState); } else { success = plcTestWriteService.simulateOnlineStatus(onlineState); } result.put("success", success); result.put("message", success ? "PLCèæºç¶æè®¾ç½®æå: " + onlineState : "设置失败"); PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("模æPLCèæºç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); } return result; } /** * éç½®PLCç¶æ */ @PostMapping("/reset") public Map<String, Object> resetPlc(@RequestBody(required = false) Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { boolean success; if (params != null && params.containsKey("dbBlock")) { String dbBlock = (String) params.get("dbBlock"); int beginIndex = (int) params.getOrDefault("beginIndex", 0); // 使ç¨é»è®¤é¡¹ç®ï¼ä½è®°å½è¦å log.warn("ä½¿ç¨æ§APIåæ°dbBlock={}, beginIndex={}ï¼å»ºè®®ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼", dbBlock, beginIndex); success = plcTestWriteService.resetPlc(); } else { success = plcTestWriteService.resetPlc(); } result.put("success", success); result.put("message", success ? "PLCç¶æéç½®æå" : "é置失败"); PlcBaseData status = plcTestWriteService.readPlcStatus(); result.put("currentStatus", status); } catch (Exception e) { log.error("éç½®ä¸çPLCç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "æä½å¤±è´¥: " + e.getMessage()); } return result; } /** * 读åPLCå½åç¶æ */ @GetMapping("/status") public Map<String, Object> getPlcStatus(@RequestParam(required = false) String dbBlock, @RequestParam(required = false, defaultValue = "0") Integer beginIndex) { Map<String, Object> result = new HashMap<>(); try { PlcBaseData status; if (dbBlock != null) { // 使ç¨é»è®¤é¡¹ç®ï¼ä½è®°å½è¦å log.warn("ä½¿ç¨æ§APIåæ°dbBlock={}, beginIndex={}ï¼å»ºè®®ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼", dbBlock, beginIndex); status = plcTestWriteService.readPlcStatus(); } else { status = plcTestWriteService.readPlcStatus(); } result.put("success", true); result.put("data", status); result.put("message", "è·åä¸çPLCç¶ææå"); } catch (Exception e) { log.error("读åä¸çPLCç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "è·åç¶æå¤±è´¥: " + e.getMessage()); } return result; } /** * æ¹éæµè¯ - 模æå®æ´ä»»å¡æµç¨ */ @PostMapping("/batch/test") public Map<String, Object> batchTest(@RequestBody Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { String protocolType = (String) params.get("protocolType"); int taskCount = (int) params.getOrDefault("taskCount", 1); log.info("å¼å§æ¹éæµè¯ï¼å议类å: {}, 任塿°é: {}", protocolType, taskCount); // 模æå®æ´ç任塿µç¨ for (int i = 1; i <= taskCount; i++) { log.info("æ§è¡ç¬¬{}个任å¡", i); if ("load".equals(protocolType)) { // æµç¨ plcTestWriteService.simulatePlcRequest(); // åéè¯·æ± // çå¾ MESååº Thread.sleep(1000); plcTestWriteService.simulatePlcReport(); // ä»»å¡å®æ } else if ("raw".equals(protocolType)) { // æµç¨ plcTestWriteService.simulatePlcRequest(); // åéè¯·æ± // çå¾ MESååº Thread.sleep(1000); plcTestWriteService.simulatePlcReport(); // ä»»å¡å®æ } // ä»»å¡é´é if (i < taskCount) { Thread.sleep(2000); } } result.put("success", true); result.put("message", "æ¹éæµè¯å®æï¼å ±æ§è¡" + taskCount + "个任å¡"); } catch (Exception e) { log.error("æ¹éæµè¯å¼å¸¸", e); result.put("success", false); result.put("message", "æ¹éæµè¯å¤±è´¥: " + e.getMessage()); } return result; } /** * 设置DBåå°åï¼å·²åºå¼ï¼ä» ä¿çå ¼å®¹æ§ï¼ */ @PostMapping("/dbBlock") public Map<String, Object> setDbBlock(@RequestBody Map<String, Object> params) { Map<String, Object> result = new HashMap<>(); try { String dbBlock = (String) params.get("dbBlock"); log.warn("设置DBåå°ååè½å·²åºå¼ï¼è¯·ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼ç®¡çPLCé ç½®"); result.put("success", false); result.put("message", "设置DBåå°ååè½å·²åºå¼ï¼è¯·ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼ç®¡çPLCé ç½®"); } catch (Exception e) { log.error("设置DBåå°åå¼å¸¸", e); result.put("success", false); result.put("message", "设置DBåå°å失败: " + e.getMessage()); } return result; } /** * è·åå½åDBåå°åï¼å·²åºå¼ï¼ä» ä¿çå ¼å®¹æ§ï¼ */ @GetMapping("/dbBlock") public Map<String, Object> getDbBlock() { Map<String, Object> result = new HashMap<>(); try { log.warn("è·åDBåå°ååè½å·²åºå¼ï¼è¯·ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼ç®¡çPLCé ç½®"); result.put("success", false); result.put("message", "è·åDBåå°ååè½å·²åºå¼ï¼è¯·ä½¿ç¨æ°APIåºäºé¡¹ç®IDçæ¹å¼ç®¡çPLCé ç½®"); } catch (Exception e) { log.error("è·åDBåå°åå¼å¸¸", e); result.put("success", false); result.put("message", "è·åDBåå°å失败: " + e.getMessage()); } return result; } /** * å¯ç¨èªå¨æµè¯æ¨¡å¼ */ @PostMapping("/auto/enable") public Map<String, Object> enableAutoTest() { Map<String, Object> result = new HashMap<>(); try { plcAutoTestService.enableAutoTest(); result.put("success", true); result.put("message", "èªå¨æµè¯æ¨¡å¼å·²å¯ç¨"); } catch (Exception e) { log.error("å¯ç¨èªå¨æµè¯æ¨¡å¼å¼å¸¸", e); result.put("success", false); result.put("message", "å¯ç¨èªå¨æµè¯æ¨¡å¼å¤±è´¥: " + e.getMessage()); } return result; } /** * ç¦ç¨èªå¨æµè¯æ¨¡å¼ */ @PostMapping("/auto/disable") public Map<String, Object> disableAutoTest() { Map<String, Object> result = new HashMap<>(); try { plcAutoTestService.disableAutoTest(); result.put("success", true); result.put("message", "èªå¨æµè¯æ¨¡å¼å·²ç¦ç¨"); } catch (Exception e) { log.error("ç¦ç¨èªå¨æµè¯æ¨¡å¼å¼å¸¸", e); result.put("success", false); result.put("message", "ç¦ç¨èªå¨æµè¯æ¨¡å¼å¤±è´¥: " + e.getMessage()); } return result; } /** * è·åèªå¨æµè¯æ¨¡å¼ç¶æ */ @GetMapping("/auto/status") public Map<String, Object> getAutoTestStatus() { Map<String, Object> result = new HashMap<>(); try { boolean isEnabled = plcAutoTestService.isAutoTestEnabled(); result.put("success", true); result.put("data", isEnabled); result.put("message", "è·åèªå¨æµè¯æ¨¡å¼ç¶ææå"); } catch (Exception e) { log.error("è·åèªå¨æµè¯æ¨¡å¼ç¶æå¼å¸¸", e); result.put("success", false); result.put("message", "è·åèªå¨æµè¯æ¨¡å¼ç¶æå¤±è´¥: " + e.getMessage()); } return result; } } mes-processes/mes-plcSend/src/main/java/com/mes/entity/PlcAddress.java
@@ -11,12 +11,12 @@ /** * PLCå°åæ å°é 置表 * * @author zhoush * @author huang * @date 2025/10/30 */ @Data @TableName("plc_address_mapping") public class PlcAddressMapping implements Serializable { public class PlcAddress implements Serializable { private static final long serialVersionUID = 1L; mes-processes/mes-plcSend/src/main/java/com/mes/entity/PlcBaseData.java
@@ -3,14 +3,12 @@ import com.github.xingshuangs.iot.common.enums.EDataType; import com.github.xingshuangs.iot.protocol.s7.serializer.S7Variable; import lombok.Data; import org.springframework.stereotype.Component; /** * @author huang * @since 2025/10/30 */ @Data @Component public class PlcBaseData { /** * plc mes-processes/mes-plcSend/src/main/java/com/mes/job/config/S7PlcSendConfig.java
File was deleted mes-processes/mes-plcSend/src/main/java/com/mes/mapper/PlcAddressMapper.java
@@ -1,16 +1,16 @@ package com.mes.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.mes.entity.PlcAddressMapping; import com.mes.entity.PlcAddress; import org.apache.ibatis.annotations.Mapper; /** * PLCå°åæ å°é ç½®Mapper * * @author zhoush * @author huang * @date 2025/10/30 */ @Mapper public interface PlcAddressMappingMapper extends BaseMapper<PlcAddressMapping> { public interface PlcAddressMapper extends BaseMapper<PlcAddress> { } mes-processes/mes-plcSend/src/main/java/com/mes/service/PlcAddressService.java
@@ -1,411 +1,100 @@ package com.mes.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType; import com.github.xingshuangs.iot.protocol.s7.service.S7PLC; import com.mes.config.PlcAddressMappingConfig; import com.mes.entity.PlcAddressMapping; import com.mes.mapper.PlcAddressMappingMapper; import com.mes.s7.enhanced.EnhancedS7Serializer; import lombok.extern.slf4j.Slf4j; import org.apache.catalina.core.ApplicationContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.mes.entity.PlcAddress; import java.util.HashMap; import java.util.List; import java.util.Map; /** * PLCå°åæ å°æå¡ * 管çPLCå°åæ å°é ç½®ï¼æ¯æä»æ°æ®åºåé ç½®æä»¶å è½½ * * @author zhoush * @date 2025/10/29 * PLCå°åæ 尿塿¥å£ * å®ä¹PLCå°åæ å°é 置管ççæ ¸å¿æ¹æ³ * * @author huang * @date 2025/10/30 */ @Slf4j @Service public class PlcAddressMappingService { @Autowired private PlcAddressMappingMapper plcAddressMappingMapper; @Autowired private PlcAddressMappingConfig plcAddressMappingConfig; // JSONè§£æå¨ private final ObjectMapper objectMapper = new ObjectMapper(); public interface PlcAddressService { /** * è·åå å«å°åæ å°ç项ç®é ç½® * åå¹¶æ°æ®åºåé ç½®æä»¶ä¸çæ å°ä¿¡æ¯ * è·åå å«å°åæ å°ç项ç®é ç½®ï¼åå¹¶æ°æ®åºä¸é ç½®æä»¶ï¼ * @param projectId 项ç®ID * @return åå¹¶åç项ç®é ç½® */ public PlcAddressMappingConfig.ProjectPlcConfig getProjectConfigWithMapping(String projectId) { try { // 1. è·åæ°æ®åºä¸çé ç½® PlcAddressMapping mapping = getMappingByProjectId(projectId); PlcAddressMappingConfig.ProjectPlcConfig projectConfig = null; if (mapping != null) { // 仿°æ®åºå®ä½è½¬æ¢ä¸ºé¡¹ç®é 置对象 projectConfig = convertToProjectConfig(mapping); } else { // æ°æ®åºä¸æ²¡æé ç½®ï¼å°è¯ä»é ç½®æä»¶è·å if (fileConfig != null && fileConfig.getProjects().containsKey(projectId)) { projectConfig = fileConfig.getProjects().get(projectId); } else { // å建é»è®¤é ç½® projectConfig = new PlcAddressMappingConfig.ProjectPlcConfig(); projectConfig.setDbArea(fileConfig != null ? fileConfig.getDefaultDbArea() : "DB1"); projectConfig.setBeginIndex(fileConfig != null ? fileConfig.getDefaultBeginIndex() : 0); projectConfig.setAddressMapping(new HashMap<>()); } } // 2. 妿é ç½®æä»¶ä¸æé¢å¤çæ å°ä¿¡æ¯ï¼è¿è¡åå¹¶ if (fileConfig != null && fileConfig.getProjects() != null && fileConfig.getProjects().containsKey(projectId)) { PlcAddressMappingConfig.ProjectPlcConfig fileProjectConfig = fileConfig.getProjects().get(projectId); // åå¹¶å°åæ å° if (fileProjectConfig.getAddressMapping() != null) { if (projectConfig.getAddressMapping() == null) { projectConfig.setAddressMapping(new HashMap<>()); } // æä»¶é ç½®ä½ä¸ºåºç¡ï¼æ°æ®åºé ç½®ä½ä¸ºè¦çï¼ä¼å 级æ´é«ï¼ Map<String, Integer> mergedMapping = new HashMap<>(fileProjectConfig.getAddressMapping()); if (projectConfig.getAddressMapping() != null) { mergedMapping.putAll(projectConfig.getAddressMapping()); } projectConfig.setAddressMapping(mergedMapping); } // 妿项ç®é ç½®ä¸ç¼ºå°æäºå±æ§ï¼ä»æä»¶é ç½®ä¸è¡¥å if (projectConfig.getDbArea() == null || projectConfig.getDbArea().trim().isEmpty()) { projectConfig.setDbArea(fileProjectConfig.getDbArea()); } if (projectConfig.getPlcIp() == null || projectConfig.getPlcIp().trim().isEmpty()) { projectConfig.setPlcIp(fileProjectConfig.getPlcIp()); } if (projectConfig.getPlcType() == null || projectConfig.getPlcType().trim().isEmpty()) { projectConfig.setPlcType(fileProjectConfig.getPlcType()); } } return projectConfig; } catch (Exception e) { log.error("è·å项ç®é 置失败ï¼é¡¹ç®ID: {}", projectId, e); // è¿åé»è®¤é ç½® PlcAddressMappingConfig.ProjectPlcConfig defaultConfig = new PlcAddressMappingConfig.ProjectPlcConfig(); defaultConfig.setDbArea(fileConfig != null ? fileConfig.getDefaultDbArea() : "DB1"); defaultConfig.setBeginIndex(fileConfig != null ? fileConfig.getDefaultBeginIndex() : 0); defaultConfig.setAddressMapping(new HashMap<>()); return defaultConfig; } } PlcAddress getProjectConfigWithMapping(String projectId); /** * 仿°æ®åºè·å项ç®é ç½® * @param projectId 项ç®ID * @return 项ç®é ç½®ï¼PlcAddresså®ä½ï¼ï¼ä¸åå¨åè¿ånull */ public PlcAddressMappingConfig.ProjectPlcConfig getProjectConfig(String projectId) { try { // ä¼å 仿°æ®åºè·åé ç½® PlcAddressMapping mapping = plcAddressMappingMapper.selectOne( new LambdaQueryWrapper<PlcAddressMapping>() .eq(PlcAddressMapping::getProjectId, projectId) ); if (mapping != null) { return convertToProjectConfig(mapping); } // å¦ææ°æ®åºä¸æ²¡æï¼åä»é ç½®æä»¶è·å if (fileConfig != null && fileConfig.getProjects() != null && fileConfig.getProjects().containsKey(projectId)) { return fileConfig.getProjects().get(projectId); } // 妿齿²¡æï¼è¿ånull return null; } catch (Exception e) { log.error("è·å项ç®é 置失败ï¼é¡¹ç®ID: {}", projectId, e); return null; } } PlcAddress getProjectConfig(String projectId); /** * è·åæææ å°é ç½® * åå¹¶æ°æ®åºåé ç½®æä»¶ä¸çæ å°ä¿¡æ¯ * è·åæææ å°é ç½®ï¼åå¹¶åçaddressMappingä¼ååå®ä½çJSONåæ®µï¼ * @return æææ å°é ç½®å表 */ public List<PlcAddressMapping> getAllMappings() { try { List<PlcAddressMapping> mappings = plcAddressMappingMapper.selectList(null); // å¤çæ¯ä¸ªæ å°é ç½® for (PlcAddressMapping mapping : mappings) { // è·åé¡¹ç®æ è¯ String projectId = mapping.getProjectId(); // è·ååå¹¶åç项ç®é ç½®ï¼å 嫿°æ®åºåé ç½®æä»¶çæ å°ä¿¡æ¯ï¼ PlcAddressMappingConfig.ProjectPlcConfig projectConfig = getProjectConfigWithMapping(projectId); // å°åå¹¶åçæ å°ä¿¡æ¯è½¬æ¢ä¸ºJSONå符串 if (projectConfig.getAddressMapping() != null && !projectConfig.getAddressMapping().isEmpty()) { try { String mergedMappingJson = objectMapper.writeValueAsString(projectConfig.getAddressMapping()); mapping.setAddressMapping(mergedMappingJson); // addressMapping屿§å·²ç»æ å°å°æ°æ®åºçaddress_mapping_jsonåæ®µ } catch (Exception e) { log.warn("转æ¢åå¹¶åçæ å°ä¿¡æ¯å¤±è´¥ï¼é¡¹ç®ID: {}", projectId, e); // ä¿æåæçaddressMappingå¼ } } } return mappings; } catch (Exception e) { log.error("è·åææPLCå°åæ å°é 置失败", e); throw new RuntimeException("è·åææPLCå°åæ å°é 置失败", e); } } List<PlcAddress> getAllMappings(); /** * å页è·åPLCå°åæ å°é ç½® * @param page 页ç * @param size æ¯é¡µå¤§å° * @param projectId 项ç®IDï¼å¯éï¼ * @param plcIp PLC IPï¼å¯éï¼ * @return åé¡µç»æ */ public IPage<PlcAddressMapping> getMappingsByPage(int page, int size, String projectId, String plcIp) { try { Page<PlcAddressMapping> pageParam = new Page<>(page, size); LambdaQueryWrapper<PlcAddressMapping> queryWrapper = new LambdaQueryWrapper<>(); if (projectId != null && !projectId.trim().isEmpty()) { queryWrapper.like(PlcAddressMapping::getProjectId, projectId); } if (plcIp != null && !plcIp.trim().isEmpty()) { queryWrapper.like(PlcAddressMapping::getPlcIp, plcIp); } return plcAddressMappingMapper.selectPage(pageParam, queryWrapper); } catch (Exception e) { log.error("å页è·åPLCå°åæ å°é 置失败", e); throw new RuntimeException("å页è·åPLCå°åæ å°é 置失败", e); } } IPage<PlcAddress> getMappingsByPage(int page, int size, String projectId, String plcIp); /** * æ ¹æ®IDè·åPLCå°åæ å°é ç½® * @param id é ç½®ID * @return PLCå°åæ å°é ç½® */ public PlcAddressMapping getMappingById(Long id) { try { return plcAddressMappingMapper.selectById(id); } catch (Exception e) { log.error("æ ¹æ®IDè·åPLCå°åæ å°é 置失败ï¼ID: {}", id, e); throw new RuntimeException("æ ¹æ®IDè·åPLCå°åæ å°é 置失败", e); } } PlcAddress getMappingById(Long id); /** * æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é ç½® * æ ¹æ®é¡¹ç®IDè·åPLCå°åæ å°é ç½® * @param projectId 项ç®ID * @return PLCå°åæ å°é ç½® */ public PlcAddressMapping getMappingByProjectId(String projectId) { try { return plcAddressMappingMapper.selectOne( new LambdaQueryWrapper<PlcAddressMapping>() .eq(PlcAddressMapping::getProjectId, projectId) ); } catch (Exception e) { log.error("æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é 置失败ï¼é¡¹ç®ID: {}", projectId, e); throw new RuntimeException("æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é 置失败", e); } } PlcAddress getMappingByProjectId(String projectId); /** * ä¿åPLCå°åæ å°é ç½® * å建PLCå°åæ å°é ç½® * @param mapping æ å°é ç½® * @return å建åçé ç½® */ public PlcAddressMapping saveMapping(PlcAddressMapping mapping) { try { // æ£æ¥é¡¹ç®IDæ¯å¦å·²åå¨ PlcAddressMapping existing = plcAddressMappingMapper.selectOne( new LambdaQueryWrapper<PlcAddressMapping>() .eq(PlcAddressMapping::getProjectId, mapping.getProjectId()) ); if (existing != null) { throw new RuntimeException("é¡¹ç®æ è¯ " + mapping.getProjectId() + " å·²åå¨"); } plcAddressMappingMapper.insert(mapping); return mapping; } catch (Exception e) { log.error("ä¿åPLCå°åæ å°é 置失败", e); throw new RuntimeException("ä¿åPLCå°åæ å°é 置失败", e); } } PlcAddress saveMapping(PlcAddress mapping); /** * æ´æ°PLCå°åæ å°é ç½® * @param mapping æ å°é ç½® * @return æ´æ°åçé ç½®ï¼æªæ¾å°è¿ånull */ public PlcAddressMapping updateMapping(PlcAddressMapping mapping) { try { // æ£æ¥IDæ¯å¦åå¨ PlcAddressMapping existing = plcAddressMappingMapper.selectById(mapping.getId()); if (existing == null) { return null; } // 妿项ç®IDæååï¼æ£æ¥æ°é¡¹ç®IDæ¯å¦å·²åå¨ if (!existing.getProjectId().equals(mapping.getProjectId())) { PlcAddressMapping duplicate = plcAddressMappingMapper.selectOne( new LambdaQueryWrapper<PlcAddressMapping>() .eq(PlcAddressMapping::getProjectId, mapping.getProjectId()) ); if (duplicate != null) { throw new RuntimeException("é¡¹ç®æ è¯ " + mapping.getProjectId() + " å·²åå¨"); } } plcAddressMappingMapper.updateById(mapping); return mapping; } catch (Exception e) { log.error("æ´æ°PLCå°åæ å°é 置失败", e); throw new RuntimeException("æ´æ°PLCå°åæ å°é 置失败", e); } } PlcAddress updateMapping(PlcAddress mapping); /** * å é¤PLCå°åæ å°é ç½® * @param id é ç½®ID * @return æ¯å¦æå */ public boolean deleteMapping(Long id) { try { int result = plcAddressMappingMapper.deleteById(id); return result > 0; } catch (Exception e) { log.error("å é¤PLCå°åæ å°é 置失败ï¼ID: {}", id, e); throw new RuntimeException("å é¤PLCå°åæ å°é 置失败", e); } } boolean deleteMapping(Long id); /** * æ¹éå é¤PLCå°åæ å°é ç½® * @param ids é ç½®IDå表 * @return å 餿°é */ public int deleteMappings(List<Long> ids) { try { if (ids == null || ids.isEmpty()) { return 0; } return plcAddressMappingMapper.deleteBatchIds(ids); } catch (Exception e) { log.error("æ¹éå é¤PLCå°åæ å°é 置失败ï¼IDå表: {}", ids, e); throw new RuntimeException("æ¹éå é¤PLCå°åæ å°é 置失败", e); } } int deleteMappings(List<Long> ids); /** * æµè¯PLCè¿æ¥ * @param mapping æ å°é ç½® * @return æ¯å¦æå */ public boolean testConnection(PlcAddressMapping mapping) { try { // è§£æPLCç±»å EPlcType plcType = EPlcType.S1200; // é»è®¤å¼ if (mapping.getPlcType() != null && !mapping.getPlcType().trim().isEmpty()) { try { plcType = EPlcType.valueOf(mapping.getPlcType()); } catch (IllegalArgumentException e) { log.warn("æªç¥çPLCç±»å: {}, 使ç¨é»è®¤ç±»å S1200", mapping.getPlcType()); } } // å建S7PLCå®ä¾ String plcIp = mapping.getPlcIp() != null ? mapping.getPlcIp() : "192.168.10.21"; S7PLC s7Plc = new S7PLC(plcType, plcIp); // å建EnhancedS7Serializerå®ä¾ EnhancedS7Serializer serializer = EnhancedS7Serializer.newInstance(s7Plc); // å°è¯è¯»åä¸ä¸ªç®åçæ°æ®æ¥æµè¯è¿æ¥ String dbArea = mapping.getDbArea() != null ? mapping.getDbArea() : "DB1"; int beginIndex = mapping.getBeginIndex(); // è¿éæä»¬åªæµè¯è¿æ¥ï¼ä¸è¯»åå®é æ°æ® // å®é 项ç®ä¸å¯è½éè¦æ ¹æ®å ·ä½éæ±è°æ´ return true; } catch (Exception e) { log.error("PLCè¿æ¥æµè¯å¤±è´¥", e); return false; } } boolean testConnection(PlcAddress mapping); /** * éæ°å è½½é ç½®æä»¶ä¸çæ å° * éæ°å è½½é ç½®æä»¶ä¸çæ å°é ç½® */ public void reloadConfigMappings() { try { // å ³é®ä¿®æ¹3ï¼éè¿Springä¸ä¸æå·æ°é ç½®ï¼éç¨äºSpring Boot 2.xï¼ ApplicationContext applicationContext = SpringContextHolder.getApplicationContext(); if (applicationContext != null) { // è·åé ç½®ç»å®çBeanDefinition ConfigurableApplicationContext configurableContext = (ConfigurableApplicationContext) applicationContext; ConfigurableEnvironment environment = configurableContext.getEnvironment(); // å·æ°é ç½®æºï¼éæ°è¯»åé ç½®æä»¶ï¼ for (PropertySource<?> source : environment.getPropertySources()) { if (source instanceof ResourcePropertySource) { ResourcePropertySource resourceSource = (ResourcePropertySource) source; // éæ°å è½½é ç½®æä»¶èµæº resourceSource.refresh(); } } // éæ°ç»å®é ç½®å°PlcAddressMappingConfig Binder.get(environment) .bind("plc.address.mapping", PlcAddressMappingConfig.class) .ifBound(config -> { // æ´æ°æ³¨å ¥çé ç½®å®ä¾ï¼å @ConfigurationPropertiesé»è®¤æ¯åä¾ï¼éæå¨æ´æ°å±æ§ï¼ this.plcAddressMappingConfig.setDefaultDbArea(config.getDefaultDbArea()); this.plcAddressMappingConfig.setDefaultBeginIndex(config.getDefaultBeginIndex()); this.plcAddressMappingConfig.setProjects(config.getProjects()); }); log.info("æåéæ°å è½½é ç½®æä»¶ä¸çPLCå°åæ å°"); } } catch (Exception e) { log.error("éæ°å è½½é ç½®æä»¶ä¸çPLCå°åæ å°å¤±è´¥", e); } } /** * å°æ°æ®åºå®ä½è½¬æ¢ä¸ºé¡¹ç®é 置对象 */ private PlcAddressMappingConfig.ProjectPlcConfig convertToProjectConfig(PlcAddressMapping mapping) { PlcAddressMappingConfig.ProjectPlcConfig config = new PlcAddressMappingConfig.ProjectPlcConfig(); config.setDbArea(mapping.getDbArea()); config.setBeginIndex(mapping.getBeginIndex()); config.setPlcIp(mapping.getPlcIp()); config.setPlcType(mapping.getPlcType()); // è§£æå°åæ å°JSON if (mapping.getAddressMapping() != null && !mapping.getAddressMapping().trim().isEmpty()) { try { // 使ç¨Jacksonè§£æJSONå符串为Map<String, Integer> Map<String, Integer> addressMap = objectMapper.readValue( mapping.getAddressMapping(), new TypeReference<Map<String, Integer>>() {} ); config.setAddressMapping(addressMap); } catch (Exception e) { log.warn("è§£æå°åæ å°JSON失败: {}", mapping.getAddressMapping(), e); // å¦æè§£æå¤±è´¥ï¼å建ä¸ä¸ªç©ºçæ å° config.setAddressMapping(new HashMap<>()); } } else { // å¦ææ²¡æå°åæ å°ï¼å建ä¸ä¸ªç©ºçæ å° config.setAddressMapping(new HashMap<>()); } return config; } void reloadConfigMappings(); } mes-processes/mes-plcSend/src/main/java/com/mes/service/PlcAutoTestService.java
@@ -1,6 +1,5 @@ package com.mes.service; import com.mes.s7.enhanced.EnhancedS7Serializer; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; @@ -12,15 +11,12 @@ * PLCèªå¨æµè¯æå¡ * 宿¶æ¨¡æPLCè¡ä¸ºï¼åPLCåå ¥æµè¯æ°æ®ï¼ç¨äºèªå¨æµè¯MESç¨åº * * @author zhoush * @author huang * @date 2025/10/30 */ @Slf4j @Service public class PlcAutoTestService { @Resource private EnhancedS7Serializer s7Serializer; @Resource private PlcTestWriteService plcTestWriteService; @@ -32,9 +28,6 @@ // èªå¨æµè¯é´éï¼æ¯«ç§ï¼ @Value("${plc.auto.test.interval:5000}") private long autoTestInterval; private static final int ON = 1; private static final int OFF = 0; /** * 宿¶èªå¨æµè¯ä»»å¡ mes-processes/mes-plcSend/src/main/java/com/mes/service/PlcTestWriteService.java
@@ -2,8 +2,8 @@ import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType; import com.github.xingshuangs.iot.protocol.s7.service.S7PLC; import com.mes.config.PlcAddressMappingConfig; import com.mes.entity.PlcBaseData; import com.mes.entity.PlcAddress; import com.mes.s7.enhanced.EnhancedS7Serializer; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -16,7 +16,7 @@ * PLCæµè¯åå ¥æå¡ * 模æPLCè¡ä¸ºï¼åPLCåå ¥æµè¯æ°æ®ï¼ç¨äºæµè¯MESç¨åº * * @author zhoush * @author huang * @date 2025/10/29 */ @Slf4j @@ -24,13 +24,13 @@ public class PlcTestWriteService { @Resource private PlcAddressMappingService plcAddressMappingService; private PlcAddressService plcAddressService; private static final int ON = 1; private static final int OFF = 0; // å½å使ç¨çé¡¹ç®æ è¯ private String currentProjectId = "shuttle"; private String currentProjectId = "vertical"; // ç¼åä¸å项ç®çS7Serializerå®ä¾ private final ConcurrentMap<String, EnhancedS7Serializer> serializerCache = new ConcurrentHashMap<>(); @@ -47,8 +47,8 @@ */ public boolean simulatePlcRequest(String projectId) { try { // è·å项ç®é ç½® PlcAddressMappingConfig.ProjectPlcConfig config = plcAddressMappingService.getProjectConfig(projectId); // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); @@ -88,8 +88,8 @@ */ public boolean simulatePlcReport(String projectId) { try { // è·å项ç®é ç½® PlcAddressMappingConfig.ProjectPlcConfig config = plcAddressMappingService.getProjectConfig(projectId); // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); @@ -127,8 +127,8 @@ */ public boolean simulateOnlineStatus(int onlineState, String projectId) { try { // è·å项ç®é ç½® PlcAddressMappingConfig.ProjectPlcConfig config = plcAddressMappingService.getProjectConfig(projectId); // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); @@ -161,8 +161,8 @@ */ public boolean resetPlc(String projectId) { try { // è·å项ç®é ç½® PlcAddressMappingConfig.ProjectPlcConfig config = plcAddressMappingService.getProjectConfig(projectId); // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); @@ -203,8 +203,8 @@ */ public PlcBaseData readPlcStatus(String projectId) { try { // è·å项ç®é ç½® PlcAddressMappingConfig.ProjectPlcConfig config = plcAddressMappingService.getProjectConfig(projectId); // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); @@ -238,11 +238,11 @@ * @param config 项ç®é ç½® * @return S7Serializerå®ä¾ */ private EnhancedS7Serializer getSerializerForProject(String projectId, PlcAddressMappingConfig.ProjectPlcConfig config) { private EnhancedS7Serializer getSerializerForProject(String projectId, PlcAddress config) { return serializerCache.computeIfAbsent(projectId, id -> { // è§£æPLCç±»å EPlcType plcType = EPlcType.S1200; // é»è®¤å¼ if (config.getPlcType() != null) { if (config != null && config.getPlcType() != null) { try { plcType = EPlcType.valueOf(config.getPlcType()); } catch (IllegalArgumentException e) { @@ -251,7 +251,7 @@ } // å建S7PLCå®ä¾ String plcIp = config.getPlcIp() != null ? config.getPlcIp() : "192.168.10.21"; String plcIp = (config != null && config.getPlcIp() != null) ? config.getPlcIp() : "192.168.10.21"; S7PLC s7Plc = new S7PLC(plcType, plcIp); // å建并è¿åEnhancedS7Serializerå®ä¾ mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcAddressServiceImpl.java
New file @@ -0,0 +1,270 @@ package com.mes.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType; import com.github.xingshuangs.iot.protocol.s7.service.S7PLC; import com.mes.entity.PlcAddress; import com.mes.mapper.PlcAddressMapper; import com.mes.s7.enhanced.EnhancedS7Serializer; import com.mes.service.PlcAddressService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * PLCå°åæ å°æå¡å®ç°ç±» * 管çPLCå°åæ å°é ç½®ï¼æ¯æä»æ°æ®åºåé ç½®æä»¶å è½½ * * @author huang * @date 2025/10/30 */ @Slf4j @Service public class PlcAddressServiceImpl implements PlcAddressService { @Autowired private PlcAddressMapper plcAddressMapper; // JSONè§£æå¨ private final ObjectMapper objectMapper = new ObjectMapper(); /** * è·åå å«å°åæ å°ç项ç®é ç½® * åå¹¶æ°æ®åºåé ç½®æä»¶ä¸çæ å°ä¿¡æ¯ */ @Override public PlcAddress getProjectConfigWithMapping(String projectId) { try { // ä» ä½¿ç¨æ°æ®åºä¸ç项ç®é ç½® return getMappingByProjectId(projectId); } catch (Exception e) { log.error("è·å项ç®é 置失败ï¼é¡¹ç®ID: {}", projectId, e); return null; } } /** * 仿°æ®åºè·å项ç®é ç½® */ @Override public PlcAddress getProjectConfig(String projectId) { try { return plcAddressMapper.selectOne( new LambdaQueryWrapper<PlcAddress>() .eq(PlcAddress::getProjectId, projectId) ); } catch (Exception e) { log.error("è·å项ç®é 置失败ï¼é¡¹ç®ID: {}", projectId, e); return null; } } /** * è·åæææ å°é ç½® * åå¹¶æ°æ®åºåé ç½®æä»¶ä¸çæ å°ä¿¡æ¯ */ @Override public List<PlcAddress> getAllMappings() { try { // ç´æ¥è¿åæ°æ®åºä¸çæ å°é ç½® return plcAddressMapper.selectList(null); } catch (Exception e) { log.error("è·åææPLCå°åæ å°é 置失败", e); throw new RuntimeException("è·åææPLCå°åæ å°é 置失败", e); } } /** * å页è·åPLCå°åæ å°é ç½® */ @Override public IPage<PlcAddress> getMappingsByPage(int page, int size, String projectId, String plcIp) { try { Page<PlcAddress> pageParam = new Page<>(page, size); LambdaQueryWrapper<PlcAddress> queryWrapper = new LambdaQueryWrapper<>(); if (projectId != null && !projectId.trim().isEmpty()) { queryWrapper.like(PlcAddress::getProjectId, projectId); } if (plcIp != null && !plcIp.trim().isEmpty()) { queryWrapper.like(PlcAddress::getPlcIp, plcIp); } return plcAddressMapper.selectPage(pageParam, queryWrapper); } catch (Exception e) { log.error("å页è·åPLCå°åæ å°é 置失败", e); throw new RuntimeException("å页è·åPLCå°åæ å°é 置失败", e); } } /** * æ ¹æ®IDè·åPLCå°åæ å°é ç½® */ @Override public PlcAddress getMappingById(Long id) { try { return plcAddressMapper.selectById(id); } catch (Exception e) { log.error("æ ¹æ®IDè·åPLCå°åæ å°é 置失败ï¼ID: {}", id, e); throw new RuntimeException("æ ¹æ®IDè·åPLCå°åæ å°é 置失败", e); } } /** * æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é ç½® */ @Override public PlcAddress getMappingByProjectId(String projectId) { try { return plcAddressMapper.selectOne( new LambdaQueryWrapper<PlcAddress>() .eq(PlcAddress::getProjectId, projectId) ); } catch (Exception e) { log.error("æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é 置失败ï¼é¡¹ç®ID: {}", projectId, e); throw new RuntimeException("æ ¹æ®é¡¹ç®æ è¯è·åPLCå°åæ å°é 置失败", e); } } /** * ä¿åPLCå°åæ å°é ç½® */ @Override public PlcAddress saveMapping(PlcAddress mapping) { try { // æ£æ¥é¡¹ç®IDæ¯å¦å·²åå¨ PlcAddress existing = plcAddressMapper.selectOne( new LambdaQueryWrapper<PlcAddress>() .eq(PlcAddress::getProjectId, mapping.getProjectId()) ); if (existing != null) { throw new RuntimeException("é¡¹ç®æ è¯ " + mapping.getProjectId() + " å·²åå¨"); } plcAddressMapper.insert(mapping); return mapping; } catch (Exception e) { log.error("ä¿åPLCå°åæ å°é 置失败", e); throw new RuntimeException("ä¿åPLCå°åæ å°é 置失败", e); } } /** * æ´æ°PLCå°åæ å°é ç½® */ @Override public PlcAddress updateMapping(PlcAddress mapping) { try { // æ£æ¥IDæ¯å¦åå¨ PlcAddress existing = plcAddressMapper.selectById(mapping.getId()); if (existing == null) { return null; } // 妿项ç®IDæååï¼æ£æ¥æ°é¡¹ç®IDæ¯å¦å·²åå¨ if (!existing.getProjectId().equals(mapping.getProjectId())) { PlcAddress duplicate = plcAddressMapper.selectOne( new LambdaQueryWrapper<PlcAddress>() .eq(PlcAddress::getProjectId, mapping.getProjectId()) ); if (duplicate != null) { throw new RuntimeException("é¡¹ç®æ è¯ " + mapping.getProjectId() + " å·²åå¨"); } } plcAddressMapper.updateById(mapping); return mapping; } catch (Exception e) { log.error("æ´æ°PLCå°åæ å°é 置失败", e); throw new RuntimeException("æ´æ°PLCå°åæ å°é 置失败", e); } } /** * å é¤PLCå°åæ å°é ç½® */ @Override public boolean deleteMapping(Long id) { try { int result = plcAddressMapper.deleteById(id); return result > 0; } catch (Exception e) { log.error("å é¤PLCå°åæ å°é 置失败ï¼ID: {}", id, e); throw new RuntimeException("å é¤PLCå°åæ å°é 置失败", e); } } /** * æ¹éå é¤PLCå°åæ å°é ç½® */ @Override public int deleteMappings(List<Long> ids) { try { if (ids == null || ids.isEmpty()) { return 0; } return plcAddressMapper.deleteBatchIds(ids); } catch (Exception e) { log.error("æ¹éå é¤PLCå°åæ å°é 置失败ï¼IDå表: {}", ids, e); throw new RuntimeException("æ¹éå é¤PLCå°åæ å°é 置失败", e); } } /** * æµè¯PLCè¿æ¥ */ @Override public boolean testConnection(PlcAddress mapping) { try { // è§£æPLCç±»å EPlcType plcType = EPlcType.S1200; // é»è®¤å¼ if (mapping.getPlcType() != null && !mapping.getPlcType().trim().isEmpty()) { try { plcType = EPlcType.valueOf(mapping.getPlcType()); } catch (IllegalArgumentException e) { log.warn("æªç¥çPLCç±»å: {}, 使ç¨é»è®¤ç±»å S1200", mapping.getPlcType()); } } // å建S7PLCå®ä¾ String plcIp = mapping.getPlcIp() != null ? mapping.getPlcIp() : "192.168.10.21"; S7PLC s7Plc = new S7PLC(plcType, plcIp); // å建EnhancedS7Serializerå®ä¾ EnhancedS7Serializer serializer = EnhancedS7Serializer.newInstance(s7Plc); // å°è¯è¯»åä¸ä¸ªç®åçæ°æ®æ¥æµè¯è¿æ¥ String dbArea = mapping.getDbArea() != null ? mapping.getDbArea() : "DB1"; int beginIndex = mapping.getBeginIndex(); // è¿éæä»¬åªæµè¯è¿æ¥ï¼ä¸è¯»åå®é æ°æ® // å®é 项ç®ä¸å¯è½éè¦æ ¹æ®å ·ä½éæ±è°æ´ return true; } catch (Exception e) { log.error("PLCè¿æ¥æµè¯å¤±è´¥", e); return false; } } /** * éæ°å è½½é ç½®æä»¶ä¸çæ å° */ @Override public void reloadConfigMappings() { // ç°ä» ä½¿ç¨æ°æ®åºä¸çé ç½®ï¼ä¸å仿件éè½½ log.info("å½åä½¿ç¨æ°æ®åºé ç½®ï¼reloadConfigMappingsæ éæä½"); } /** * å°æ°æ®åºå®ä½è½¬æ¢ä¸ºé¡¹ç®é 置对象 */ } mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcAutoTestServiceImpl.java
New file @@ -0,0 +1,81 @@ package com.mes.service.impl; import com.mes.service.IPlcAutoTestService; import com.mes.service.IPlcTestWriteService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import javax.annotation.Resource; /** * PLCèªå¨æµè¯æå¡å®ç°ç±» * 宿¶æ¨¡æPLCè¡ä¸ºï¼åPLCåå ¥æµè¯æ°æ®ï¼ç¨äºèªå¨æµè¯MESç¨åº * * @author huang * @date 2025/10/30 */ @Slf4j @Service public class PlcAutoTestServiceImpl implements PlcAutoTestService { @Resource private IPlcTestWriteService plcTestWriteService; // èªå¨æµè¯å¼å ³ @Value("${plc.auto.test.enabled:false}") private boolean autoTestEnabled; // èªå¨æµè¯é´éï¼æ¯«ç§ï¼ @Value("${plc.auto.test.interval:5000}") private long autoTestInterval; /** * 宿¶èªå¨æµè¯ä»»å¡ */ @Scheduled(fixedDelayString = "${plc.auto.test.interval:5000}") public void autoTestTask() { if (!autoTestEnabled) { return; } try { log.info("å¼å§æ§è¡PLCèªå¨æµè¯ä»»å¡"); // 模æPLCè¯·æ± plcTestWriteService.simulatePlcRequest(); Thread.sleep(1000); // 模æPLCæ±æ¥ plcTestWriteService.simulatePlcReport(); log.info("PLCèªå¨æµè¯ä»»å¡æ§è¡å®æ"); } catch (Exception e) { log.error("PLCèªå¨æµè¯ä»»å¡æ§è¡å¼å¸¸", e); } } /** * å¯ç¨èªå¨æµè¯ */ @Override public void enableAutoTest() { this.autoTestEnabled = true; log.info("PLCèªå¨æµè¯å·²å¯ç¨"); } /** * ç¦ç¨èªå¨æµè¯ */ @Override public void disableAutoTest() { this.autoTestEnabled = false; log.info("PLCèªå¨æµè¯å·²ç¦ç¨"); } /** * è·åèªå¨æµè¯ç¶æ */ @Override public boolean isAutoTestEnabled() { return this.autoTestEnabled; } } mes-processes/mes-plcSend/src/main/java/com/mes/service/impl/PlcTestWriteServiceImpl.java
New file @@ -0,0 +1,295 @@ package com.mes.service.impl; import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType; import com.github.xingshuangs.iot.protocol.s7.service.S7PLC; import com.mes.entity.PlcBaseData; import com.mes.entity.PlcAddress; import com.mes.s7.enhanced.EnhancedS7Serializer; import com.mes.service.PlcAddressService; import com.mes.service.IPlcTestWriteService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** * PLCæµè¯åå ¥æå¡å®ç°ç±» * 模æPLCè¡ä¸ºï¼åPLCåå ¥æµè¯æ°æ®ï¼ç¨äºæµè¯MESç¨åº * * @author huang * @date 2025/10/30 */ @Slf4j @Service public class PlcTestWriteServiceImpl implements PlcTestWriteService { @Resource private PlcAddressService plcAddressService; private static final int ON = 1; private static final int OFF = 0; // å½å使ç¨çé¡¹ç®æ è¯ private String currentProjectId = "vertical"; // ç¼åä¸å项ç®çS7Serializerå®ä¾ private final ConcurrentMap<String, EnhancedS7Serializer> serializerCache = new ConcurrentHashMap<>(); /** * 模æPLCåé请æ±åï¼è§¦åMESä»»å¡ä¸åï¼ */ @Override public boolean simulatePlcRequest() { return simulatePlcRequest(currentProjectId); } /** * 模æPLCåé请æ±åï¼è§¦åMESä»»å¡ä¸åï¼- æ¯ææå®é¡¹ç® */ @Override public boolean simulatePlcRequest(String projectId) { try { // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); // 读åå½åPLCç¶æ PlcBaseData currentData = s7Serializer.read(PlcBaseData.class, config.getDbArea(), config.getBeginIndex()); if (currentData.getOnlineState() == OFF) { log.info("å½åPLCèæºæ¨¡å¼ä¸º0ï¼åæ¢èæº"); return false; }else if (currentData.getPlcReport() == ON){ log.info("å½åä¸çPLCæ±æ¥å为1ï¼é置为0"); currentData.setPlcReport(OFF); } // 设置PLC请æ±å为1ï¼è§¦åMESä»»å¡å¤çï¼ currentData.setPlcRequest(ON); s7Serializer.write(currentData, config.getDbArea(), config.getBeginIndex()); log.info("模æPLCåé请æ±åæåï¼plcRequest=1, projectId={}, dbArea={}, beginIndex={}", projectId, config.getDbArea(), config.getBeginIndex()); return true; } catch (Exception e) { log.error("模æPLC请æ±å失败", e); return false; } } /** * 模æPLCä»»å¡å®ææ±æ¥ */ @Override public boolean simulatePlcReport() { return simulatePlcReport(currentProjectId); } /** * 模æPLCä»»å¡å®ææ±æ¥ - æ¯ææå®é¡¹ç® */ @Override public boolean simulatePlcReport(String projectId) { try { // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); PlcBaseData currentData = s7Serializer.read(PlcBaseData.class, config.getDbArea(), config.getBeginIndex()); // 设置PLCæ±æ¥å为1ï¼ä»»å¡å®æï¼ currentData.setPlcReport(ON); // 请æ±åæ¸ 0 currentData.setPlcRequest(OFF); // è®¾ç½®å®ææ°éçæ°æ® currentData.setMesGlassCount(10); s7Serializer.write(currentData, config.getDbArea(), config.getBeginIndex()); log.info("模æPLCä»»å¡å®ææ±æ¥ï¼plcReport=1, mesGlassCount=10, projectId={}, dbArea={}, beginIndex={}", projectId, config.getDbArea(), config.getBeginIndex()); return true; } catch (Exception e) { log.error("模æPLCä»»å¡å®ææ±æ¥å¤±è´¥", e); return false; } } /** * 模æPLCåéèæºç¶æ */ @Override public boolean simulateOnlineStatus(int onlineState) { return simulateOnlineStatus(onlineState, currentProjectId); } /** * 模æPLCåéèæºç¶æ - æ¯ææå®é¡¹ç® */ @Override public boolean simulateOnlineStatus(int onlineState, String projectId) { try { // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); PlcBaseData currentData = s7Serializer.read(PlcBaseData.class, config.getDbArea(), config.getBeginIndex()); // 1:èæº 0:è±æº currentData.setOnlineState(onlineState); s7Serializer.write(currentData, config.getDbArea(), config.getBeginIndex()); log.info("模æPLCèæºç¶æï¼onlineState={}, projectId={}, dbArea={}, beginIndex={}", onlineState, projectId, config.getDbArea(), config.getBeginIndex()); return true; } catch (Exception e) { log.error("模æPLCèæºç¶æå¤±è´¥", e); return false; } } /** * éç½®PLCææç¶æ */ @Override public boolean resetPlc() { return resetPlc(currentProjectId); } /** * éç½®PLCææç¶æ - æ¯ææå®é¡¹ç® */ @Override public boolean resetPlc(String projectId) { try { // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); PlcBaseData resetData = new PlcBaseData(); // éç½®ææå ³é®å段 resetData.setPlcRequest(OFF); resetData.setPlcReport(OFF); resetData.setMesSend(OFF); resetData.setMesConfirm(OFF); // é»è®¤èæº resetData.setOnlineState(ON); resetData.setMesGlassCount(0); // æ¸ é¤æ¥è¦ resetData.setAlarmInfo(OFF); s7Serializer.write(resetData, config.getDbArea(), config.getBeginIndex()); log.info("PLCç¶æå·²éç½®, projectId={}, dbArea={}, beginIndex={}", projectId, config.getDbArea(), config.getBeginIndex()); return true; } catch (Exception e) { log.error("éç½®PLCç¶æå¤±è´¥", e); return false; } } /** * 读åPLCå½åç¶æ */ @Override public PlcBaseData readPlcStatus() { return readPlcStatus(currentProjectId); } /** * 读åPLCå½åç¶æ - æ¯ææå®é¡¹ç® */ @Override public PlcBaseData readPlcStatus(String projectId) { try { // è·å项ç®é ç½®ï¼æ°æ®åºå®ä½ï¼ PlcAddress config = plcAddressService.getProjectConfigWithMapping(projectId); // è·å对åºçS7Serializer EnhancedS7Serializer s7Serializer = getSerializerForProject(projectId, config); return s7Serializer.read(PlcBaseData.class, config.getDbArea(), config.getBeginIndex()); } catch (Exception e) { log.error("读åPLCç¶æå¤±è´¥", e); return null; } } /** * 设置å½åé¡¹ç®æ è¯ */ @Override public void setCurrentProjectId(String projectId) { this.currentProjectId = projectId; } /** * è·åå½åé¡¹ç®æ è¯ */ @Override public String getCurrentProjectId() { return this.currentProjectId; } /** * è·å项ç®å¯¹åºçS7Serializerå®ä¾ * 妿ä¸åå¨ï¼åå建ä¸ä¸ªæ°çå®ä¾å¹¶ç¼å * * @param projectId é¡¹ç®æ è¯ * @param config 项ç®é ç½® * @return S7Serializerå®ä¾ */ private EnhancedS7Serializer getSerializerForProject(String projectId, PlcAddress config) { return serializerCache.computeIfAbsent(projectId, id -> { // è§£æPLCç±»å EPlcType plcType = EPlcType.S1200; // é»è®¤å¼ if (config != null && config.getPlcType() != null) { try { plcType = EPlcType.valueOf(config.getPlcType()); } catch (IllegalArgumentException e) { log.warn("æªç¥çPLCç±»å: {}, 使ç¨é»è®¤ç±»å S1200", config.getPlcType()); } } // å建S7PLCå®ä¾ String plcIp = (config != null && config.getPlcIp() != null) ? config.getPlcIp() : "192.168.10.21"; S7PLC s7Plc = new S7PLC(plcType, plcIp); // å建并è¿åEnhancedS7Serializerå®ä¾ return EnhancedS7Serializer.newInstance(s7Plc); }); } /** * æ¸ é¤æå®é¡¹ç®çS7Serializerç¼å * * @param projectId é¡¹ç®æ è¯ */ @Override public void clearSerializerCache(String projectId) { serializerCache.remove(projectId); log.info("å·²æ¸ é¤é¡¹ç® {} çS7Serializerç¼å", projectId); } /** * æ¸ é¤ææS7Serializerç¼å */ @Override public void clearAllSerializerCache() { serializerCache.clear(); log.info("å·²æ¸ é¤ææS7Serializerç¼å"); } } mes-processes/mes-plcSend/src/main/java/com/mes/vo/Result.java
@@ -5,7 +5,7 @@ /** * ç»ä¸APIååºç»æ * * @author zhoush * @author huang * @date 2025/10/29 */ @Data @@ -104,6 +104,7 @@ * 夿æ¯å¦æå */ public boolean isSuccess() { return this.code != null && this.code == 200; // 使ç¨Integer.valueOfé¿å èªå¨æç®±é®é¢ return this.code != null && Integer.valueOf(200).equals(this.code); } } mes-processes/mes-plcSend/src/main/resources/application-dev.yml
@@ -30,38 +30,6 @@ port: 6379 password: 123456 raw: mode: shuttle s7: shuttle: dbArea: DB38. beginIndex: 0 address: raw: onlineState: 2 plcRequest: 0 plcReport: 10 finishA: 60 finishB: 62 state: 18 onePosition: 6 twoPosition: 14 mesSend: 20 mesConfirm: 40 start: 24 target: 26 mesGlassCount: 30 rawMargin1: 32 mesWidth1: 34 mesHeight1: 36 rawThickness1: 38 rawMargin2: 44 mesWidth2: 46 mesHeight2: 48 rawThickness2: 50 alarmInfo: 52 # PLCèªå¨æµè¯é ç½® plc: auto: @@ -71,10 +39,8 @@ # PLCå°åæ å°é ç½® address: mapping: defaultDbArea: "DB1." defaultBeginIndex: 0 projects: shuttle: vertical: dbArea: "DB38." beginIndex: 0 plcIp: "192.168.10.21" mes-processes/mes-plcSend/src/main/resources/db/migration/V1.0.0__Create_plc_address_mapping_table.sql
@@ -22,5 +22,5 @@ -- æå ¥é»è®¤é ç½® INSERT INTO `plc_address_mapping` (`project_id`, `project_name`, `db_area`, `begin_index`, `plc_ip`, `plc_type`, `description`) VALUES ('shuttle', 'ç©¿æ¢è½¦é¡¹ç®', 'DB38', 0, '192.168.10.21', 'S1200', 'é»è®¤ç©¿æ¢è½¦é¡¹ç®é ç½®') ON DUPLICATE KEY UPDATE `update_time` = CURRENT_TIMESTAMP; VALUES ('vertical', 'åç´è½¦é¡¹ç®', 'DB38', 0, '192.168.10.21', 'S1200', 'é»è®¤åç´è½¦é¡¹ç®é ç½®') ON DUPLICATE KEY UPDATE `update_time` = CURRENT_TIMESTAMP; mes-processes/mes-plcSend/target/classes/application-dev.yml
File was deleted mes-processes/mes-plcSend/target/classes/application.yml
File was deleted mes-processes/mes-plcSend/target/classes/changelog/changelogBase.xml
File was deleted mes-processes/mes-plcSend/target/classes/changelog/mesInit.sql
File was deleted mes-processes/mes-plcSend/target/classes/changelog/mesInitLy.sql
File was deleted mes-processes/mes-plcSend/target/classes/com/mes/PlcSendApplication.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/config/PlcAddressMappingConfig$ProjectPlcConfig.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/config/PlcAddressMappingConfig.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/controller/PlcAddressMappingController.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/controller/PlcTestWriteController.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/entity/PlcAddressMapping.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/entity/PlcBaseData.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/job/config/S7PlcSendConfig.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/mapper/PlcAddressMappingMapper.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/service/PlcAddressMappingService.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/service/PlcAutoTestService.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/service/PlcTestWriteService.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/service/impl/PlcTestWriteServiceImpl.classBinary files differ
mes-processes/mes-plcSend/target/classes/com/mes/vo/Result.classBinary files differ
mes-processes/mes-plcSend/target/classes/db/migration/V1.0.0__Create_plc_address_mapping_table.sql
File was deleted mes-processes/mes-plcSend/target/config/application-dev.yml
File was deleted mes-processes/mes-plcSend/target/config/application.yml
File was deleted mes-processes/mes-plcSend/target/config/changelog/changelogBase.xml
File was deleted mes-processes/mes-plcSend/target/config/changelog/mesInit.sql
File was deleted mes-processes/mes-plcSend/target/config/changelog/mesInitLy.sql
File was deleted mes-processes/mes-plcSend/target/config/db/migration/V1.0.0__Create_plc_address_mapping_table.sql
File was deleted mes-processes/mes-plcSend/target/lib/FastInfoset-1.2.15.jarBinary files differ
mes-processes/mes-plcSend/target/lib/HdrHistogram-2.1.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/HikariCP-3.2.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/SparseBitSet-1.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/archaius-core-0.7.6.jarBinary files differ
mes-processes/mes-plcSend/target/lib/aspectjweaver-1.9.4.jarBinary files differ
mes-processes/mes-plcSend/target/lib/bcpkix-jdk15on-1.60.jarBinary files differ
mes-processes/mes-plcSend/target/lib/bcpkix-jdk18on-1.75.jarBinary files differ
mes-processes/mes-plcSend/target/lib/bcprov-jdk15on-1.60.jarBinary files differ
mes-processes/mes-plcSend/target/lib/bcprov-jdk18on-1.75.jarBinary files differ
mes-processes/mes-plcSend/target/lib/bcutil-jdk18on-1.75.jarBinary files differ
mes-processes/mes-plcSend/target/lib/byte-buddy-1.9.16.jarBinary files differ
mes-processes/mes-plcSend/target/lib/classgraph-4.1.7.jarBinary files differ
mes-processes/mes-plcSend/target/lib/classmate-1.4.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-codec-1.11.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-collections-3.2.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-collections4-4.4.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-compress-1.19.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-configuration-1.8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-csv-1.8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-fileupload-1.4.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-io-2.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-lang-2.6.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-lang3-3.8.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-logging-1.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-math3-3.6.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/commons-pool2-2.6.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/curvesapi-1.06.jarBinary files differ
mes-processes/mes-plcSend/target/lib/druid-1.1.8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/dynamic-datasource-spring-boot-starter-3.3.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/easyexcel-3.1.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/easyexcel-core-3.1.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/easyexcel-support-3.1.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/ehcache-3.6.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/fastjson-1.2.33.jarBinary files differ
mes-processes/mes-plcSend/target/lib/feign-core-10.2.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/feign-form-3.8.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/feign-form-spring-3.8.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/feign-hystrix-10.2.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/feign-slf4j-10.2.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/freemarker-2.3.29.jarBinary files differ
mes-processes/mes-plcSend/target/lib/guava-19.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/hibernate-validator-6.0.17.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/httpclient-4.5.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/httpcore-4.4.12.jarBinary files differ
mes-processes/mes-plcSend/target/lib/hutool-all-5.4.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/hystrix-core-1.5.18.jarBinary files differ
mes-processes/mes-plcSend/target/lib/iot-communication-1.5.4.jarBinary files differ
mes-processes/mes-plcSend/target/lib/istack-commons-runtime-3.0.7.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jackson-annotations-2.9.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jackson-core-2.9.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jackson-databind-2.9.9.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jackson-datatype-jdk8-2.9.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jackson-datatype-jsr310-2.9.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jackson-module-parameter-names-2.9.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/javassist-3.25.0-GA.jarBinary files differ
mes-processes/mes-plcSend/target/lib/javax.activation-api-1.2.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/javax.annotation-api-1.3.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/javax.inject-1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jaxb-api-2.3.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jaxb-runtime-2.3.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jboss-logging-3.3.3.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jedis-2.9.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jersey-apache-client4-1.19.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jersey-client-1.19.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jersey-core-1.19.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jjwt-0.9.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jsqlparser-3.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jsr305-3.0.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jsr311-api-1.1.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/jul-to-slf4j-1.7.28.jarBinary files differ
mes-processes/mes-plcSend/target/lib/knife4j-annotations-2.0.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/knife4j-core-2.0.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/knife4j-spring-2.0.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/knife4j-spring-boot-autoconfigure-2.0.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/knife4j-spring-boot-starter-2.0.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/knife4j-spring-ui-2.0.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/liquibase-core-3.6.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/log4j-api-2.11.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/log4j-to-slf4j-2.11.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/logback-classic-1.2.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/logback-core-1.2.3.jarBinary files differ
mes-processes/mes-plcSend/target/lib/lombok-1.18.8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mapstruct-1.3.1.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mes-rawGlassStorage-1.0.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/milo-spring-boot-starter-3.0.6.12.jarBinary files differ
mes-processes/mes-plcSend/target/lib/model-1.0.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mssql-jdbc-6.4.0.jre8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-3.5.6.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-plus-3.3.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-plus-annotation-3.4.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-plus-boot-starter-3.3.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-plus-core-3.4.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-plus-extension-3.4.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-plus-generator-3.4.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mybatis-spring-2.0.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/mysql-connector-java-8.0.17.jarBinary files differ
mes-processes/mes-plcSend/target/lib/nacos-api-1.1.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/nacos-client-1.1.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/nacos-common-1.1.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netflix-commons-util-0.3.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netflix-statistics-0.1.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-buffer-4.1.39.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-channel-fsm-0.8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-codec-4.1.39.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-codec-http-4.1.39.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-common-4.1.39.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-handler-4.1.39.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-resolver-4.1.39.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/netty-transport-4.1.39.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/poi-4.1.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/poi-ooxml-4.1.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/poi-ooxml-schemas-4.1.2.jarBinary files differ
mes-processes/mes-plcSend/target/lib/ribbon-2.3.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/ribbon-core-2.3.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/ribbon-httpclient-2.3.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/ribbon-loadbalancer-2.3.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/ribbon-transport-2.3.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/rxjava-1.3.8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/rxnetty-0.4.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/rxnetty-contexts-0.4.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/rxnetty-servo-0.4.9.jarBinary files differ
mes-processes/mes-plcSend/target/lib/screw-core-1.0.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/sdk-client-0.6.12.jarBinary files differ
mes-processes/mes-plcSend/target/lib/sdk-core-0.6.12.jarBinary files differ
mes-processes/mes-plcSend/target/lib/serverBase-1.0.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/servo-core-0.12.21.jarBinary files differ
mes-processes/mes-plcSend/target/lib/simpleclient-0.5.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/slf4j-api-1.7.28.jarBinary files differ
mes-processes/mes-plcSend/target/lib/snakeyaml-1.23.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-aop-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-beans-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-autoconfigure-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-aop-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-data-redis-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-jdbc-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-json-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-logging-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-security-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-tomcat-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-web-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-boot-starter-websocket-2.1.8.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-alibaba-nacos-discovery-2.1.0.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-commons-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-context-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-netflix-archaius-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-netflix-ribbon-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-openfeign-core-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-starter-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-starter-alibaba-nacos-discovery-2.1.0.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-starter-netflix-archaius-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-starter-netflix-ribbon-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-cloud-starter-openfeign-2.1.3.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-context-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-context-support-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-core-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-data-commons-2.1.10.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-data-keyvalue-2.1.10.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-data-redis-2.1.10.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-expression-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-jcl-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-jdbc-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-messaging-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-oxm-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-plugin-core-2.0.0.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-plugin-metadata-1.2.0.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-security-config-5.1.6.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-security-core-5.1.6.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-security-crypto-5.1.6.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-security-rsa-1.0.7.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-security-web-5.1.6.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-tx-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-web-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-webmvc-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/spring-websocket-5.1.9.RELEASE.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springSecurity-1.0.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-bean-validators-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-core-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-schema-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-spi-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-spring-web-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-spring-webmvc-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-swagger-common-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/springfox-swagger2-2.10.5.jarBinary files differ
mes-processes/mes-plcSend/target/lib/stack-client-0.6.12.jarBinary files differ
mes-processes/mes-plcSend/target/lib/stack-core-0.6.12.jarBinary files differ
mes-processes/mes-plcSend/target/lib/stax-ex-1.8.jarBinary files differ
mes-processes/mes-plcSend/target/lib/strict-machine-0.6.jarBinary files differ
mes-processes/mes-plcSend/target/lib/swagger-annotations-1.5.22.jarBinary files differ
mes-processes/mes-plcSend/target/lib/swagger-models-1.5.22.jarBinary files differ
mes-processes/mes-plcSend/target/lib/tomcat-embed-core-9.0.24.jarBinary files differ
mes-processes/mes-plcSend/target/lib/tomcat-embed-el-9.0.24.jarBinary files differ
mes-processes/mes-plcSend/target/lib/tomcat-embed-websocket-9.0.24.jarBinary files differ
mes-processes/mes-plcSend/target/lib/txw2-2.3.1.jarBinary files differ
mes-processes/mes-plcSend/target/lib/validation-api-2.0.1.Final.jarBinary files differ
mes-processes/mes-plcSend/target/lib/velocity-engine-core-2.0.jarBinary files differ
mes-processes/mes-plcSend/target/lib/xmlbeans-3.1.0.jarBinary files differ
mes-processes/mes-plcSend/target/maven-archiver/pom.properties
File was deleted mes-processes/mes-plcSend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
File was deleted mes-processes/mes-plcSend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
File was deleted mes-processes/mes-plcSend/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
mes-processes/mes-plcSend/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
mes-processes/mes-plcSend/target/mes-plcSend-1.0.0.jarBinary files differ
mes-processes/mes-plcSend/target/mes-plcSend-1.0.0.jar.originalBinary files differ
mes-web/src/views/plcTest/Test.vue
@@ -1,551 +1,899 @@ <template> <div class="auto-test-dashboard"> <!-- é¡¶é¨å¯¼èªåº --> <el-header class="header"> <h1>MESèªå¨åæµè¯å¹³å°</h1> <div class="header-actions"> <el-button type="primary" @click="showModuleStatus">æ¥ç模åç¶æ</el-button> <el-button type="primary" @click="importTask">å¯¼å ¥æµè¯ä»»å¡</el-button> <el-button type="success" @click="startTest" :disabled="!isConfigReady">å¼å§æµè¯</el-button> <el-button type="warning" @click="batchTest" :disabled="batchTasks.length === 0">æ¹éæµè¯</el-button> <el-button @click="resetAll">éç½®é ç½®</el-button> <div class="dashboard-container"> <div class="dashboard-header"> <div class="header-left"> <h2>MESæµè¯ç³»ç»</h2> </div> </el-header> <!-- 主ä½å å®¹åº --> <el-container> <!-- å·¦ä¾§ï¼æ¨¡åé ç½®ä¸åæ®µéæ© --> <el-aside width="320px" class="aside"> <el-card class="config-card"> <h3 class="section-title">模åé ç½®</h3> <el-select v-model="selectedModule" @change="handleModuleChange" placeholder="éæ©æµè¯æ¨¡å" style="width: 100%"> <el-option label="é¾é¨ä»å¨" value="gantryStorage"></el-option> <el-option label="ä¸ç模å" value="upperModule"></el-option> <el-option label="ç©¿æ¢ä»å¨" value="storageModule"></el-option> </el-select> <h3 class="section-title">åè®®åæ®µéæ©</h3> <el-checkbox-group v-model="checkedFields" class="field-checkbox-group"> <el-checkbox v-for="field in allFields" :key="field.value" :label="field.value" :disabled="isSystemField(field.value)"> {{ field.label }} </el-checkbox> </el-checkbox-group> <h3 class="section-title">æµè¯åæ°é ç½®</h3> <el-form :model="testParameters" label-width="120px" class="parameter-form"> <el-form-item label="PlCå°å"> <el-input v-model="testParameters.plcAddress" :min="0" :max="100" size="small"></el-input> <div class="header-right"> <el-button type="success" @click="startTest"> <i class="el-icon-play"></i> å¼å§æµè¯ </el-button> <el-button type="warning" @click="stopTest"> <i class="el-icon-stop"></i> 忢æµè¯ </el-button> </div> </div> <div class="dashboard-content"> <el-aside width="400px" class="config-aside"> <el-card class="config-section"> <h3><i class="el-icon-sitemap"></i> 项ç®é ç½®</h3> <el-form label-width="100px" size=""> <el-form-item label="项ç®éæ©"> <el-select v-model="selectedProject" placeholder="è¯·éæ©é¡¹ç®" @change="handleProjectChange" class="full-width"> <el-option v-for="project in projectList" :key="project.value" :label="project.label" :value="project.value"> </el-option> </el-select> </el-form-item> <el-form-item label="DBå"> <el-input v-model="testParameters.dbAddress" :min="0" :max="100" size="small"></el-input> </el-form-item> <el-form-item label="ä»»å¡éè¯æ¬¡æ°"> <el-input-number v-model="testParameters.retryCount" :min="0" :max="10" size="small"></el-input-number> </el-form-item> <el-form-item label="æµè¯é´é(ms)"> <el-input-number v-model="testParameters.interval" :min="100" :max="10000" size="small"></el-input-number> </el-form-item> <el-form-item label="æ¨¡ææ éæ¦ç"> <el-slider v-model="testParameters.failureRate" :min="0" :max="100" show-stops></el-slider> <el-form-item label="模åéæ©"> <el-select v-model="selectedModule" placeholder="è¯·éæ©æ¨¡å" @change="handleModuleChange" class="full-width"> <el-option v-for="module in availableModules" :key="module" :label="module" :value="module"> </el-option> </el-select> </el-form-item> </el-form> <div class="test-actions"> <el-button type="primary" size="small" @click="saveCurrentConfig">ä¿åé ç½®</el-button> <el-button size="small" @click="loadConfig">å è½½é ç½®</el-button> </el-card> <el-card class="config-section"> <h3><i class="el-icon-list"></i> åè®®åæ®µé ç½®</h3> <div class="field-container"> <div class="field-header"> <span>åæ®µå表</span> <el-button type="text" size="small" icon="el-icon-plus" @click="addNewField" class="add-btn">æ·»å åæ®µ</el-button> </div> <div class="field-list"> <div v-for="field in allFields" :key="field.value" class="field-item"> <div class="field-info"> <el-checkbox v-model="checkedFields" :label="field.value">{{ field.label }}</el-checkbox> </div> <div class="field-address"> <span class="field-address-label">DBåç´¢å¼:</span> <el-input v-model="field.address" size="mini" placeholder="è¾å ¥DBåç´¢å¼" style="width: 100px;"></el-input> </div> <el-button v-if="!isSystemField(field.value)" type="text" size="mini" icon="el-icon-delete" class="remove-btn" @click="removeField(field.value)"></el-button> </div> </div> </div> </el-card> <el-card class="config-section"> <h3><i class="el-icon-sliders"></i> æµè¯åæ°é ç½®</h3> <el-form :model="testParameters" label-width="100px" size="small"> <el-form-item label="PLCå°å"> <el-input v-model="testParameters.plcAddress" placeholder="è¾å ¥PLCå°å"></el-input> </el-form-item> <el-form-item label="DBå"> <el-input v-model="testParameters.dbAddress" placeholder="è¾å ¥DBå"></el-input> </el-form-item> <el-form-item label="è¶ æ¶æ¶é´"> <el-input-number v-model="testParameters.timeout" :min="1" :max="60" controls-position="right"></el-input-number> <span style="margin-left: 10px;">ç§</span> </el-form-item> <el-form-item label="éè¯æ¬¡æ°"> <el-input-number v-model="testParameters.retryCount" :min="0" :max="10" controls-position="right"></el-input-number> <span style="margin-left: 10px;">次</span> </el-form-item> </el-form> <div style="margin-top: 15px; text-align: center;"> <el-button type="primary" @click="saveCurrentConfig">ä¿åé ç½®</el-button> <el-button @click="resetConfig">éç½®é ç½®</el-button> </div> </el-card> </el-aside> <!-- å³ä¾§ï¼ä»»å¡çæ§ä¸ç»æå±ç¤º --> <el-main class="main"> <!-- æ¹éæµè¯é ç½® --> <el-card class="batch-test-card" v-if="showBatchTestConfig"> <h3 class="section-title">æ¹éæµè¯é ç½®</h3> <el-table :data="batchTasks" style="width: 100%"> <el-table-column prop="module" label="模å" width="120"></el-table-column> <el-table-column prop="start" label="èµ·å§ä½ç½®" width="100"></el-table-column> <el-table-column prop="target" label="ç®æ ä½ç½®" width="100"></el-table-column> <el-table-column prop="retryCount" label="éè¯æ¬¡æ°" width="100"></el-table-column> <el-table-column label="æä½" width="80"> <template #default="scope"> <el-button type="danger" size="mini" @click="removeBatchTask(scope.$index)">å é¤</el-button> </template> </el-table-column> </el-table> <div class="batch-actions"> <el-button type="primary" size="small" @click="addCurrentToBatch">æ·»å å½åé ç½®</el-button> <el-button type="success" size="small" @click="startBatchTest">æ§è¡æ¹éæµè¯</el-button> <el-main class="monitor-main"> <div class="monitor-section"> <div class="section-header"> <h3><i class="el-icon-monitor"></i> ä»»å¡çæ§</h3> <div class="section-actions"> <el-button type="primary" size="small" @click="showBatchTestDialog"> <i class="el-icon-files"></i> æ¹éæµè¯ </el-button> <el-button type="success" size="small" @click="showImportDialog"> <i class="el-icon-upload2"></i> å¯¼å ¥ä»»å¡ </el-button> <el-button size="small" @click="refreshTasks"> <i class="el-icon-refresh"></i> å·æ° </el-button> </div> </div> </el-card> <!-- 任塿µè½¬æ¶é´çº¿ --> <div class="timeline-section"> <h3 class="section-title">任塿µè½¬çæµ</h3> <div class="timeline-container" v-if="runningTasks.length > 0"> <el-timeline v-for="(task, index) in runningTasks" :key="index" class="task-timeline"> <el-timeline-item v-for="(event, eventIndex) in task.timeline" :key="eventIndex" :timestamp="event.time" :type="event.status" :color="getStatusColor(event.status)" :icon="getEventIcon(event.status)"> {{ event.desc }} </el-timeline-item> </el-timeline> <div class="task-container"> <h4>å½åä»»å¡</h4> <div v-if="currentTasks.length === 0" class="empty-state"> <div class="empty-icon"><i class="el-icon-clipboard"></i></div> <div class="empty-text">ææ ä»»å¡</div> </div> <div v-else class="task-list"> <div v-for="task in currentTasks" :key="task.id" class="task-item" @click="showTaskDetail(task)"> <div class="task-info"> <span class="task-id">{{ task.id }}</span> <span class="task-module">{{ task.module }}</span> <span class="task-project">{{ task.project }}</span> </div> <el-tag :type="getStatusType(task.status)">{{ task.status }}</el-tag> </div> </div> </div> <div class="empty-state" v-else> <el-empty description="ææ è¿è¡ä¸çä»»å¡" /> <div class="result-container"> <h4>æµè¯ç»æç»è®¡</h4> <div class="result-stats"> <div class="stat-item"> <div class="stat-number">{{ testStats.total }}</div> <div class="stat-label">æ»æµè¯æ°</div> </div> <div class="stat-item"> <div class="stat-number pass">{{ testStats.passed }}</div> <div class="stat-label">éè¿</div> </div> <div class="stat-item"> <div class="stat-number fail">{{ testStats.failed }}</div> <div class="stat-label">失败</div> </div> <div class="stat-item"> <div class="stat-number">{{ testStats.running }}</div> <div class="stat-label">è¿è¡ä¸</div> </div> </div> </div> </div> <!-- æµè¯ç»æç»è®¡ --> <div class="result-section mt-20"> <h3 class="section-title">æµè¯ç»æç»è®¡</h3> <el-row :gutter="20"> <el-col :span="6"> <el-card class="result-card"> <div class="result-item"> <span class="label">æ»ä»»å¡æ°</span> <span class="value">{{ taskCount.total }}</span> </div> </el-card> </el-col> <el-col :span="6"> <el-card class="result-card"> <div class="result-item"> <span class="label">éè¿æ°</span> <span class="value success">{{ taskCount.pass }}</span> </div> </el-card> </el-col> <el-col :span="6"> <el-card class="result-card"> <div class="result-item"> <span class="label">失败æ°</span> <span class="value error">{{ taskCount.fail }}</span> </div> </el-card> </el-col> <el-col :span="6"> <el-card class="result-card"> <div class="result-item"> <span class="label">éè¿ç</span> <span class="value" :class="{ success: taskCount.total > 0 && taskCount.pass / taskCount.total > 0.9, error: taskCount.total > 0 && taskCount.pass / taskCount.total < 0.5 }"> {{ calculatePassRate() }}% </span> </div> </el-card> </el-col> </el-row> <div class="result-table-container"> <el-table :data="testResults" style="width: 100%" border> <el-table-column prop="module" label="模å"></el-table-column> <el-table-column prop="startTime" label="å¼å§æ¶é´"></el-table-column> <el-table-column prop="endTime" label="ç»ææ¶é´"></el-table-column> <el-table-column prop="status" label="ç¶æ" width="80"> <template #default="scope"> <el-tag :type="scope.row.status === 'éè¿' ? 'success' : 'error'" size="small"> {{ scope.row.status }} </el-tag> <div class="result-list"> <h4>æµè¯ç»æ</h4> <el-table :data="testResults" style="width: 100%" border stripe :cell-style="{ padding: '8px 10px' }"> <el-table-column prop="id" label="ä»»å¡ID" width="100"></el-table-column> <el-table-column prop="project" label="项ç®" width="120"></el-table-column> <el-table-column prop="module" label="模å" width="120"></el-table-column> <el-table-column prop="field" label="åæ®µ" width="120"></el-table-column> <el-table-column prop="status" label="ç¶æ" width="100"> <template slot-scope="scope"> <el-tag :type="getStatusType(scope.row.status)">{{ scope.row.status }}</el-tag> </template> </el-table-column> <el-table-column prop="duration" label="èæ¶(ç§)"></el-table-column> <el-table-column prop="retryCount" label="éè¯æ¬¡æ°"></el-table-column> <el-table-column prop="errorMsg" label="é误信æ¯" v-if="showErrorColumn" :show-overflow-tooltip="true"></el-table-column> <el-table-column label="æä½" width="100"> <template #default="scope"> <el-button type="text" size="small" @click="viewTaskDetail(scope.row)">æ¥ç详æ </el-button> <el-button type="text" size="small" @click="retryTask(scope.row)">éè¯</el-button> </template> </el-table-column> <el-table-column prop="startTime" label="å¼å§æ¶é´" width="160"></el-table-column> <el-table-column prop="duration" label="èæ¶" width="100"></el-table-column> <el-table-column prop="result" label="ç»æ"></el-table-column> </el-table> </div> </div> </el-main> </el-container> <!-- å¯¼å ¥ä»»å¡å¼¹çª --> <el-dialog title="å¯¼å ¥æµè¯ä»»å¡" v-model="importDialogVisible" width="50%"> <el-upload class="upload-demo" action="#" :auto-upload="false" :on-change="handleFileChange" :before-upload="beforeFileUpload" drag> <i class="el-icon-upload"></i> <div class="el-upload__text">ææ½æä»¶å°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> <template #tip> <div class="el-upload__tip">ä» æ¯æExcel/JSONæ ¼å¼ï¼å¤§å°ä¸è¶ è¿5MB</div> </template> </el-upload> <template #footer> <div class="dialog-footer"> <el-button @click="importDialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="confirmImport">ç¡®è®¤å¯¼å ¥</el-button> </div> </template> </el-dialog> <!-- 模åç¶æå¼¹çª --> <el-dialog title="PLC模åç¶æ" v-model="statusDialogVisible" width="70%"> <div class="status-container"> <el-tabs v-model="activeStatusTab" @tab-click="handleStatusTabClick"> <el-tab-pane label="é¾é¨ä»å¨" name="gantryStorage"></el-tab-pane> <el-tab-pane label="ä¸ç模å" name="upperModule"></el-tab-pane> <el-tab-pane label="ç©¿æ¢ä»å¨" name="storageModule"></el-tab-pane> </el-tabs> <el-table :data="statusTableData" style="width: 100%" border v-if="statusTableData.length > 0"> <el-table-column prop="key" label="åæ°åç§°"></el-table-column> <el-table-column prop="value" label="å½åå¼"></el-table-column> <el-table-column prop="updateTime" label="æ´æ°æ¶é´"></el-table-column> </el-table> <div v-else class="empty-status"> <el-empty description="ææ ç¶ææ°æ®" /> </div> <div class="status-actions"> <el-button type="primary" size="small" @click="refreshModuleStatus">å·æ°ç¶æ</el-button> <el-button type="warning" size="small" @click="resetModuleStatus">é置模å</el-button> </div> <!-- æ¹éæµè¯å¼¹çª --> <el-dialog title="æ¹éæµè¯" :visible.sync="batchTestDialogVisible" width="60%"> <div class="batch-test-container"> <el-form :model="batchTestForm" label-width="100px"> <el-form-item label="项ç®éæ©"> <el-select v-model="batchTestForm.projectIds" multiple placeholder="è¯·éæ©é¡¹ç®" style="width: 100%"> <el-option v-for="project in projectList" :key="project.value" :label="project.label" :value="project.value"> </el-option> </el-select> </el-form-item> <el-form-item label="模åéæ©"> <el-checkbox-group v-model="batchTestForm.modules"> <el-checkbox v-for="module in availableModules" :key="module" :label="module">{{ module }}</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="æµè¯å段"> <el-transfer v-model="batchTestForm.selectedFields" :data="allFields.map(field => ({key: field.value, label: field.label}))" :titles="['å¯éåæ®µ', 'å·²éåæ®µ']" :props="{key: 'key', label: 'label'}"> </el-transfer> </el-form-item> </el-form> <div class="batch-footer"> <el-button @click="batchTestDialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="startBatchTest">å¼å§æ¹éæµè¯</el-button> </div> </div> </el-dialog> <!-- ä»»å¡å¯¼å ¥å¼¹çª --> <el-dialog title="å¯¼å ¥ä»»å¡" :visible.sync="importDialogVisible" width="50%"> <el-upload class="upload-demo" drag action="/api/plcSend/test/import" :on-success="handleImportSuccess" :before-upload="beforeUpload"> <i class="el-icon-upload"></i> <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> <div class="el-upload__tip" slot="tip">åªè½ä¸ä¼ xlsx/xlsæä»¶ï¼ä¸ä¸è¶ è¿10MB</div> </el-upload> <div class="import-footer"> <el-button @click="importDialogVisible = false">åæ¶</el-button> <el-button type="primary" @click="confirmImport">ç¡®è®¤å¯¼å ¥</el-button> </div> </el-dialog> <!-- ä»»å¡è¯¦æ å¼¹çª --> <el-dialog title="ä»»å¡è¯¦æ " v-model="taskDetailVisible" width="60%"> <div class="task-detail"> <div class="detail-section"> <h4>åºæ¬ä¿¡æ¯</h4> <el-descriptions :column="2" :border="true"> <el-descriptions-item label="ä»»å¡ID">{{ currentTaskDetail.id }}</el-descriptions-item> <el-descriptions-item label="模å">{{ currentTaskDetail.module }}</el-descriptions-item> <el-descriptions-item label="ç¶æ">{{ currentTaskDetail.status }}</el-descriptions-item> <el-descriptions-item label="èæ¶">{{ currentTaskDetail.duration }}ç§</el-descriptions-item> <el-descriptions-item label="å¼å§æ¶é´" :span="2">{{ currentTaskDetail.startTime }}</el-descriptions-item> <el-descriptions-item label="ç»ææ¶é´" :span="2">{{ currentTaskDetail.endTime }}</el-descriptions-item> </el-descriptions> </div> <div class="detail-section"> <h4>æ§è¡æ¥å¿</h4> <el-dialog title="ä»»å¡è¯¦æ " :visible.sync="taskDetailDialogVisible" width="60%"> <div class="task-detail-container" v-if="selectedTask"> <el-descriptions :column="2" border> <el-descriptions-item label="ä»»å¡ID">{{ selectedTask.id }}</el-descriptions-item> <el-descriptions-item label="项ç®">{{ selectedTask.project }}</el-descriptions-item> <el-descriptions-item label="模å">{{ selectedTask.module }}</el-descriptions-item> <el-descriptions-item label="ç¶æ"> <el-tag :type="getStatusType(selectedTask.status)">{{ selectedTask.status }}</el-tag> </el-descriptions-item> <el-descriptions-item label="å¼å§æ¶é´">{{ selectedTask.startTime }}</el-descriptions-item> <el-descriptions-item label="ç»ææ¶é´">{{ selectedTask.endTime || '-' }}</el-descriptions-item> <el-descriptions-item label="èæ¶">{{ selectedTask.duration || '-' }}</el-descriptions-item> <el-descriptions-item label="æ§è¡äºº">{{ selectedTask.operator || '-' }}</el-descriptions-item> </el-descriptions> <div class="task-timeline"> <h4>任塿µè½¬æ¶é´çº¿</h4> <el-timeline> <el-timeline-item v-for="(event, index) in currentTaskDetail.timeline" :key="index" :timestamp="event.time" :type="event.status" :color="getStatusColor(event.status)"> {{ event.desc }} <el-timeline-item v-for="(activity, index) in selectedTask.timeline" :key="index" :timestamp="activity.timestamp"> {{ activity.content }} </el-timeline-item> </el-timeline> </div> </div> </el-dialog> <!-- 模åç¶æå¼¹çª --> <el-dialog title="模åç¶æ" :visible.sync="moduleStatusDialogVisible" width="50%"> <div class="status-container"> <el-table :data="moduleStatusData" style="width: 100%" border stripe> <el-table-column prop="module" label="模ååç§°"></el-table-column> <el-table-column prop="status" label="ç¶æ" width="100"> <template slot-scope="scope"> <el-tag :type="getStatusType(scope.row.status)">{{ scope.row.status }}</el-tag> </template> </el-table-column> <el-table-column prop="lastUpdate" label="æåæ´æ°"></el-table-column> <el-table-column label="æä½" width="120"> <template slot-scope="scope"> <el-button size="mini" @click="checkModuleStatus(scope.row)">æ£æ¥ç¶æ</el-button> </template> </el-table-column> </el-table> </div> </el-dialog> </div> </template> <script> // èæ¬é¨åä¿æä¸å import axios from 'axios' import * as XLSX from 'xlsx' import { ElMessage, ElMessageBox } from 'element-plus' export default { name: 'Test', data() { return { // 模åéæ©ååæ®µé ç½® selectedModule: 'gantryStorage', allFields: [ { label: 'èæºç¶æ', value: 'onlineStatus', isSystem: false }, { label: 'PLC请æ±å', value: 'plcRequest', isSystem: false }, { label: 'PLCæ±æ¥å', value: 'plcReport', isSystem: false }, { label: '宿1A', value: 'complete1A', isSystem: false }, { label: '宿1B', value: 'complete1B', isSystem: false }, { label: 'ä»»å¡ç¶æ', value: 'taskStatus', isSystem: true }, { label: 'ç©¿æ¢è½¦/天车ä½ç½®', value: 'shuttlePosition', isSystem: false }, { label: 'å¸ç/å°è½¦ä½ç½®', value: 'suctionPosition', isSystem: false }, { label: 'MESä»»å¡åéå', value: 'mesSend', isSystem: true }, { label: 'MESä»»å¡ç¡®è®¤å', value: 'mesConfirm', isSystem: true }, { label: 'èµ·å§', value: 'start', isSystem: true }, { label: 'ç®æ ', value: 'target', isSystem: true }, { label: 'ç»çæ°é', value: 'glassCount', isSystem: false }, { label: '1å·è¾¹è·', value: 'edge1Margin', isSystem: false }, { label: '1å·é¿è¾¹', value: 'edge1Long', isSystem: false }, { label: '1å·çè¾¹', value: 'edge1Short', isSystem: false }, { label: '1å·å', value: 'edge1Thick', isSystem: false }, { label: '2å·è¾¹è·', value: 'edge2Margin', isSystem: false }, { label: '2å·é¿è¾¹', value: 'edge2Long', isSystem: false }, { label: '2å·çè¾¹', value: 'edge2Short', isSystem: false }, { label: '2å·å', value: 'edge2Thick', isSystem: false }, { label: 'æ¥è¦ä¿¡å·', value: 'alarm', isSystem: true } ], checkedFields: [], selectedProject: 'default', // é»è®¤é¡¹ç® selectedModule: '', checkedFields: ['onlineState', 'plcRequest'], projectList: [], availableModules: ['gantryStorage', 'upperModule', 'storageModule'], fieldDbIndexes: {}, allFields: [], // æµè¯åæ°é ç½® // æµè¯åæ° testParameters: { start: 1, target: 5, retryCount: 2, plcAddress: '192.168.10.21', dbAddress: 'DB38', retryCount: 3, interval: 1000, failureRate: 0 failureRate: 5, timeout: 30 }, // æ¹éæµè¯ç¸å ³ showBatchTestConfig: false, // æ¹éæµè¯ batchTasks: [], showBatchTestConfig: false, // ä»»å¡åç»æ // ä»»å¡çæ§ runningTasks: [], taskCount: { total: 0, pass: 0, fail: 0 }, testResults: [], taskCount: { total: 0, pass: 0, fail: 0 }, // å¼¹çªç¶æ importDialogVisible: false, statusDialogVisible: false, moduleStatusVisible: false, taskDetailVisible: false, importFile: null, currentTaskDetail: null, // 模åç¶æç¸å ³ activeStatusTab: 'gantryStorage', statusTableData: [], // æä»¶ä¸ä¼ uploadFile: null, // å½åä»»å¡è¯¦æ currentTaskDetail: {}, // 宿¶å¨ statusTimer: null, testTimer: null, // æ¾ç¤ºé误å // ç³»ç»å段ï¼ä¸å¯åæ¶å¾éï¼ systemFields: ['onlineState', 'plcRequest', 'taskId'], // å¼¹çªç¶æ batchTestDialogVisible: false, taskDetailDialogVisible: false, moduleStatusDialogVisible: false, // æ¹éæµè¯è¡¨å batchTestForm: { projectIds: [], modules: [], selectedFields: [] }, // 任塿°æ® currentTasks: [], selectedTask: null, testStats: { total: 0, passed: 0, failed: 0, running: 0 }, moduleStatusData: [], // é误信æ¯åæ¾ç¤ºæ§å¶ showErrorColumn: false }; }, computed: { // 夿é ç½®æ¯å¦åå¤å°±ç»ª // æ£æ¥é ç½®æ¯å¦åå¤å°±ç»ª isConfigReady() { return this.checkedFields.length > 0; return this.selectedModule && this.checkedFields.length > 0; } }, mounted() { // åå§åæ¶è®¾ç½®é»è®¤å段 this.setDefaultFieldsByModule(this.selectedModule); // å è½½æ¬å°åå¨çé ç½® this.loadLocalConfig(); // 页é¢å è½½æ¶è·å项ç®å表 this.fetchProjectList(); // å è½½ä¿åçé ç½® this.loadConfig(); // å¯å¨ç¶æçæ§ this.startStatusMonitoring(); }, beforeUnmount() { // æ¸ ç宿¶å¨ if (this.statusTimer) { clearInterval(this.statusTimer); } if (this.testTimer) { clearInterval(this.testTimer); } }, methods: { // 模å忢æ¶è®¾ç½®é»è®¤å段 handleModuleChange(module) { this.setDefaultFieldsByModule(module); }, // æ ¹æ®æ¨¡å设置é»è®¤å段 setDefaultFieldsByModule(module) { if (module === 'gantryStorage') { this.checkedFields = this.allFields.map(field => field.value); } else if (module === 'shuttle') { this.checkedFields = [ 'onlineStatus', 'plcRequest', 'plcReport', 'taskStatus', 'mesSend', 'mesConfirm', 'start', 'target', 'alarm' ]; } else if (module === 'upperModule') { this.checkedFields = [ 'onlineStatus', 'plcRequest', 'plcReport', 'taskStatus', 'mesSend', 'mesConfirm', 'start', 'target', 'alarm', 'complete1A', 'complete1B', 'glassCount' ]; } else if (module === 'storageModule') { this.checkedFields = [ 'onlineStatus', 'plcRequest', 'plcReport', 'taskStatus', 'mesSend', 'mesConfirm', 'start', 'target', 'alarm', 'shuttlePosition', 'suctionPosition' ]; // è·å项ç®å表 async fetchProjectList() { try { const response = await axios.get('/api/plcSend/address-mapping/list'); if (response.data && response.data.code === 200) { this.projectList = response.data.data.map(item => ({ value: item.projectId, label: item.projectName || item.projectId, plcIp: item.plcIp, dbArea: item.dbArea, addressMapping: item.addressMapping, remarks: item.remarks })); // 妿å½åéæ©ç项ç®ä¸å¨å表ä¸ï¼è®¾ç½®ä¸ºç¬¬ä¸ä¸ªé¡¹ç® if (this.projectList.length > 0 && !this.projectList.find(p => p.value === this.selectedProject)) { this.selectedProject = this.projectList[0].value; this.handleProjectChange(); } } else { ElMessage.error('è·å项ç®å表失败'); } } catch (error) { console.error('è·å项ç®å表失败:', error); ElMessage.error('è·å项ç®å表失败'); } }, // 夿æ¯å¦ä¸ºç³»ç»çº§å¿ éåæ®µ isSystemField(fieldValue) { return this.allFields.find(item => item.value === fieldValue)?.isSystem || false; }, // å¯¼å ¥æµè¯ä»»å¡ importTask() { this.importDialogVisible = true; }, // æä»¶ä¸ä¼ åæ£æ¥ beforeFileUpload(file) { const isExcel = file.type === 'application/vnd.ms-excel' || file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; const isJson = file.type === 'application/json'; const isLt5M = file.size / 1024 / 1024 < 5; if (!isExcel && !isJson) { this.$message.error('ä¸ä¼ æä»¶åªè½æ¯ Excel æ JSON æ ¼å¼!'); return false; } if (!isLt5M) { this.$message.error('ä¸ä¼ æä»¶å¤§å°ä¸è½è¶ è¿ 5MB!'); return false; } return true; }, // æä»¶æ¹åå¤ç handleFileChange(file) { this.importFile = file.raw; }, // ç¡®è®¤å¯¼å ¥ confirmImport() { if (!this.importFile) { this.$message.warning('请å éæ©æä»¶'); // å¤ç项ç®åæ´ async handleProjectChange() { // ç¡®ä¿projectListåå¨ä¸ä¸æ¯ç©ºæ°ç» if (!this.projectList || this.projectList.length === 0) { console.log('项ç®å表æªå è½½'); return; } // 模ææä»¶è§£æé»è¾ const reader = new FileReader(); reader.onload = (e) => { try { // æ ¹æ®æä»¶ç±»åè§£æ if (this.importFile.name.endsWith('.json')) { const data = JSON.parse(e.target.result); if (data.batchTasks) { this.batchTasks = data.batchTasks; this.showBatchTestConfig = true; this.$message.success('æ¹éæµè¯ä»»å¡å¯¼å ¥æå'); } else if (data.testParameters) { this.testParameters = data.testParameters; this.$message.success('æµè¯åæ°é ç½®å¯¼å ¥æå'); const project = this.projectList.find(p => p.value === this.selectedProject); if (project) { // æ´æ°PLCå°ååDBå this.testParameters.plcAddress = project.plcIp || 'null'; this.testParameters.dbAddress = project.dbArea || 'null'; this.selectedModule = project.remarks || 'null'; // è·å宿´ç项ç®é ç½®ï¼å å«å°åæ å°ï¼ if (this.selectedProject && this.selectedProject !== 'default') { try { const response = await axios.get(`/api/plcSend/address-mapping/project/config?projectId=${this.selectedProject}`); if (response.data && response.data.code === 200 && response.data.data) { const projectConfig = response.data.data; // 使ç¨å®æ´çå°åæ å°æ´æ°å段é ç½® if (projectConfig.addressMapping) { this.updateFieldAddresses(projectConfig.addressMapping); } } else { console.error('è·å项ç®é 置失败:', response.data?.message); // åéå°ä½¿ç¨é¡¹ç®å表ä¸çå°åæ å° if (project.addressMapping) { try { const addressMapping = JSON.parse(project.addressMapping); this.updateFieldAddresses(addressMapping); } catch (e) { console.error('è§£æå°åæ å°å¤±è´¥:', e); } } } } else { // 对äºExcelæä»¶ï¼å¯ä»¥ä½¿ç¨xlsxåºè§£æ this.$message.success('Excelæä»¶å¯¼å ¥æåï¼å®é 项ç®ä¸éè¦æ·»å è§£æé»è¾ï¼'); } catch (error) { console.error('è·å项ç®é 置失败:', error); // åéå°ä½¿ç¨é¡¹ç®å表ä¸çå°åæ å° if (project.addressMapping) { try { const addressMapping = JSON.parse(project.addressMapping); this.updateFieldAddresses(addressMapping); } catch (e) { console.error('è§£æå°åæ å°å¤±è´¥:', e); } } } } catch (error) { this.$message.error('æä»¶è§£æå¤±è´¥: ' + error.message); } else { // 对äºé»è®¤é¡¹ç®ï¼ä½¿ç¨é¡¹ç®å表ä¸çå°åæ å° if (project.addressMapping) { try { const addressMapping = JSON.parse(project.addressMapping); this.updateFieldAddresses(addressMapping); } catch (e) { console.error('è§£æå°åæ å°å¤±è´¥:', e); } } } }; reader.readAsText(this.importFile); } else { console.log('æªæ¾å°éä¸ç项ç®:', this.selectedProject); } this.importDialogVisible = false; // æ¸ ç©ºå½åä»»å¡ç¶æ this.runningTasks = []; this.testResults = []; this.updateTaskCount(); }, // æ´æ°å段å°å updateFieldAddresses(addressMapping) { // åæ®µåå°ä¸ææ ç¾çæ å°å ³ç³» const fieldLabels = { 'onlineState': 'èæºç¶æ', 'plcRequest': 'PLC请æ±', 'plcReport': 'PLCæ±æ¥', 'finishA': 'å®æä¿¡å·A', 'finishB': 'å®æä¿¡å·B', 'state': '设å¤ç¶æ', 'onePosition': 'ä¸å·ä½ç½®', 'twoPosition': 'äºå·ä½ç½®', 'mesSend': 'MESåé', 'mesConfirm': 'MES确认', 'start': 'èµ·å§ä½ç½®', 'target': 'ç®æ ä½ç½®', 'mesGlassCount': 'ç»çæ°é', 'rawMargin1': 'åçè¾¹è·1', 'mesWidth1': 'ç»ç宽度1', 'mesHeight1': 'ç»çé«åº¦1', 'rawThickness1': 'ç»çå度1', 'rawMargin2': 'åçè¾¹è·2', 'mesWidth2': 'ç»ç宽度2', 'mesHeight2': 'ç»çé«åº¦2', 'rawThickness2': 'ç»çå度2', 'alarmInfo': 'æ¥è¦ä¿¡æ¯' }; // æ ¹æ®addressMapping卿çæallFieldsæ°ç» const newFields = []; // éåaddressMappingï¼çææ°çåæ®µå表 for (const [fieldName, address] of Object.entries(addressMapping)) { newFields.push({ label: fieldLabels[fieldName] || fieldName, // ä½¿ç¨æ å°ç䏿æ ç¾ï¼å¦ææ²¡æå使ç¨å段å value: fieldName, address: address }); } // æ´æ°allFields this.allFields = newFields; // 妿æ¯ç¬¬ä¸æ¬¡å è½½ï¼é»è®¤éä¸ç³»ç»å ³é®å段 if (!this.checkedFields || this.checkedFields.length === 0 || this.checkedFields.includes('')) { this.checkedFields = ['onlineState', 'plcRequest']; } }, // å¤ç模ååæ´ handleModuleChange() { // æ ¹æ®æ¨¡åç±»å设置é»è®¤å段 if (this.selectedModule === 'gantryStorage') { this.checkedFields = ['onlineState', 'plcRequest', 'taskId', 'startPos', 'targetPos', 'deviceStatus']; } else if (this.selectedModule === 'upperModule') { this.checkedFields = ['onlineState', 'plcRequest', 'taskId', 'runMode', 'errorCode', 'currentSpeed']; } else if (this.selectedModule === 'storageModule') { this.checkedFields = ['onlineState', 'plcRequest', 'taskId', 'currentPos', 'taskStatus', 'completion']; } }, // 夿æ¯å¦ä¸ºç³»ç»å段 isSystemField(field) { return this.systemFields.includes(field); }, // æ·»å æ°å段 addNewField() { ElMessageBox.prompt('请è¾å ¥æ°å段åç§°', 'æ·»å åæ®µ', { confirmButtonText: 'ç¡®å®', cancelButtonText: 'åæ¶', inputPattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, inputErrorMessage: 'åæ®µåç§°å¿ é¡»ä»¥åæ¯å¼å¤´ï¼åªè½å å«åæ¯ãæ°ååä¸å线' }).then(({ value }) => { // æ£æ¥å段æ¯å¦å·²åå¨ if (this.allFields.find(f => f.value === value)) { ElMessage.warning('åæ®µå·²åå¨'); return; } // æ·»å æ°å段 this.allFields.push({ label: value, value: value, address: 0, system: false }); ElMessage.success('åæ®µæ·»å æå'); }).catch(() => { // ç¨æ·åæ¶ }); }, // å é¤å段 removeField(field) { if (this.isSystemField(field)) { ElMessage.warning('ç³»ç»å段ä¸è½å é¤'); return; } ElMessageBox.confirm(`ç¡®å®è¦å é¤å段 "${field}" åï¼`, 'æç¤º', { confirmButtonText: 'ç¡®å®', cancelButtonText: 'åæ¶', type: 'warning' }).then(() => { // ä»allFieldsä¸ç§»é¤ this.allFields = this.allFields.filter(f => f.value !== field); // ä»checkedFieldsä¸ç§»é¤ this.checkedFields = this.checkedFields.filter(f => f !== field); ElMessage.success('åæ®µå 餿å'); }).catch(() => { // ç¨æ·åæ¶ }); }, // æ´æ°å段å°å updateFieldAddress(field, address) { const fieldIndex = this.allFields.findIndex(f => f.value === field); if (fieldIndex !== -1) { this.allFields[fieldIndex].address = parseInt(address) || 0; } }, // ä¿åå½åé ç½® async saveCurrentConfig() { try { // æå»ºå°åæ å°JSON const addressMapping = {}; this.allFields.forEach(field => { if (field.address !== undefined) { addressMapping[field.value] = field.address; } }); // ä¿åå°æ¬å°åå¨ localStorage.setItem('plcTestConfig', JSON.stringify({ selectedProject: this.selectedProject, selectedModule: this.selectedModule, checkedFields: this.checkedFields, testParameters: this.testParameters, allFields: this.allFields })); // åªæå½selectedProject䏿¯'default'æ¶æè°ç¨API if (this.selectedProject && this.selectedProject !== 'default') { // å夿´æ°æ°æ® const updateData = { projectId: this.selectedProject, plcIp: this.testParameters.plcAddress, dbArea: this.testParameters.dbAddress, addressMapping: JSON.stringify(addressMapping) }; // è°ç¨APIæ´æ°é ç½® const response = await axios.put(`/api/plcSend/address-mapping/project/${this.selectedProject}`, updateData); if (response.data && response.data.code === 200) { ElMessage.success('é ç½®ä¿åæå'); } else { ElMessage.error('é ç½®ä¿å失败'); } } else { // 妿æ¯é»è®¤é¡¹ç®ï¼åªä¿åå°æ¬å° ElMessage.success('é 置已ä¿åå°æ¬å°'); } } catch (error) { console.error('ä¿åé 置失败:', error); ElMessage.error('é ç½®ä¿å失败'); } }, // å è½½é ç½® loadConfig() { const savedConfig = localStorage.getItem('plcTestConfig'); if (savedConfig) { try { const config = JSON.parse(savedConfig); this.selectedProject = config.selectedProject || 'default'; this.selectedModule = config.selectedModule || 'gantryStorage'; this.checkedFields = config.checkedFields || ['onlineState', 'plcRequest', 'taskId']; this.testParameters = { ...this.testParameters, ...config.testParameters }; if (config.allFields) { this.allFields = config.allFields; } } catch (e) { console.error('å è½½é 置失败:', e); } } }, // éç½®é ç½® resetAll() { ElMessageBox.confirm('ç¡®å®è¦éç½®ææé ç½®åï¼', 'æç¤º', { confirmButtonText: 'ç¡®å®', cancelButtonText: 'åæ¶', type: 'warning' }).then(() => { // éç½®æ°æ® this.selectedProject = 'default'; this.selectedModule = 'gantryStorage'; this.checkedFields = ['onlineState', 'plcRequest', 'taskId']; this.testParameters = { plcAddress: '192.168.10.21', dbAddress: 'DB38', retryCount: 3, interval: 1000, failureRate: 5 }; // æ¸ ç©ºä»»å¡ this.runningTasks = []; this.testResults = []; this.batchTasks = []; this.updateTaskCount(); // æ¸ é¤æ¬å°åå¨ localStorage.removeItem('plcTestConfig'); ElMessage.success('é 置已éç½®'); }).catch(() => { // ç¨æ·åæ¶ }); }, // å¼å§æµè¯ startTest() { const moduleMap = { gantryStorage: 'é¾é¨ä»å¨', upperModule: 'ä¸ç模å', storageModule: 'ç©¿æ¢ä»å¨' }; const moduleName = moduleMap[this.selectedModule]; async startTest() { if (!this.isConfigReady) { ElMessage.warning('请å 宿é ç½®'); return; } // å建æ°ä»»å¡ const taskId = Date.now(); const task = { id: taskId, module: moduleName, moduleKey: this.selectedModule, startTime: new Date().toLocaleString(), timeline: [ { time: new Date().toLocaleTimeString(), status: 'primary', desc: 'æµè¯ä»»å¡å¯å¨' }, { time: new Date().toLocaleTimeString(), status: 'primary', desc: 'å¼å§åå§åæµè¯ç¯å¢' } ] }; this.runningTasks.push(task); const startTime = Date.now(); // åå¤ä»»å¡æ°æ® const taskData = { // åºç¡å段 mesSend: 1, mesConfirm: 0, plcRequest: 0, taskStatus: 0, // 卿忰 start: this.testParameters.start, target: this.testParameters.target }; // è°ç¨å端API this.$axios.post(`/api/plc/operation/execute/${this.selectedModule}`, taskData) .then(response => { const result = response.data; const timeline = this.runningTasks.find(t => t.id === taskId).timeline; try { // æå»ºæµè¯åæ° const testParams = { projectId: this.selectedProject, module: this.selectedModule, fields: this.checkedFields, parameters: this.testParameters }; // è°ç¨æµè¯API const response = await axios.post(`/api/plcSend/test/execute/${this.selectedModule}`, testParams); if (response.data && response.data.code === 200) { const taskId = response.data.data.taskId; timeline.push({ time: new Date().toLocaleTimeString(), status: 'success', desc: 'PLC请æ±åéæå' // æ·»å å°è¿è¡ä»»å¡å表 this.runningTasks.push({ id: taskId, module: this.selectedModule, project: this.selectedProject, status: 'running', startTime: new Date().toLocaleTimeString(), timeline: [ { time: new Date().toLocaleTimeString(), desc: 'ä»»å¡å·²æäº¤', status: 'primary' } ] }); // 模æä»»å¡æ§è¡ï¼å®é 项ç®ä¸å¯è½éè¦è½®è¯¢æWebSocketï¼ setTimeout(() => { // æ ¹æ®é ç½®çæ éæ¦çæ¨¡æå¤±è´¥æ åµ const shouldFail = Math.random() * 100 < this.testParameters.failureRate; ElMessage.success('æµè¯ä»»å¡å·²æäº¤'); // å¼å§çæ§ä»»å¡ç¶æ this.monitorTask(taskId); } else { ElMessage.error('æäº¤æµè¯ä»»å¡å¤±è´¥'); } } catch (error) { console.error('æäº¤æµè¯ä»»å¡å¤±è´¥:', error); ElMessage.error('æäº¤æµè¯ä»»å¡å¤±è´¥'); } }, // çæ§ä»»å¡ç¶æ async monitorTask(taskId) { const checkStatus = async () => { try { const response = await axios.get(`/api/plcSend/test/status/${this.selectedModule}?taskId=${taskId}`); if (response.data && response.data.code === 200) { const taskData = response.data.data; const taskIndex = this.runningTasks.findIndex(t => t.id === taskId); if (!shouldFail && result.success) { timeline.push({ if (taskIndex !== -1) { // æ´æ°ä»»å¡ç¶æ this.runningTasks[taskIndex].status = taskData.status; // æ·»å ç¶æååäºä»¶ this.runningTasks[taskIndex].timeline.push({ time: new Date().toLocaleTimeString(), status: 'success', desc: '任塿§è¡å®æ' desc: `ç¶ææ´æ°: ${taskData.status}`, status: taskData.status === 'success' ? 'success' : taskData.status === 'failed' ? 'danger' : 'primary' }); // æ´æ°æµè¯ç»æ this.updateTestResults(taskId, moduleName, 'éè¿', '', startTime, 0); } else { const errorMsg = 'æ¨¡ææ éåç'; timeline.push({ time: new Date().toLocaleTimeString(), status: 'error', desc: `任塿§è¡å¤±è´¥: ${errorMsg}` }); // æ´æ°æµè¯ç»æ this.updateTestResults(taskId, moduleName, '失败', errorMsg, startTime, 0); // 妿任å¡å®æï¼æ·»å å°ç»æå表 if (taskData.status === 'success' || taskData.status === 'failed') { this.testResults.push({ id: taskId, module: this.selectedModule, project: this.selectedProject, startTime: this.runningTasks[taskIndex].startTime, endTime: new Date().toLocaleTimeString(), status: taskData.status === 'success' ? 'éè¿' : '失败', duration: taskData.duration || 0, retryCount: taskData.retryCount || 0, errorMsg: taskData.errorMsg || '' }); // æ´æ°ä»»å¡è®¡æ° this.updateTaskCount(); // ä»è¿è¡ä»»å¡å表ä¸ç§»é¤ this.runningTasks.splice(taskIndex, 1); // æ¾ç¤ºé误信æ¯åï¼å¦ææéè¯¯ï¼ if (taskData.errorMsg) { this.showErrorColumn = true; } } else { // ç»§ç»çæ§ setTimeout(checkStatus, 2000); } } // ä»è¿è¡ä»»å¡å表ä¸ç§»é¤ this.removeRunningTask(taskId); }, this.testParameters.interval); }) .catch(error => { const timeline = this.runningTasks.find(t => t.id === taskId).timeline; timeline.push({ time: new Date().toLocaleTimeString(), status: 'error', desc: `APIè°ç¨å¤±è´¥: ${error.message || 'ç½ç»é误'}` }); // æ´æ°æµè¯ç»æ this.updateTestResults(taskId, moduleName, '失败', error.message || 'ç½ç»é误', startTime, 0); // ä»è¿è¡ä»»å¡å表ä¸ç§»é¤ this.removeRunningTask(taskId); }); } } catch (error) { console.error('è·åä»»å¡ç¶æå¤±è´¥:', error); } }; // å¼å§æ£æ¥ç¶æ setTimeout(checkStatus, 1000); }, // æ¹éæµè¯ batchTest() { this.showBatchTestConfig = !this.showBatchTestConfig; this.showBatchTestConfig = true; }, // æ·»å å½åé ç½®å°æ¹éä»»å¡ addCurrentToBatch() { const batchTask = { module: this.selectedModule, start: this.testParameters.start, target: this.testParameters.target, retryCount: this.testParameters.retryCount }; this.batchTasks.push(batchTask); this.$message.success('已添å å°æ¹éæµè¯ä»»å¡'); }, // æ§è¡æ¹éæµè¯ startBatchTest() { if (this.batchTasks.length === 0) { this.$message.warning('è¯·å æ·»å æ¹éæµè¯ä»»å¡'); if (!this.isConfigReady) { ElMessage.warning('请å 宿é ç½®'); return; } // é个æ§è¡æ¹éä»»å¡ this.batchTasks.forEach((task, index) => { setTimeout(() => { this.selectedModule = task.module; this.testParameters.start = task.start; this.testParameters.target = task.target; this.testParameters.retryCount = task.retryCount; this.startTest(); }, index * (this.testParameters.interval + 1000)); this.batchTasks.push({ module: this.selectedModule, project: this.selectedProject, start: this.testParameters.startPos || 0, target: this.testParameters.targetPos || 0, retryCount: this.testParameters.retryCount }); this.$message.success(`æ¹éæµè¯å·²å¯å¨ï¼å ±${this.batchTasks.length}个任å¡`); ElMessage.success('已添å å°æ¹éä»»å¡å表'); }, // å¼å§æ¹éæµè¯ async startBatchTest() { if (this.batchTasks.length === 0) { ElMessage.warning('æ¹éä»»å¡å表为空'); return; } try { // è°ç¨æ¹éæµè¯API const response = await axios.post('/api/plcSend/test/batch', { tasks: this.batchTasks }); if (response.data && response.data.code === 200) { ElMessage.success('æ¹éæµè¯å·²æäº¤'); this.showBatchTestConfig = false; // æ·»å å°è¿è¡ä»»å¡å表 response.data.data.taskIds.forEach((taskId, index) => { this.runningTasks.push({ id: taskId, module: this.batchTasks[index].module, project: this.batchTasks[index].project, status: 'running', startTime: new Date().toLocaleTimeString(), timeline: [ { time: new Date().toLocaleTimeString(), desc: 'æ¹éä»»å¡å·²æäº¤', status: 'primary' } ] }); // çæ§ä»»å¡ç¶æ this.monitorTask(taskId); }); } else { ElMessage.error('æäº¤æ¹éæµè¯å¤±è´¥'); } } catch (error) { console.error('æäº¤æ¹éæµè¯å¤±è´¥:', error); ElMessage.error('æäº¤æ¹éæµè¯å¤±è´¥'); } }, // ç§»é¤æ¹éä»»å¡ @@ -553,175 +901,150 @@ this.batchTasks.splice(index, 1); }, // æ´æ°æµè¯ç»æ updateTestResults(taskId, moduleName, status, errorMsg, startTime, retryCount) { const endTime = new Date(); const duration = Math.round((endTime.getTime() - startTime) / 1000); // å¯¼å ¥ä»»å¡ importTask() { this.importDialogVisible = true; }, // å¤çæä»¶åå handleFileChange(file) { this.uploadFile = file.raw; }, // æä»¶ä¸ä¼ åæ£æ¥ beforeFileUpload(file) { const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type === 'application/vnd.ms-excel'; const isJSON = file.type === 'application/json'; const isLt5M = file.size / 1024 / 1024 < 5; this.testResults.push({ id: taskId, module: moduleName, startTime: new Date(startTime).toLocaleString(), endTime: endTime.toLocaleString(), status: status, duration: duration, retryCount: retryCount, errorMsg: errorMsg, timeline: this.runningTasks.find(t => t.id === taskId)?.timeline || [] }); if (!isExcel && !isJSON) { ElMessage.error('åªè½ä¸ä¼ ExcelæJSONæ ¼å¼æä»¶!'); } if (!isLt5M) { ElMessage.error('æä»¶å¤§å°ä¸è½è¶ è¿5MB!'); } return (isExcel || isJSON) && isLt5M; }, // ç¡®è®¤å¯¼å ¥ async confirmImport() { if (!this.uploadFile) { ElMessage.warning('请å éæ©æä»¶'); return; } // æ´æ°ç»è®¡æ°æ® this.taskCount.total++; if (status === 'éè¿') { this.taskCount.pass++; } else { this.taskCount.fail++; this.showErrorColumn = true; try { const formData = new FormData(); formData.append('file', this.uploadFile); const response = await axios.post('/api/plcSend/test/import', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); if (response.data && response.data.code === 200) { ElMessage.success('å¯¼å ¥æå'); this.importDialogVisible = false; // æ·»å å¯¼å ¥çä»»å¡å°æ¹éä»»å¡å表 if (response.data.data && response.data.data.tasks) { this.batchTasks = [...this.batchTasks, ...response.data.data.tasks]; } } else { ElMessage.error('å¯¼å ¥å¤±è´¥'); } } catch (error) { console.error('å¯¼å ¥å¤±è´¥:', error); ElMessage.error('å¯¼å ¥å¤±è´¥'); } }, // ä»è¿è¡ä»»å¡å表ä¸ç§»é¤ removeRunningTask(taskId) { const index = this.runningTasks.findIndex(t => t.id === taskId); if (index > -1) { this.runningTasks.splice(index, 1); // æ¾ç¤ºä»»å¡è¯¦æ showTaskDetail(task) { this.selectedTask = task; this.taskDetailDialogVisible = true; }, // æ¾ç¤ºæ¹éæµè¯å¼¹çª showBatchTestDialog() { this.batchTestDialogVisible = true; }, // æ¾ç¤ºå¯¼å ¥å¼¹çª showImportDialog() { this.importDialogVisible = true; }, // å¤çå¯¼å ¥æå handleImportSuccess(response) { if (response.data && response.data.code === 200) { ElMessage.success('æä»¶ä¸ä¼ æå'); // å¯ä»¥å¨è¿éå¤çä¸ä¼ æååçé»è¾ } }, // éç½®ææé ç½® resetAll() { this.$confirm('ç¡®å®è¦éç½®ææé ç½®åï¼è¿å°æ¸ é¤æææµè¯ç»æåè¿è¡ä¸çä»»å¡ã', 'æç¤º', { // æä»¶ä¸ä¼ åæ£æ¥ beforeUpload(file) { const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type === 'application/vnd.ms-excel'; const isJSON = file.type === 'application/json'; const isLt10M = file.size / 1024 / 1024 < 10; if (!isExcel && !isJSON) { ElMessage.error('åªè½ä¸ä¼ ExcelæJSONæ ¼å¼æä»¶!'); return false; } if (!isLt10M) { ElMessage.error('æä»¶å¤§å°ä¸è½è¶ è¿10MB!'); return false; } return true; }, // åæ¶æµè¯ stopTest() { ElMessageBox.confirm('ç¡®å®è¦åæ¢å½åæµè¯åï¼', 'æç¤º', { confirmButtonText: 'ç¡®å®', cancelButtonText: 'åæ¶', type: 'warning' }).then(() => { this.checkedFields = []; this.runningTasks = []; this.testResults = []; this.taskCount = { total: 0, pass: 0, fail: 0 }; this.showErrorColumn = false; this.setDefaultFieldsByModule(this.selectedModule); this.$message.success('ææé 置已éç½®'); }).catch(() => {}); }, // è·åæ¶é´çº¿ç¶æé¢è² getStatusColor(status) { const colorMap = { primary: 'blue', success: 'green', error: 'red', warning: 'orange' }; return colorMap[status] || 'blue'; }, // è·åäºä»¶å¾æ getEventIcon(status) { const iconMap = { primary: 'el-icon-loading', success: 'el-icon-circle-check', error: 'el-icon-circle-close', warning: 'el-icon-warning' }; return iconMap[status] || 'el-icon-information'; }, // 计ç®éè¿ç calculatePassRate() { if (this.taskCount.total === 0) return 0; return Math.round((this.taskCount.pass / this.taskCount.total) * 100); }, // ä¿åå½åé ç½® saveCurrentConfig() { const config = { selectedModule: this.selectedModule, checkedFields: this.checkedFields, testParameters: this.testParameters }; localStorage.setItem('plcTestConfig', JSON.stringify(config)); this.$message.success('é 置已ä¿å'); }, // å è½½æ¬å°é ç½® loadLocalConfig() { const config = localStorage.getItem('plcTestConfig'); if (config) { }).then(async () => { try { const parsedConfig = JSON.parse(config); this.selectedModule = parsedConfig.selectedModule || 'gantryStorage'; this.checkedFields = parsedConfig.checkedFields || []; this.testParameters = parsedConfig.testParameters || this.testParameters; this.$message.success('é 置已å è½½'); } catch (error) { console.error('å è½½é 置失败:', error); } } }, // æå¨å è½½é ç½® loadConfig() { this.loadLocalConfig(); }, // æ¾ç¤ºæ¨¡åç¶æ showModuleStatus() { this.statusDialogVisible = true; this.refreshModuleStatus(); }, // å¤çç¶ææ ç¾ç¹å» handleStatusTabClick(tab) { this.activeStatusTab = tab.name; this.refreshModuleStatus(); }, // å·æ°æ¨¡åç¶æ refreshModuleStatus() { this.$axios.get(`/api/plc/operation/status/${this.activeStatusTab}`) .then(response => { const statusData = response.data.data; this.statusTableData = []; // ä¿®æ¹ä¸ºä½¿ç¨è·¯å¾åæ°çæ¹å¼è°ç¨API const response = await axios.post(`/api/plcSend/test/stop/${this.selectedModule}`); if (statusData) { for (const [key, value] of Object.entries(statusData)) { this.statusTableData.push({ key: this.getFieldLabel(key) || key, value: value, updateTime: new Date().toLocaleTimeString() }); } if (response.data && response.data.success) { ElMessage.success('æµè¯å·²åæ¢'); // æ¸ ç©ºè¿è¡ä¸çä»»å¡ this.runningTasks = []; this.testStats.running = 0; } else { ElMessage.error('忢æµè¯å¤±è´¥'); } }) .catch(error => { this.$message.error('è·å模åç¶æå¤±è´¥: ' + error.message); }); } catch (error) { console.error('忢æµè¯å¤±è´¥:', error); ElMessage.error('忢æµè¯å¤±è´¥'); } }).catch(() => { // ç¨æ·åæ¶ }); }, // é置模åç¶æ resetModuleStatus() { this.$confirm('ç¡®å®è¦é置该模åç¶æåï¼', 'æç¤º', { confirmButtonText: 'ç¡®å®', cancelButtonText: 'åæ¶', type: 'warning' }).then(() => { this.$axios.post(`/api/plc/operation/reset/${this.activeStatusTab}`) .then(() => { this.$message.success('模åç¶æå·²éç½®'); this.refreshModuleStatus(); }) .catch(error => { this.$message.error('é置模åç¶æå¤±è´¥: ' + error.message); }); }).catch(() => {}); }, // è·ååæ®µæ ç¾ getFieldLabel(fieldValue) { const field = this.allFields.find(item => item.value === fieldValue); return field ? field.label : null; async resetModuleStatus() { try { const response = await axios.post(`/api/plcSend/test/reset/${this.selectedModule}`); if (response.data && response.data.code === 200) { ElMessage.success('模åç¶æå·²éç½®'); } else { ElMessage.error('é置模åç¶æå¤±è´¥'); } } catch (error) { console.error('é置模åç¶æå¤±è´¥:', error); ElMessage.error('é置模åç¶æå¤±è´¥'); } }, // æ¥çä»»å¡è¯¦æ @@ -731,207 +1054,635 @@ }, // éè¯ä»»å¡ retryTask(task) { // 妿任塿moduleKeyåæ®µï¼ä½¿ç¨å®ï¼å¦åæ ¹æ®æ¨¡ååç§°æ¨æ const moduleMap = { 'é¾é¨ä»å¨': 'gantryStorage', 'ä¸ç模å': 'upperModule', 'ç©¿æ¢ä»å¨': 'storageModule' async retryTask(task) { try { const response = await axios.post(`/api/plcSend/test/retry/${task.module}`, { taskId: task.id, projectId: task.project }); if (response.data && response.data.code === 200) { ElMessage.success('ä»»å¡éè¯å·²æäº¤'); // æ·»å å°è¿è¡ä»»å¡å表 this.runningTasks.push({ id: task.id, module: task.module, project: task.project, status: 'running', startTime: new Date().toLocaleTimeString(), timeline: [ { time: new Date().toLocaleTimeString(), desc: 'ä»»å¡éè¯å·²æäº¤', status: 'primary' } ] }); // çæ§ä»»å¡ç¶æ this.monitorTask(task.id); } else { ElMessage.error('ä»»å¡éè¯å¤±è´¥'); } } catch (error) { console.error('ä»»å¡éè¯å¤±è´¥:', error); ElMessage.error('ä»»å¡éè¯å¤±è´¥'); } }, // æ´æ°ä»»å¡è®¡æ° updateTaskCount() { this.taskCount.total = this.testResults.length; this.taskCount.pass = this.testResults.filter(r => r.status === 'éè¿').length; this.taskCount.fail = this.testResults.filter(r => r.status === '失败').length; }, // 计ç®éè¿ç calculatePassRate() { if (this.taskCount.total === 0) return 0; return Math.round((this.taskCount.pass / this.taskCount.total) * 100); }, // è·åç¶æé¢è² getStatusColor(status) { const colorMap = { 'primary': '#409EFF', 'success': '#67C23A', 'warning': '#E6A23C', 'danger': '#F56C6C', 'info': '#909399' }; this.selectedModule = task.moduleKey || moduleMap[task.module] || 'gantryStorage'; // éç½®åæ®µéæ© this.setDefaultFieldsByModule(this.selectedModule); // å¯å¨æµè¯ this.startTest(); return colorMap[status] || '#409EFF'; }, // è·åäºä»¶å¾æ getEventIcon(status) { const iconMap = { 'primary': 'el-icon-loading', 'success': 'el-icon-circle-check', 'warning': 'el-icon-warning', 'danger': 'el-icon-circle-close', 'info': 'el-icon-info' }; return iconMap[status] || 'el-icon-info'; }, // å¯å¨ç¶æçæ§ startStatusMonitoring() { // æ¯30ç§å·æ°ä¸æ¬¡ç¶æ this.statusTimer = setInterval(() => { this.refreshTasks(); this.refreshModuleStatus(); }, 30000); }, // å·æ°ä»»å¡å表 async refreshTasks() { try { // å端没æç´æ¥æä¾è·åææä»»å¡çæ¥å£ // è¿éä½¿ç¨æ¬å°æ°æ®æ¨¡æï¼å®é åºç¨ä¸å¯è½éè¦è°æ´å®ç°é»è¾ // æè å端éè¦æ°å¢ç¸åºæ¥å£ // const response = await axios.get('/api/plc/test/tasks'); // ä½¿ç¨æ¨¡ææ°æ® this.currentTasks = this.runningTasks; // æ´æ°ä»»å¡ç»è®¡ this.testStats.total = this.testResults.length; this.testStats.passed = this.testResults.filter(r => r.status === 'éè¿').length; this.testStats.failed = this.testResults.filter(r => r.status === '失败').length; this.testStats.running = this.currentTasks.length; } catch (error) { console.error('å·æ°ä»»å¡å表失败:', error); } }, // å·æ°æ¨¡åç¶æ async refreshModuleStatus() { try { // å端没æç´æ¥æä¾è·åæææ¨¡åç¶æçæ¥å£ // è¿éä½¿ç¨æ¬å°æ°æ®æ¨¡æï¼å®é åºç¨ä¸å¯è½éè¦è°æ´å®ç°é»è¾ // æè å端éè¦æ°å¢ç¸åºæ¥å£ // const response = await axios.get('/api/plc/test/modules/status'); // ä½¿ç¨æ¨¡ææ°æ®ä¿æç颿£å¸¸å·¥ä½ if (!this.moduleStatusData || this.moduleStatusData.length === 0) { // å¦ææ²¡ææ°æ®ï¼åå§åä¸äºæ¨¡ææ¨¡å this.moduleStatusData = [ { module: 'gantryStorage', status: 'idle', lastUpdate: new Date().toLocaleTimeString() }, { module: 'upperModule', status: 'idle', lastUpdate: new Date().toLocaleTimeString() }, { module: 'storageModule', status: 'idle', lastUpdate: new Date().toLocaleTimeString() } ]; } else { // æ´æ°ç°ææ¨¡åçæ¶é´æ³ this.moduleStatusData.forEach(module => { module.lastUpdate = new Date().toLocaleTimeString(); }); } } catch (error) { console.error('å·æ°æ¨¡åç¶æå¤±è´¥:', error); } }, // æ£æ¥æ¨¡åç¶æ async checkModuleStatus(module) { try { // ä¿®æ¹ä¸ºä½¿ç¨å端æä¾çreadPlcStatusæ¥å£ const response = await axios.get(`/api/plcSend/test/status?projectId=${module.module}`); // ç±äºæ¥å£è¿åçæ¯PlcBaseData对象èéç´æ¥çç¶æä¿¡æ¯ï¼éè¦è¿è¡éé const index = this.moduleStatusData.findIndex(m => m.module === module.module); if (index !== -1) { // å设onlineStateåæ®µè¡¨ç¤ºæ¨¡åæ¯å¦å¨çº¿ const status = response.data ? 'online' : 'offline'; this.moduleStatusData[index] = { ...this.moduleStatusData[index], status: status, lastUpdate: new Date().toLocaleTimeString(), details: response.data || {} }; ElMessage.success('模åç¶ææ´æ°æå'); } } catch (error) { console.error('æ£æ¥æ¨¡åç¶æå¤±è´¥:', error); ElMessage.error('æ£æ¥æ¨¡åç¶æå¤±è´¥'); } }, // è·åç¶æç±»å getStatusType(status) { const statusMap = { 'running': 'warning', 'success': 'success', 'éè¿': 'success', 'failed': 'danger', '失败': 'danger', 'online': 'success', 'offline': 'danger', 'idle': 'info' }; return statusMap[status] || 'primary'; }, // éç½®é ç½® resetConfig() { ElMessageBox.confirm('ç¡®å®è¦éç½®ææé ç½®åï¼', 'æç¤º', { confirmButtonText: 'ç¡®å®', cancelButtonText: 'åæ¶', type: 'warning' }).then(() => { this.resetAll(); }).catch(() => { // ç¨æ·åæ¶ }); } } }; </script> <style scoped> .auto-test-dashboard { .dashboard-container { height: 100vh; display: flex; flex-direction: column; background-color: #f5f7fa; overflow: hidden; } .header { .dashboard-header { background-color: #2c3e50; color: white; display: flex; justify-content: space-between; align-items: center; padding: 0 20px; background-color: #fff; border-bottom: 1px solid #eaecef; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); height: 60px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); flex-shrink: 0; } .header h1 { font-size: 20px; font-weight: 600; color: #303133; } .header-actions { .header-left h2 { margin: 0; font-size: 1.4rem; font-weight: 500; display: flex; gap: 10px; align-items: center; } .aside { background-color: #f5f7fa; border-right: 1px solid #eaecef; padding: 15px; overflow-y: auto; .header-left h2::before { content: "âï¸"; margin-right: 10px; } .main { padding: 20px; overflow: auto; flex: 1; } .mt-20 { margin-top: 20px; } .config-card, .batch-test-card, .timeline-section, .result-section { background-color: #fff; border-radius: 4px; padding: 20px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08); margin-bottom: 20px; } .section-title { font-size: 16px; font-weight: 600; color: #303133; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #ebeef5; } .field-checkbox-group { max-height: 200px; overflow-y: auto; padding: 5px 0; } .field-checkbox-group .el-checkbox { margin-bottom: 8px; display: block; } .parameter-form { margin-top: 15px; } .parameter-form .el-form-item { margin-bottom: 15px; } .test-actions, .batch-actions { .header-right { display: flex; gap: 10px; margin-top: 20px; gap: 12px; } .batch-actions { justify-content: flex-end; .header-right .el-button { transition: all 0.2s ease; } .timeline-container { max-height: 400px; overflow-y: auto; } .task-timeline { margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px dashed #ebeef5; } .task-timeline:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } .result-card { text-align: center; transition: all 0.3s; } .result-card:hover { .header-right .el-button:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } .result-item { .dashboard-content { display: flex; flex: 1; overflow: hidden; padding: 15px; gap: 15px; } .config-aside { background-color: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); padding: 15px; width: 400px; flex-shrink: 0; overflow-y: auto; } .monitor-main { background-color: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); padding: 20px; flex: 1; overflow-y: auto; } .config-section { margin-bottom: 20px; border-radius: 6px; border: none; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); transition: all 0.2s ease; } .config-section:hover { box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08); } .config-section h3 { margin-top: 0; margin-bottom: 15px; font-size: 16px; color: #303133; border-bottom: 1px solid #f0f0f0; padding-bottom: 10px; display: flex; align-items: center; } .config-section h3 i { margin-right: 8px; color: #409EFF; } .full-width { width: 100%; margin-bottom: 10px; } .monitor-section { height: 100%; } .section-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid #f0f0f0; } .label { .section-header h3 { margin: 0; font-size: 18px; color: #303133; display: flex; align-items: center; } .section-header h3 i { margin-right: 8px; color: #409EFF; } .section-actions { display: flex; gap: 10px; } .section-actions .el-button { transition: all 0.2s ease; } .section-actions .el-button:hover { transform: translateY(-2px); } .task-container, .result-container, .result-list { margin-bottom: 25px; } .task-container h4, .result-container h4, .result-list h4 { margin-bottom: 15px; font-size: 16px; color: #606266; font-weight: 500; display: flex; align-items: center; } .task-container h4::before, .result-container h4::before, .result-list h4::before { content: ""; display: inline-block; width: 4px; height: 16px; background-color: #409EFF; margin-right: 8px; border-radius: 2px; } .task-list { display: flex; flex-wrap: wrap; gap: 15px; } .task-item { display: flex; justify-content: space-between; align-items: center; padding: 12px 15px; background-color: #f9fafc; border-radius: 6px; border-left: 4px solid #409EFF; width: calc(50% - 7.5px); box-sizing: border-box; cursor: pointer; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); transition: all 0.2s ease; } .task-item:hover { background-color: #ecf5ff; transform: translateY(-2px); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1); } .task-info { display: flex; align-items: center; gap: 15px; flex-wrap: wrap; } .task-id { font-weight: 500; color: #303133; min-width: 60px; } .task-module, .task-project { color: #606266; font-size: 14px; background-color: rgba(144, 147, 153, 0.1); padding: 2px 8px; border-radius: 4px; } .value { .result-stats { display: flex; justify-content: space-between; margin-bottom: 15px; gap: 15px; } .stat-item { text-align: center; padding: 20px 15px; background-color: #f9fafc; border-radius: 6px; flex: 1; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); transition: all 0.2s ease; } .stat-item:hover { transform: translateY(-3px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } .stat-number { font-size: 28px; font-weight: 600; font-size: 18px; margin-bottom: 8px; transition: all 0.3s ease; } .success { color: #67c23a; .stat-item:hover .stat-number { transform: scale(1.05); } .error { color: #f56c6c; .stat-number.pass { color: #67C23A; } .result-table-container { margin-top: 20px; .stat-number.fail { color: #F56C6C; } .stat-label { font-size: 14px; color: #909399; text-transform: uppercase; letter-spacing: 0.5px; } .empty-state { padding: 40px 0; text-align: center; padding: 40px 20px; color: #909399; background-color: #f9fafc; border-radius: 6px; } .status-container { .empty-icon { font-size: 48px; margin-bottom: 15px; color: #dcdfe6; } .empty-text { font-size: 16px; } /* åæ®µç®¡çæ ·å¼ */ .field-container { max-height: 300px; overflow-y: auto; border: 1px solid #f0f0f0; border-radius: 6px; } .field-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 15px; background-color: #f5f7fa; border-bottom: 1px solid #f0f0f0; font-weight: 500; } .add-btn { color: #409EFF; transition: all 0.2s; } .add-btn:hover { color: #66b1ff; background-color: rgba(64, 158, 255, 0.1); } .field-list { padding: 10px; } .field-item { display: flex; align-items: center; padding: 10px 8px; border-bottom: 1px solid #f5f5f5; transition: background-color 0.2s; } .field-item:last-child { border-bottom: none; } .field-item:hover { background-color: #f9fafc; } .field-address { display: flex; align-items: center; margin-left: auto; margin-right: 10px; } .field-address-label { width: 70px; text-align: right; margin-right: 8px; font-size: 12px; color: #909399; } .remove-btn { color: #ff4949; opacity: 0.7; transition: all 0.2s; } .remove-btn:hover { color: #ff4949; opacity: 1; background-color: rgba(255, 73, 73, 0.1); } /* æ¹éæµè¯å¼¹çªæ ·å¼ */ .batch-test-container { max-height: 500px; overflow-y: auto; } .status-actions { display: flex; gap: 10px; .batch-actions { margin-bottom: 15px; } .batch-footer { margin-top: 20px; justify-content: flex-end; text-align: right; } .task-detail { max-height: 500px; /* ä»»å¡å¯¼å ¥å¼¹çªæ ·å¼ */ .import-footer { margin-top: 20px; text-align: right; } /* ä»»å¡è¯¦æ å¼¹çªæ ·å¼ */ .task-detail-container { max-height: 600px; overflow-y: auto; padding: 10px 0; } .detail-section { margin-bottom: 20px; .task-timeline { margin-top: 20px; border-top: 1px solid #f0f0f0; padding-top: 15px; } .detail-section h4 { margin-bottom: 10px; color: #303133; .task-timeline h4 { margin-bottom: 15px; font-size: 16px; color: #606266; } .dialog-footer { display: flex; justify-content: flex-end; /* ç¶æå¼¹çªæ ·å¼ */ .status-container { min-height: 200px; } /* è¡¨æ ¼æ ·å¼ä¼å */ .el-table { border-radius: 6px; overflow: hidden; } .el-table th { background-color: #f5f7fa; font-weight: 500; } .el-table--border th, .el-table--border td { border-right: 1px solid #f0f0f0; } .el-table--border::after, .el-table--group::after, .el-table::before { background-color: #f0f0f0; } /* æ»å¨æ¡ç¾å */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 4px; } ::-webkit-scrollbar-thumb { background: #dcdfe6; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: #c0c4cc; } </style>