Springboot整合JAVAFX
实体与VO设计
pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.elitedatai</groupId>
<artifactId>javafxTest</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<javafx.version>21</javafx.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- javaFX -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<!-- JavaFX Maven Plugin -->
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>com.elitedatai.MainApp</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
实体类设计:
package com.elitedatai.model;
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author llg
* @slogan 致敬大师,致敬未来的你
* @create 2025-04-10 15:57
*/
@Data
@Table(name = "Work_Order")
@Entity
public class WorkOrder {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 50)
private String orderNo; // 工单编号
@Column(nullable = false, length = 100)
private String productName; // 产品名称
@Column(nullable = false, length = 50)
private String productCode; // 产品编码
@Column(nullable = false)
private Integer plannedQuantity; // 计划数量
@Column(nullable = false)
private Integer completedQuantity = 0; // 已完成数量
@Column(nullable = false)
private LocalDateTime startTime; // 计划开始时间
@Column(nullable = false)
private LocalDateTime endTime; // 计划结束时间
@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 20)
private OrderStatus status; // 工单状态
@Column(length = 500)
private String remark; // 备注
// 工单状态枚举
public enum OrderStatus {
PENDING, // 待开始
IN_PROGRESS, // 进行中
PAUSED, // 已暂停
COMPLETED, // 已完成
CANCELLED // 已取消
}
}
VO类设计:
/**
* 工单值对象 - 用于前后端数据传输
* 这个类可以被Spring MVC和JavaFX共同使用
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class WorkOrderVO {
private Long id;
private String orderNo;
private String productName;
private String productCode;
private Integer plannedQuantity;
private Integer completedQuantity;
private LocalDateTime startTime;
private LocalDateTime endTime;
private WorkOrder.OrderStatus status;
private String remark;
// 计算进度百分比
public Double getProgress() {
if (plannedQuantity == null || plannedQuantity == 0) {
return 0.0;
}
return (completedQuantity.doubleValue() / plannedQuantity.doubleValue()) * 100;
}
// 从实体类转换
public static WorkOrderVO fromEntity(WorkOrder entity) {
if (entity == null) return null;
WorkOrderVO vo = new WorkOrderVO();
vo.setId(entity.getId());
vo.setOrderNo(entity.getOrderNo());
vo.setProductName(entity.getProductName());
vo.setProductCode(entity.getProductCode());
vo.setPlannedQuantity(entity.getPlannedQuantity());
vo.setCompletedQuantity(entity.getCompletedQuantity());
vo.setStartTime(entity.getStartTime());
vo.setEndTime(entity.getEndTime());
vo.setStatus(entity.getStatus());
vo.setRemark(entity.getRemark());
return vo;
}
// 转换为实体类
public WorkOrder toEntity() {
WorkOrder entity = new WorkOrder();
entity.setId(this.getId());
entity.setOrderNo(this.getOrderNo());
entity.setProductName(this.getProductName());
entity.setProductCode(this.getProductCode());
entity.setPlannedQuantity(this.getPlannedQuantity());
entity.setCompletedQuantity(this.getCompletedQuantity());
entity.setStartTime(this.getStartTime());
entity.setEndTime(this.getEndTime());
entity.setStatus(this.getStatus());
entity.setRemark(this.getRemark());
return entity;
}
}
SpringBoot与JavaFX集成配置
JavaFX配置类 (JavaFXConfiguration.java)
package com.elitedatai.config;
/**
* @author llg
* @slogan 致敬大师,致敬未来的你
* @create 2025-04-10 15:47
*/
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.application.Platform;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import java.util.function.Consumer;
/**
* JavaFX配置类,负责启动JavaFX应用并集成Spring上下文
* 核心功能:
* 1. 初始化Spring应用上下文
* 2. 加载JavaFX主舞台(Stage)
* 3. 管理两者生命周期
*/
public class JavaFXConfiguration extends Application {
// Spring应用上下文,用于依赖注入
private ConfigurableApplicationContext context;
// JavaFX根节点,所有UI组件的容器
private Parent root;
// Stage自定义配置回调函数
private Consumer<Stage> stageConsumer;
@Override
public void init() throws Exception {
// // 创建Spring上下文初始化器,注册JavaFX核心对象
ApplicationContextInitializer<GenericApplicationContext> initializer = ac -> {
// 将JavaFX Application实例注册为Spring Bean
ac.registerBean(Application.class, () -> JavaFXConfiguration.this);
// 注册启动参数(命令行参数)
ac.registerBean(Parameters.class, this::getParameters);
// 注册HostServices(用于打开网页等操作)
ac.registerBean(HostServices.class, this::getHostServices);
};
// 构建Spring应用(关键步骤)
this.context = new SpringApplicationBuilder()
.sources(com.elitedatai.Application.class) // 指定SpringBoot主类
.initializers(initializer) // 添加上文初始化器
.run(getParameters().getRaw().toArray(new String[0])); // 传递启动参数
}
/**
* JavaFX主入口(UI线程开始执行)
* @param primaryStage 主舞台(相当于主窗口)
*/
@Override
public void start(Stage primaryStage) throws Exception {
// 从Spring容器获取FXML加载配置
FxmlViewConfiguration viewConfig = context.getBean(FxmlViewConfiguration.class);
// 加载主视图(触发FXML文件的解析和控制器初始化)
this.root = viewConfig.mainView();
// 创建场景图(Scene是UI组件的根容器)
Scene scene = new Scene(root, 1200, 800);
// 配置主舞台
primaryStage.setScene(scene); // 绑定场景到舞台
primaryStage.setTitle(" 工厂MES上位机系统"); // 设置窗口标题
primaryStage.centerOnScreen(); // 窗口居中显示
// 执行自定义舞台配置(如果有)
if (stageConsumer != null) {
stageConsumer.accept(primaryStage);
}
// 显示窗口(至此UI可见)
primaryStage.show();
}
/**
* JavaFX停止方法(窗口关闭时调用)
*/
@Override
public void stop() throws Exception {
// 关闭Spring应用上下文(触发@PreDestroy等生命周期回调)
this.context.close();
// 确保JavaFX平台完全退出
Platform.exit();
}
/**
* 设置舞台自定义配置器
* @param stageConsumer 接收Stage对象的函数式接口
*/
public void setStageConsumer(Consumer<Stage> stageConsumer) {
this.stageConsumer = stageConsumer;
}
}
FXML视图配置 (FxmlViewConfiguration.java)
package com.elitedatai.config;
/**
* @author llg
* @slogan 致敬大师,致敬未来的你
* @create 2025-04-10 15:48
*/
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URL;
/**
* FXML视图配置类,负责加载FXML文件并注入Spring管理的控制器
*/
@Component
public class FxmlViewConfiguration {
private final ApplicationContext context;
@Autowired
public FxmlViewConfiguration(ApplicationContext context) {
this.context = context;
}
/**
* 加载主视图
*/
public Parent mainView() throws IOException {
return loadView("/fxml/main.fxml");
}
/**
* 加载工单管理视图
*/
public Parent workOrderView() throws IOException {
return loadView("/fxml/work_order.fxml");
}
/**
* 通用视图加载方法
*/
private Parent loadView(String fxmlPath) throws IOException {
FXMLLoader loader = new FXMLLoader();
URL resource = getClass().getResource(fxmlPath);
loader.setLocation(resource);
loader.setControllerFactory(context::getBean); // 使用Spring管理的控制器
return loader.load();
}
}
服务层接口
我使用的是JPA框架,根据实体,写好实体相关仓库接口和业务层接口,直接贴代码:
/**
* 工单服务类 - 业务逻辑处理
*/
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class WorkOrderService {
private final WorkOrderRepository workOrderRepository;
private final ModelMapper modelMapper;
/**
* 创建工单
*/
@Transactional
public WorkOrderVO create(WorkOrderVO vo) {
WorkOrder entity = vo.toEntity();
WorkOrder saved = workOrderRepository.save(entity);
return WorkOrderVO.fromEntity(saved);
}
/**
* 更新工单
*/
@Transactional
public WorkOrderVO update(WorkOrderVO vo) {
WorkOrder existing = workOrderRepository.findById(vo.getId())
.orElseThrow(() -> new RuntimeException("工单不存在"));
// 更新字段
existing.setOrderNo(vo.getOrderNo());
existing.setProductName(vo.getProductName());
existing.setProductCode(vo.getProductCode());
existing.setPlannedQuantity(vo.getPlannedQuantity());
existing.setCompletedQuantity(vo.getCompletedQuantity());
existing.setStartTime(vo.getStartTime());
existing.setEndTime(vo.getEndTime());
existing.setStatus(vo.getStatus());
existing.setRemark(vo.getRemark());
WorkOrder updated = workOrderRepository.save(existing);
return WorkOrderVO.fromEntity(updated);
}
/**
* 获取所有工单
*/
public List<WorkOrderVO> findAll() {
return workOrderRepository.findAll().stream()
.map(WorkOrderVO::fromEntity)
.collect(Collectors.toList());
}
/**
* 分页查询工单
*/
public Page<WorkOrderVO> findAll(Pageable pageable) {
return workOrderRepository.findAll(pageable)
.map(WorkOrderVO::fromEntity);
}
/**
* 根据ID获取工单
*/
public WorkOrderVO findById(Long id) {
return workOrderRepository.findById(id)
.map(WorkOrderVO::fromEntity)
.orElseThrow(() -> new RuntimeException("工单不存在"));
}
/**
* 删除工单
*/
@Transactional
public void delete(Long id) {
workOrderRepository.deleteById(id);
}
/**
* 更新工单进度
*/
@Transactional
public WorkOrderVO updateProgress(Long id, Integer completed) {
WorkOrder order = workOrderRepository.findById(id)
.orElseThrow(() -> new RuntimeException("工单不存在"));
order.setCompletedQuantity(completed);
if (completed >= order.getPlannedQuantity()) {
order.setStatus(WorkOrder.OrderStatus.COMPLETED);
}
WorkOrder updated = workOrderRepository.save(order);
return WorkOrderVO.fromEntity(updated);
}
}
控制层
javafx相关控制层
Main控制层:
package com.elitedatai.controller.fx;
import com.elitedatai.config.FxmlViewConfiguration;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import org.springframework.stereotype.Controller;
/**
* 主界面控制器 - 负责管理主界面的导航和状态显示
*/
@Controller
public class MainController {
@FXML private StackPane contentPane;
@FXML private Label statusLabel;
private final FxmlViewConfiguration viewConfig;
public MainController(FxmlViewConfiguration viewConfig) {
this.viewConfig = viewConfig;
}
/**
* 初始化方法,FXML加载后自动调用
*/
@FXML
public void initialize() {
// 默认加载工单管理视图
showWorkOrderView();
}
/**
* 显示工单管理视图
*/
@FXML
public void showWorkOrderView() {
try {
contentPane.getChildren().clear();
contentPane.getChildren().add(viewConfig.workOrderView());
updateStatus("工单管理视图已加载");
} catch (Exception e) {
updateStatus("加载工单视图失败: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 退出应用程序
*/
@FXML
public void handleExit() {
javafx.application.Platform.exit();
}
/**
* 更新状态栏信息
*/
private void updateStatus(String message) {
statusLabel.setText(message);
}
}
main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<BorderPane xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.elitedatai.controller.fx.MainController">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
<Menu text="文件">
<items>
<MenuItem text="退出" onAction="#handleExit" />
</items>
</Menu>
<Menu text="工单管理">
<items>
<MenuItem text="工单列表" onAction="#showWorkOrderView" />
</items>
</Menu>
<Menu text="帮助">
<items>
<MenuItem text="关于" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<StackPane fx:id="contentPane" />
</center>
<bottom>
<HBox alignment="CENTER" spacing="10" style="-fx-background-color: #f0f0f0; -fx-padding: 5;">
<Label text="工厂MES上位机系统" />
<Label text="版本: 1.0.0" />
<Label fx:id="statusLabel" text="就绪" />
</HBox>
</bottom>
</BorderPane>
WorkOrderController:
package com.elitedatai.controller.fx;
import com.elitedatai.model.Test;
import com.elitedatai.service.WorkOrderService;
import com.elitedatai.vo.TestVO;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import java.time.LocalDateTime;
import java.util.List;
/**
* JavaFX工单控制器
*/
@Controller
@RequiredArgsConstructor
public class WorkOrderController {
private final WorkOrderService workOrderService;
// FXML注入的UI组件
@FXML private TableView<TestVO> workOrderTable;
@FXML private TableColumn<TestVO, String> orderNoColumn;
@FXML private TableColumn<TestVO, String> productNameColumn;
@FXML private TableColumn<TestVO, Integer> plannedQuantityColumn;
@FXML private TableColumn<TestVO, Integer> completedQuantityColumn;
@FXML private TableColumn<TestVO, String> progressColumn;
@FXML private TableColumn<TestVO, String> statusColumn;
@FXML private TextField orderNoField;
@FXML private TextField productNameField;
@FXML private TextField productCodeField;
@FXML private TextField plannedQuantityField;
@FXML private DatePicker startDatePicker;
@FXML private DatePicker endDatePicker;
@FXML private ComboBox<String> statusComboBox;
@FXML private TextArea remarkArea;
private final ObservableList<TestVO> workOrderData = FXCollections.observableArrayList();
/**
* 初始化方法,由FXML加载器调用
*/
@FXML
public void initialize() {
// 配置表格列
orderNoColumn.setCellValueFactory(new PropertyValueFactory<>("orderNo"));
productNameColumn.setCellValueFactory(new PropertyValueFactory<>("productName"));
plannedQuantityColumn.setCellValueFactory(new PropertyValueFactory<>("plannedQuantity"));
completedQuantityColumn.setCellValueFactory(new PropertyValueFactory<>("completedQuantity"));
progressColumn.setCellValueFactory(cellData -> {
double progress = cellData.getValue().getProgress();
return new javafx.beans.property.SimpleStringProperty(String.format("%.2f%%", progress));
});
statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
// 绑定数据
workOrderTable.setItems(workOrderData);
// 加载数据
refreshData();
// 配置状态下拉框
statusComboBox.getItems().addAll(
"PENDING", "IN_PROGRESS", "PAUSED", "COMPLETED", "CANCELLED"
);
}
/**
* 刷新表格数据
*/
private void refreshData() {
List<TestVO> orders = workOrderService.findAll();
workOrderData.clear();
workOrderData.addAll(orders);
}
/**
* 创建新工单
*/
@FXML
private void handleCreate() {
try {
TestVO vo = new TestVO();
vo.setOrderNo(orderNoField.getText());
vo.setProductName(productNameField.getText());
vo.setProductCode(productCodeField.getText());
vo.setPlannedQuantity(Integer.parseInt(plannedQuantityField.getText()));
vo.setCompletedQuantity(0);
vo.setStartTime(LocalDateTime.from(startDatePicker.getValue().atStartOfDay()));
vo.setEndTime(LocalDateTime.from(endDatePicker.getValue().atStartOfDay()));
vo.setStatus(Test.OrderStatus.valueOf(statusComboBox.getValue()));
vo.setRemark(remarkArea.getText());
workOrderService.create(vo);
refreshData();
clearFields();
showAlert("成功", "工单创建成功", Alert.AlertType.INFORMATION);
} catch (Exception e) {
showAlert("错误", "创建工单失败: " + e.getMessage(), Alert.AlertType.ERROR);
}
}
/**
* 更新工单进度
*/
@FXML
private void handleUpdateProgress() {
TestVO selected = workOrderTable.getSelectionModel().getSelectedItem();
if (selected == null) {
showAlert("警告", "请先选择一条工单", Alert.AlertType.WARNING);
return;
}
TextInputDialog dialog = new TextInputDialog(selected.getCompletedQuantity().toString());
dialog.setTitle(" 更新进度");
dialog.setHeaderText(" 请输入已完成数量");
dialog.setContentText(" 数量:");
dialog.showAndWait().ifPresent(completed -> {
try {
int completedQty = Integer.parseInt(completed);
workOrderService.updateProgress(selected.getId(), completedQty);
refreshData();
showAlert("成功", "工单进度更新成功", Alert.AlertType.INFORMATION);
} catch (NumberFormatException e) {
showAlert("错误", "请输入有效的数字", Alert.AlertType.ERROR);
} catch (Exception e) {
showAlert("错误", "更新进度失败: " + e.getMessage(), Alert.AlertType.ERROR);
}
});
}
/**
* 显示警告对话框
*/
private void showAlert(String title, String message, Alert.AlertType type) {
Alert alert = new Alert(type);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
/**
* 清空输入字段
*/
private void clearFields() {
orderNoField.clear();
productNameField.clear();
productCodeField.clear();
plannedQuantityField.clear();
startDatePicker.setValue(null);
endDatePicker.setValue(null);
statusComboBox.setValue(null);
remarkArea.clear();
}
}
workorder.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<VBox xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.elitedatai.controller.fx.WorkOrderController" spacing="10">
<Label text="工单管理" style="-fx-font-size: 16pt; -fx-font-weight: bold;" />
<HBox spacing="10" alignment="CENTER_LEFT">
<Label text="工单编号:" />
<TextField fx:id="orderNoField" promptText="请输入工单编号" />
<Label text="产品名称:" />
<TextField fx:id="productNameField" promptText="请输入产品名称" />
<Label text="产品编码:" />
<TextField fx:id="productCodeField" promptText="请输入产品编码" />
</HBox>
<HBox spacing="10" alignment="CENTER_LEFT">
<Label text="计划数量:" />
<TextField fx:id="plannedQuantityField" promptText="请输入计划数量" />
<Label text="开始日期:" />
<DatePicker fx:id="startDatePicker" />
<Label text="结束日期:" />
<DatePicker fx:id="endDatePicker" />
<Label text="状态:" />
<ComboBox fx:id="statusComboBox" promptText="选择状态" />
</HBox>
<HBox spacing="10" alignment="CENTER_LEFT">
<Label text="备注:" />
<TextArea fx:id="remarkArea" promptText="请输入备注信息" wrapText="true" prefRowCount="2" />
</HBox>
<HBox spacing="10">
<Button text="创建工单" onAction="#handleCreate" style="-fx-base: #4CAF50;" />
<Button text="更新进度" onAction="#handleUpdateProgress" style="-fx-base: #2196F3;" />
</HBox>
<TableView fx:id="workOrderTable" prefHeight="400">
<columns>
<TableColumn text="工单编号" fx:id="orderNoColumn" prefWidth="120" />
<TableColumn text="产品名称" fx:id="productNameColumn" prefWidth="150" />
<TableColumn text="计划数量" fx:id="plannedQuantityColumn" prefWidth="80" />
<TableColumn text="完成数量" fx:id="completedQuantityColumn" prefWidth="80" />
<TableColumn text="进度" fx:id="progressColumn" prefWidth="80" />
<TableColumn text="状态" fx:id="statusColumn" prefWidth="100" />
</columns>
</TableView>
</VBox>
web控制层
package com.elitedatai.controller.web;
/**
* @author llg
* @slogan 致敬大师,致敬未来的你
* @create 2025-04-10 16:19
*/
import com.elitedatai.service.WorkOrderService;
import com.elitedatai.vo.TestVO;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 工单REST API控制器
*/
@RestController
@RequestMapping("/api/work-orders")
@RequiredArgsConstructor
public class WorkOrderApiController {
private final WorkOrderService workOrderService;
/**
* 获取所有工单
*/
@GetMapping
public ResponseEntity<List<TestVO>> findAll() {
return ResponseEntity.ok(workOrderService.findAll());
}
/**
* 分页查询工单
*/
@GetMapping("/page")
public ResponseEntity<Page<TestVO>> findAll(Pageable pageable) {
return ResponseEntity.ok(workOrderService.findAll(pageable));
}
/**
* 根据ID获取工单
*/
@GetMapping("/{id}")
public ResponseEntity<TestVO> findById(@PathVariable Long id) {
return ResponseEntity.ok(workOrderService.findById(id));
}
/**
* 创建工单
*/
@PostMapping
public ResponseEntity<TestVO> create(@RequestBody TestVO vo) {
return ResponseEntity.ok(workOrderService.create(vo));
}
/**
* 更新工单
*/
@PutMapping("/{id}")
public ResponseEntity<TestVO> update(@PathVariable Long id, @RequestBody TestVO vo) {
vo.setId(id);
return ResponseEntity.ok(workOrderService.update(vo));
}
/**
* 删除工单
*/
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
workOrderService.delete(id);
return ResponseEntity.noContent().build();
}
/**
* 更新工单进度
*/
@PatchMapping("/{id}/progress")
public ResponseEntity<TestVO> updateProgress(
@PathVariable Long id,
@RequestParam Integer completed) {
return ResponseEntity.ok(workOrderService.updateProgress(id, completed));
}
}
启动类与主应用
SpringBoot主类 (Application.java)
package com.elitedatai;
/**
* @author llg
* @slogan 致敬大师,致敬未来的你
* @create 2025-04-10 16:12
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* SpringBoot主启动类
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 检查是否以JavaFX模式启动
if (args.length > 0 && args[0].equals("--javafx")) {
com.elitedatai.MainApp.main(args);
} else {
SpringApplication.run(Application.class, args);
}
}
}
JavaFX主类 (MainApp.java)
package com.elitedatai;
import com.elitedatai.config.JavaFXConfiguration;
import javafx.application.Application;
/**
* JavaFX主启动类
*/
public class MainApp {
public static void main(String[] args) {
// 启动JavaFX应用
Application.launch(JavaFXConfiguration.class, "--javafx");
}
}
运行与部署
1. 运行应用
直接想启动web就运行web主类,想启动javafx就运行javafx主类
2.打包应用
创建可执行JAR:
mvn clean package
然后运行:
java -jar target/mes-upper-machine-1.0.0.jar --javafx
或者作为Web应用运行:
java -jar target/mes-upper-machine-1.0.0.jar
JavaFx在Springboot中的依赖关系如图: