feat(contract): 新增合同内容管理功能

- 添加合同内容窗口控制器及相关视图模型
- 实现合同内容基础信息标签页
- 添加金额计算功能
- 完善合同内容相关字段绑定
- 优化合同内容界面布局
This commit is contained in:
2025-10-16 00:09:01 +08:00
parent d2e0dc4555
commit cf0a7e18ea
7 changed files with 445 additions and 32 deletions

View File

@@ -0,0 +1,140 @@
package com.ecep.contract.controller.contract;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.ecep.contract.controller.AbstEntityController;
import com.ecep.contract.controller.inventory.InventoryWindowController;
import com.ecep.contract.controller.tab.ContractItemTabSkinBase;
import com.ecep.contract.service.ContractItemService;
import com.ecep.contract.service.InventoryService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.ContractItemViewModel;
import com.ecep.contract.vm.InventoryViewModel;
import com.ecep.contract.vo.ContractItemVo;
import com.ecep.contract.vo.InventoryVo;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/contract/contract-item.fxml")
public class ContractItemWindowController
extends AbstEntityController<ContractItemVo, ContractItemViewModel> {
public static void show(ContractItemVo contractItem, Window owner) {
show(ContractItemViewModel.from(contractItem), owner);
}
/**
* 显示界面
*/
public static void show(ContractItemViewModel viewModel, Window window) {
show(ContractItemWindowController.class, viewModel, window);
}
public BorderPane root;
public Tab baseInfoTab;
// 基本信息字段
public Label idLabel;
public TextField codeField;
public TextField titleField;
public TextField specificationField;
public TextField unitField;
public TextField inventoryField;
public Button openInventoryBtn;
// 财务信息字段
public TextField exclusiveTaxPriceField;
public TextField taxRateField;
public TextField taxPriceField;
public TextField quantityField;
public TextField taxAmountField;
public TextField exclusiveTaxAmountField;
// 日期信息字段
public DatePicker startDateField;
public DatePicker endDateField;
public TextField createDateLabel;
public TextField updateDateLabel;
public TextField creatorLabel;
public TextField updaterLabel;
// 其他信息
public TextField refIdField;
public TextArea remarkField;
@Override
public ContractItemService getViewModelService() {
return getCachedBean(ContractItemService.class);
}
public InventoryService getInventoryService() {
return getCachedBean(InventoryService.class);
}
public void onShown(WindowEvent windowEvent) {
super.onShown(windowEvent);
getTitle().bind(viewModel.getTitle()
.map(title -> "[" + viewModel.getId() + "] " + title + " 合同内容详情"));
root.getScene().getStylesheets().add("/ui/contract/contract.css");
}
@Override
protected void registerTabSkins() {
super.registerTabSkins();
TabPane tabPane = baseInfoTab.getTabPane();
ObservableList<Tab> tabs = tabPane.getTabs();
registerTabSkin(baseInfoTab, tab -> new ContractItemTabSkinBase(this));
}
/**
* 打开关联的存货信息
*/
public void onOpenInventoryAction(ActionEvent event) {
try {
if (viewModel.getInventory() == null) {
UITools.showAlertAndWait("没有关联的存货信息");
return;
}
Integer inventoryId = viewModel.getInventory().get();
InventoryVo inventory = getInventoryService().findById(inventoryId);
if (inventory != null) {
InventoryWindowController.show(InventoryViewModel.from(inventory), root.getScene().getWindow());
} else {
UITools.showAlertAndWait("未找到关联的存货信息");
}
} catch (Exception e) {
UITools.showAlertAndWait("打开存货信息失败: " + e.getMessage());
}
}
/**
* 计算税额和金额
*/
public void onCalculateAmountsAction(ActionEvent event) {
try {
viewModel.calculateAmounts();
UITools.showAlertAndWait("金额计算完成");
} catch (Exception e) {
UITools.showAlertAndWait("计算失败: " + e.getMessage());
}
}
}

View File

@@ -152,7 +152,13 @@ public class ContractWindowController
payPlanTab.setText("收款计划");
tabs.add(saleOrderTab);
registerTabSkin(saleOrderTab, tab -> new ContractTabSkinSaleOrders(this, tab));
tabs.add(new Tab(""));
Tab invoiceTab = new Tab("");
tabs.add(invoiceTab);
// registerTabSkin(invoiceTab, tab -> new ContractTabSkinInvoices(this, tab));
tabs.add(new Tab("出库单"));
tabs.add(new Tab("发货单"));
tabs.add(new Tab("签收单"));
} else if (payWay == ContractPayWay.PAY) {
registerTabSkin(extendVendorInfo, t -> new ContractTabSkinExtendVendorInfo(this));
tabs.remove(contractTab);
@@ -162,9 +168,9 @@ public class ContractWindowController
tabs.add(purchaseOrderTab);
registerTabSkin(purchaseOrderTab, tab -> new ContractTabSkinPurchaseOrders(this, tab));
tabs.add(new Tab("发货"));
tabs.add(new Tab("签收单"));
tabs.add(new Tab("入库"));
tabs.add(new Tab("付款单"));
payPlanTab.setText("付款计划");
}

View File

@@ -5,10 +5,12 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.ecep.contract.controller.AbstEntityController;
import com.ecep.contract.controller.BaseController;
import com.ecep.contract.service.InventoryService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.vm.InventoryViewModel;
import com.ecep.contract.vo.InventoryVo;
import javafx.stage.Window;
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
@@ -26,6 +28,19 @@ import javafx.stage.WindowEvent;
@Component
@FxmlPath("/ui/inventory/inventory.fxml")
public class InventoryWindowController extends AbstEntityController<InventoryVo, InventoryViewModel> {
/**
* 显示界面
*/
public static void show(InventoryViewModel viewModel, Window window) {
BaseController.show(InventoryWindowController.class, viewModel, window);
}
/**
* 显示界面
*/
public static void show(InventoryVo inventory, Window owner) {
show(InventoryViewModel.from(inventory), owner);
}
@FXML
public BorderPane root;
@FXML

View File

@@ -0,0 +1,84 @@
package com.ecep.contract.controller.tab;
import com.ecep.contract.controller.contract.ContractItemWindowController;
import com.ecep.contract.service.InventoryService;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.ContractItemViewModel;
import com.ecep.contract.vo.ContractItemVo;
import javafx.scene.control.Tab;
import javafx.util.converter.LocalDateTimeStringConverter;
/**
* 合同项目基础信息标签页
*/
public class ContractItemTabSkinBase
extends AbstEntityBasedTabSkin<ContractItemWindowController, ContractItemVo, ContractItemViewModel> {
public ContractItemTabSkinBase(ContractItemWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.baseInfoTab;
}
@Override
public void initializeTab() {
// 数据绑定
controller.idLabel.textProperty().bind(viewModel.getId().asString());
controller.codeField.textProperty().bindBidirectional(viewModel.getCode());
controller.titleField.textProperty().bindBidirectional(viewModel.getTitle());
controller.specificationField.textProperty().bindBidirectional(viewModel.getSpecification());
controller.unitField.textProperty().bindBidirectional(viewModel.getUnit());
// 财务信息绑定
controller.exclusiveTaxPriceField.textProperty().bindBidirectional(viewModel.getExclusiveTaxPrice().asObject(),
new javafx.util.converter.DoubleStringConverter());
controller.taxRateField.textProperty().bindBidirectional(viewModel.getTaxRate().asObject(),
new javafx.util.converter.DoubleStringConverter());
controller.taxPriceField.textProperty().bindBidirectional(viewModel.getTaxPrice().asObject(),
new javafx.util.converter.DoubleStringConverter());
controller.quantityField.textProperty().bindBidirectional(viewModel.getQuantity().asObject(),
new javafx.util.converter.DoubleStringConverter());
controller.taxAmountField.textProperty().bindBidirectional(viewModel.getTaxAmount().asObject(),
new javafx.util.converter.DoubleStringConverter());
controller.exclusiveTaxAmountField.textProperty().bindBidirectional(
viewModel.getExclusiveTaxAmount().asObject(),
new javafx.util.converter.DoubleStringConverter());
// 日期绑定
controller.startDateField.valueProperty().bindBidirectional(viewModel.getStartDate());
controller.endDateField.valueProperty().bindBidirectional(viewModel.getEndDate());
// 其他信息绑定
controller.refIdField.textProperty().bindBidirectional(viewModel.getRefId().asObject(),
new javafx.util.converter.IntegerStringConverter());
controller.remarkField.textProperty().bindBidirectional(viewModel.getRemark());
// 设置只读字段
LocalDateTimeStringConverter localDateTimeStringConverter = controller.getCurrentEmployee()
.getLocalDateTimeStringConverter();
controller.createDateLabel.textProperty().bindBidirectional(viewModel.getCreateDate(),
localDateTimeStringConverter);
controller.updateDateLabel.textProperty().bindBidirectional(viewModel.getUpdateDate(),
localDateTimeStringConverter);
UITools.autoCompletion(controller.updaterLabel, viewModel.getCreator(), controller.getEmployeeService());
UITools.autoCompletion(controller.updaterLabel, viewModel.getUpdater(), controller.getEmployeeService());
// 设置存货显示信息
UITools.autoCompletion(controller.inventoryField, viewModel.getInventory(),
getCachedBean(InventoryService.class));
}
@Override
protected ContractItemVo save(ContractItemVo entity) {
// 保存前自动计算金额
viewModel.calculateAmounts();
return super.save(entity);
}
}

View File

@@ -3,7 +3,8 @@ package com.ecep.contract.controller.tab;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import org.springframework.data.domain.Pageable;
import com.ecep.contract.ContractPayWay;
import com.ecep.contract.SpringApp;
@@ -20,22 +21,24 @@ import com.ecep.contract.service.InventoryService;
import com.ecep.contract.service.PurchaseOrderItemService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.ContractItemComposeViewModel;
import com.ecep.contract.vm.ContractItemViewModel;
import com.ecep.contract.vm.InventoryViewModel;
import com.ecep.contract.vo.ContractItemVo;
import com.ecep.contract.vo.InventoryVo;
import com.ecep.contract.vo.PurchaseOrderItemVo;
import javafx.application.Platform;
import javafx.scene.control.*;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.Callback;
import javafx.util.StringConverter;
import javafx.util.converter.CurrencyStringConverter;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;
import org.springframework.data.domain.Pageable;
@FxmlPath("/ui/contract/contract-tab-item-v2.fxml")
public class ContractTabSkinItemsV2

View File

@@ -10,57 +10,55 @@ import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 合同内容
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class ContractItemViewModel extends IdentityViewModel<ContractItemVo> {
/**
* 关联的合同对象,Contract
*/
SimpleObjectProperty<Integer> contract = new SimpleObjectProperty<>();
private final SimpleObjectProperty<Integer> contract = new SimpleObjectProperty<>();
/**
* 关联的用友系统中的数据ID
*/
SimpleIntegerProperty refId = new SimpleIntegerProperty();
SimpleObjectProperty<String> code = new SimpleObjectProperty<>();
SimpleObjectProperty<String> title = new SimpleObjectProperty<>();
SimpleObjectProperty<String> specification = new SimpleObjectProperty<>();
SimpleObjectProperty<String> unit = new SimpleObjectProperty<>();
private final SimpleIntegerProperty refId = new SimpleIntegerProperty();
private final SimpleObjectProperty<String> code = new SimpleObjectProperty<>();
private final SimpleObjectProperty<String> title = new SimpleObjectProperty<>();
private final SimpleObjectProperty<String> specification = new SimpleObjectProperty<>();
private final SimpleObjectProperty<String> unit = new SimpleObjectProperty<>();
/**
* 存货,Inventory
*/
SimpleObjectProperty<Integer> inventory = new SimpleObjectProperty<>();
private final SimpleObjectProperty<Integer> inventory = new SimpleObjectProperty<>();
/**
*
*/
SimpleDoubleProperty taxRate = new SimpleDoubleProperty();
SimpleDoubleProperty exclusiveTaxPrice = new SimpleDoubleProperty();
SimpleDoubleProperty taxPrice = new SimpleDoubleProperty();
SimpleDoubleProperty quantity = new SimpleDoubleProperty();
SimpleDoubleProperty taxAmount = new SimpleDoubleProperty();
SimpleDoubleProperty exclusiveTaxAmount = new SimpleDoubleProperty();
private final SimpleDoubleProperty taxRate = new SimpleDoubleProperty();
private final SimpleDoubleProperty exclusiveTaxPrice = new SimpleDoubleProperty();
private final SimpleDoubleProperty taxPrice = new SimpleDoubleProperty();
private final SimpleDoubleProperty quantity = new SimpleDoubleProperty();
private final SimpleDoubleProperty taxAmount = new SimpleDoubleProperty();
private final SimpleDoubleProperty exclusiveTaxAmount = new SimpleDoubleProperty();
SimpleObjectProperty<LocalDate> startDate = new SimpleObjectProperty<>();
SimpleObjectProperty<LocalDate> endDate = new SimpleObjectProperty<>();
private final SimpleObjectProperty<LocalDate> startDate = new SimpleObjectProperty<>();
private final SimpleObjectProperty<LocalDate> endDate = new SimpleObjectProperty<>();
SimpleObjectProperty<LocalDateTime> createDate = new SimpleObjectProperty<>();
SimpleObjectProperty<LocalDateTime> updateDate = new SimpleObjectProperty<>();
private final SimpleObjectProperty<LocalDateTime> createDate = new SimpleObjectProperty<>();
private final SimpleObjectProperty<LocalDateTime> updateDate = new SimpleObjectProperty<>();
/**
* 关联的创建人,Employee
*/
SimpleObjectProperty<Integer> creator = new SimpleObjectProperty<>();
private final SimpleObjectProperty<Integer> creator = new SimpleObjectProperty<>();
/**
* 关联的更新人,Employee
*/
SimpleObjectProperty<Integer> updater = new SimpleObjectProperty<>();
private final SimpleObjectProperty<Integer> updater = new SimpleObjectProperty<>();
SimpleObjectProperty<String> remark = new SimpleObjectProperty<>();
private final SimpleObjectProperty<String> remark = new SimpleObjectProperty<>();
@Override
protected void updateFrom(ContractItemVo v) {
@@ -87,8 +85,7 @@ public class ContractItemViewModel extends IdentityViewModel<ContractItemVo> {
getUpdater().set(v.getUpdaterId());
getRemark().set(v.getRemark());
getTaxAmount().set(v.getTaxPrice() * v.getQuantity());
getExclusiveTaxAmount().set(v.getExclusiveTaxPrice() * v.getQuantity());
calculateAmounts();
}
@Override
@@ -172,6 +169,26 @@ public class ContractItemViewModel extends IdentityViewModel<ContractItemVo> {
return modified;
}
/**
* 计算税额相关字段
*/
public void calculateAmounts() {
double price = getExclusiveTaxPrice().get();
double rate = getTaxRate().get();
double qty = getQuantity().get();
// 计算含税单价
double taxPrice = price * (1 + rate / 100);
// 计算税额
double taxAmount = price * rate / 100 * qty;
// 计算不含税金额
double exclusiveTaxAmount = price * qty;
getTaxPrice().set(taxPrice);
getTaxAmount().set(taxAmount);
getExclusiveTaxAmount().set(exclusiveTaxAmount);
}
/**
* 判断两个 double 值是否相等
*

View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.Tab?>
<BorderPane fx:id="root" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ecep.contract.controller.contract.ContractItemWindowController">
<center>
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minWidth="150.0"
tabClosingPolicy="UNAVAILABLE" tabMaxWidth="100.0" tabMinWidth="40.0">
<tabs>
<Tab fx:id="baseInfoTab" text="基本信息">
<content>
<ScrollPane fitToWidth="true" pannable="true">
<VBox>
<GridPane hgap="10.0" vgap="10.0" VBox.vgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="200.0" />
<ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="200.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="80.0" vgrow="ALWAYS" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
</rowConstraints>
<!-- ID -->
<Label text="ID:" GridPane.rowIndex="0" GridPane.columnIndex="0" />
<Label fx:id="idLabel" text="-" GridPane.rowIndex="0" GridPane.columnIndex="1" />
<!-- 合同内容代码 -->
<Label text="内容代码:" GridPane.rowIndex="1" GridPane.columnIndex="0" />
<TextField fx:id="codeField" GridPane.rowIndex="1" GridPane.columnIndex="1" />
<!-- 合同内容标题 -->
<Label text="内容标题:" GridPane.rowIndex="2" GridPane.columnIndex="0" />
<TextField fx:id="titleField" GridPane.rowIndex="2" GridPane.columnIndex="1" GridPane.columnSpan="3" />
<!-- 规格 -->
<Label text="规格:" GridPane.rowIndex="3" GridPane.columnIndex="0" />
<TextField fx:id="specificationField" GridPane.rowIndex="3" GridPane.columnIndex="1" GridPane.columnSpan="3" />
<!-- 单位 -->
<Label text="单位:" GridPane.rowIndex="4" GridPane.columnIndex="0" />
<TextField fx:id="unitField" GridPane.rowIndex="4" GridPane.columnIndex="1" />
<!-- 存货 -->
<Label text="存货:" GridPane.rowIndex="5" GridPane.columnIndex="0" />
<HBox GridPane.rowIndex="5" GridPane.columnIndex="1" GridPane.columnSpan="3">
<TextField fx:id="inventoryField" editable="false" HBox.hgrow="ALWAYS" />
<Button fx:id="openInventoryBtn" mnemonicParsing="false" text="查看" onAction="#onOpenInventoryAction" />
</HBox>
<!-- 不含税单价 -->
<Label text="不含税单价:" GridPane.rowIndex="6" GridPane.columnIndex="0" />
<TextField fx:id="exclusiveTaxPriceField" GridPane.rowIndex="6" GridPane.columnIndex="1" />
<!-- 税率 -->
<Label text="税率(%):" GridPane.rowIndex="6" GridPane.columnIndex="2" />
<TextField fx:id="taxRateField" GridPane.rowIndex="6" GridPane.columnIndex="3" />
<!-- 含税单价 -->
<Label text="含税单价:" GridPane.rowIndex="7" GridPane.columnIndex="0" />
<TextField fx:id="taxPriceField" editable="false" GridPane.rowIndex="7" GridPane.columnIndex="1" />
<!-- 数量 -->
<Label text="数量:" GridPane.rowIndex="7" GridPane.columnIndex="2" />
<TextField fx:id="quantityField" GridPane.rowIndex="7" GridPane.columnIndex="3" />
<!-- 税额 -->
<Label text="税额:" GridPane.rowIndex="8" GridPane.columnIndex="0" />
<TextField fx:id="taxAmountField" editable="false" GridPane.rowIndex="8" GridPane.columnIndex="1" />
<!-- 不含税金额 -->
<Label text="不含税金额:" GridPane.rowIndex="8" GridPane.columnIndex="2" />
<TextField fx:id="exclusiveTaxAmountField" editable="false" GridPane.rowIndex="8" GridPane.columnIndex="3" />
<!-- 开始日期 -->
<Label text="开始日期:" GridPane.rowIndex="9" GridPane.columnIndex="0" />
<DatePicker fx:id="startDateField" GridPane.rowIndex="9" GridPane.columnIndex="1" />
<!-- 结束日期 -->
<Label text="结束日期:" GridPane.rowIndex="9" GridPane.columnIndex="2" />
<DatePicker fx:id="endDateField" GridPane.rowIndex="9" GridPane.columnIndex="3" />
<!-- 备注 -->
<Label text="备注:" GridPane.rowIndex="10" GridPane.columnIndex="0" />
<TextArea fx:id="remarkField" GridPane.rowIndex="10" GridPane.columnIndex="1" GridPane.columnSpan="3" />
<!-- 引用ID -->
<Label text="引用ID:" GridPane.rowIndex="11" GridPane.columnIndex="0" />
<TextField fx:id="refIdField" GridPane.rowIndex="11" GridPane.columnIndex="1" GridPane.columnSpan="3" />
<!-- 创建信息 -->
<Label text="创建日期:" GridPane.rowIndex="12" GridPane.columnIndex="0" />
<TextField fx:id="createDateLabel" editable="false" text="-" GridPane.rowIndex="12" GridPane.columnIndex="1" />
<Label text="创建人:" GridPane.rowIndex="13" GridPane.columnIndex="0" />
<TextField fx:id="creatorLabel" editable="false" text="-" GridPane.rowIndex="13" GridPane.columnIndex="1" />
<Label text="更新日期:" GridPane.rowIndex="14" GridPane.columnIndex="0" />
<TextField fx:id="updateDateLabel" editable="false" text="-" GridPane.rowIndex="14" GridPane.columnIndex="1" />
<Label text="更新人:" GridPane.rowIndex="15" GridPane.columnIndex="0" />
<TextField fx:id="updaterLabel" editable="false" text="-" GridPane.rowIndex="15" GridPane.columnIndex="1" />
</GridPane>
<HBox alignment="CENTER" spacing="20.0" VBox.vgrow="NEVER">
<Button mnemonicParsing="false" text="计算金额" onAction="#onCalculateAmountsAction" />
</HBox>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
</ScrollPane>
</content>
</Tab>
</tabs>
</TabPane>
</center>
</BorderPane>