feat(service): 实现国际化支持并优化Service层
重构文件类型相关Service以支持国际化查询 添加findOneByLang辅助方法统一查询逻辑 实现StringConverter支持UI控件显示 优化缓存配置和查询性能 新增UnitStringConverter和CustomerCatalogStringConverter 完善文档和测试用例
This commit is contained in:
220
docs/task/table_cell_implementation_guide.md
Normal file
220
docs/task/table_cell_implementation_guide.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# TableCell 实现规则与模式指南
|
||||
|
||||
## 1. 目的与作用
|
||||
|
||||
TableCell 是 JavaFX TableView 组件中的关键元素,负责表格中单个单元格的渲染和交互。在 Contract-Manager 项目中,TableCell 主要用于:
|
||||
|
||||
- 显示各种类型的数据(数字、日期、实体引用等)
|
||||
- 提供自定义的显示格式和样式
|
||||
- 支持异步加载关联数据
|
||||
- 实现单元格内编辑功能
|
||||
|
||||
## 2. 文件结构与命名规范
|
||||
|
||||
- **文件位置**:`client/src/main/java/com/ecep/contract/controller/table/cell/`
|
||||
- **命名规范**:使用 PascalCase(驼峰命名法,首字母大写),以 `TableCell` 结尾
|
||||
- 示例:`CompanyTableCell.java`、`LocalDateFieldTableCell.java`
|
||||
|
||||
## 3. TableCell 分类与实现模式
|
||||
|
||||
### 3.1 基础 TableCell
|
||||
|
||||
直接继承 JavaFX 的 `TableCell` 类,适用于简单的数据显示。
|
||||
|
||||
**实现规则**:
|
||||
- 继承 `TableCell<S, T>`,其中 S 是表格行数据类型,T 是单元格数据类型
|
||||
- 实现 `updateItem(T item, boolean empty)` 方法
|
||||
- 提供静态的 `forTableColumn()` 工厂方法
|
||||
|
||||
**示例**:
|
||||
```java
|
||||
public class NumberTableCell<S> extends TableCell<S, Number> {
|
||||
private final NumberStringConverter numberStringConverter;
|
||||
|
||||
public NumberTableCell(NumberStringConverter numberStringConverter) {
|
||||
this.numberStringConverter = numberStringConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(Number item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty || item == null) {
|
||||
setText(null);
|
||||
} else {
|
||||
setText(numberStringConverter.toString(item));
|
||||
}
|
||||
}
|
||||
|
||||
public static <S> Callback<TableColumn<S, Number>, TableCell<S, Number>> forTableColumn(NumberStringConverter numberStringConverter) {
|
||||
return param -> new NumberTableCell<>(numberStringConverter);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 异步更新 TableCell
|
||||
|
||||
继承 `AsyncUpdateTableCell`,用于异步加载并显示关联的实体数据。
|
||||
|
||||
**实现规则**:
|
||||
- 继承 `AsyncUpdateTableCell<V, K, T>`,其中 V 是表格行数据类型,K 是 ID 类型,T 是实体类型
|
||||
- 提供构造函数接收服务对象,或实现 `getServiceBean()` 方法从 Spring 容器获取服务
|
||||
- 可选:重写 `initialize()` 方法自定义实体加载逻辑
|
||||
- 可选:重写 `format()` 方法自定义实体显示格式
|
||||
|
||||
**示例**:
|
||||
```java
|
||||
@NoArgsConstructor
|
||||
public class CompanyTableCell<V> extends AsyncUpdateTableCell<V, Integer, CompanyVo> {
|
||||
public CompanyTableCell(CompanyService companyService) {
|
||||
setService(companyService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompanyService getServiceBean() {
|
||||
return SpringApp.getBean(CompanyService.class);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 可编辑 TableCell
|
||||
|
||||
实现单元格内编辑功能,如日期选择、文本编辑等。
|
||||
|
||||
**实现规则**:
|
||||
- 继承 `TableCell` 或其子类
|
||||
- 实现 `startEdit()`、`cancelEdit()` 方法
|
||||
- 在 `updateItem()` 方法中处理编辑状态的显示
|
||||
- 提供编辑控件和事件处理
|
||||
|
||||
**示例**:
|
||||
```java
|
||||
public class LocalDateFieldTableCell<S> extends TableCell<S, LocalDate> {
|
||||
private final DatePicker datePicker;
|
||||
|
||||
// 构造函数、converter 属性等
|
||||
|
||||
@Override
|
||||
public void startEdit() {
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
super.startEdit();
|
||||
setGraphic(datePicker);
|
||||
datePicker.setConverter(getConverter());
|
||||
datePicker.setValue(getItem());
|
||||
datePicker.requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelEdit() {
|
||||
super.cancelEdit();
|
||||
LocalDate item = getItem();
|
||||
if (item == null) {
|
||||
setText(null);
|
||||
} else {
|
||||
setText(getConverter().toString(item));
|
||||
}
|
||||
setGraphic(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(LocalDate item, boolean empty) {
|
||||
// 实现更新逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. AsyncUpdateTableCell 核心功能
|
||||
|
||||
`AsyncUpdateTableCell` 是项目中最常用的基类,提供以下核心功能:
|
||||
|
||||
### 4.1 异步加载机制
|
||||
|
||||
- 显示占位符(`#id`)直到数据加载完成
|
||||
- 使用线程池执行异步任务
|
||||
- 自动取消不再需要的异步任务
|
||||
- 确保在 JavaFX 应用线程更新 UI
|
||||
|
||||
### 4.2 实体显示格式化
|
||||
|
||||
- 默认使用 `toString()` 方法格式化实体
|
||||
- 对 `NamedEntity` 和 `BasedEntity` 有特殊处理
|
||||
- 允许子类重写 `format()` 方法自定义格式
|
||||
|
||||
### 4.3 服务获取方式
|
||||
|
||||
- 通过构造函数注入服务
|
||||
- 或通过 `getServiceBean()` 方法从 Spring 容器获取
|
||||
|
||||
## 5. 特殊情况处理
|
||||
|
||||
### 5.1 非 Integer 类型 ID
|
||||
|
||||
当实体 ID 不是 Integer 类型时,需要重写 `initialize()` 方法:
|
||||
|
||||
```java
|
||||
@Override
|
||||
protected ContractFileTypeLocalVo initialize() {
|
||||
ContractFileType item = getItem();
|
||||
ContractFileTypeLocalVo localVo = getServiceBean().findByType(
|
||||
Desktop.instance.getActiveEmployee().localeProperty().get(), item);
|
||||
return localVo;
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 自定义显示格式
|
||||
|
||||
当需要自定义实体的显示格式时,重写 `format()` 方法:
|
||||
|
||||
```java
|
||||
@Override
|
||||
public String format(ContractFileTypeLocalVo entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
return entity.getValue();
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 工厂方法模式
|
||||
|
||||
所有 TableCell 类都应提供静态的 `forTableColumn()` 工厂方法,用于创建单元格工厂回调:
|
||||
|
||||
- 无参数版本:`public static <S> Callback<TableColumn<S, T>, TableCell<S, T>> forTableColumn()`
|
||||
- 带服务参数版本:`public static <S> Callback<TableColumn<S, T>, TableCell<S, T>> forTableColumn(ServiceType service)`
|
||||
|
||||
## 7. 代码规范
|
||||
|
||||
- 使用 Lombok 注解(如 `@NoArgsConstructor`)简化代码
|
||||
- 添加适当的 JavaDoc 注释
|
||||
- 遵循 JavaFX 最佳实践
|
||||
- 处理空值和异常情况
|
||||
- 确保线程安全,UI 更新在 JavaFX 应用线程执行
|
||||
|
||||
## 8. 实现检查清单
|
||||
|
||||
创建新的 TableCell 时,请检查以下项目:
|
||||
|
||||
- [ ] 类名符合 `*TableCell` 命名规范
|
||||
- [ ] 放置在正确的包路径下
|
||||
- [ ] 选择合适的基类(TableCell、AsyncUpdateTableCell)
|
||||
- [ ] 实现必要的构造函数
|
||||
- [ ] 实现或重写 `updateItem()` 方法
|
||||
- [ ] 提供静态的 `forTableColumn()` 工厂方法
|
||||
- [ ] 对于异步更新类型,实现 `getServiceBean()` 或提供服务注入
|
||||
- [ ] 添加适当的注释
|
||||
- [ ] 处理空值和异常情况
|
||||
|
||||
## 9. 示例实现
|
||||
|
||||
### 9.1 简单数据类型 TableCell
|
||||
|
||||
参考 `NumberTableCell.java`、`LocalDateFieldTableCell.java`
|
||||
|
||||
### 9.2 实体引用 TableCell
|
||||
|
||||
参考 `CompanyTableCell.java`、`ContractTableCell.java`
|
||||
|
||||
### 9.3 特殊处理 TableCell
|
||||
|
||||
参考 `ContractFileTypeTableCell.java`
|
||||
Reference in New Issue
Block a user