up
This commit is contained in:
182
.trae/rules/tasker_implementation_guide.md
Normal file
182
.trae/rules/tasker_implementation_guide.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Tasker实现规范指南
|
||||
|
||||
## 1. Tasker架构概述
|
||||
|
||||
Tasker是系统中用于执行异步任务的核心框架,主要用于处理耗时操作并提供实时进度反馈。Tasker架构包括:
|
||||
|
||||
- **Tasker基类**:提供任务执行的基础框架和通信功能
|
||||
- **WebSocketServerTasker接口**:定义WebSocket通信任务的规范
|
||||
- **MessageHolder**:用于在任务执行过程中传递消息和更新进度
|
||||
|
||||
## 2. 服务器端Tasker实现规范
|
||||
|
||||
### 2.1 基本结构
|
||||
|
||||
服务器端Tasker实现应遵循以下结构:
|
||||
|
||||
```java
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class YourTaskNameTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
// 服务依赖
|
||||
@Setter
|
||||
private YourService service;
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化任务标题
|
||||
updateTitle("任务标题");
|
||||
// 初始化参数
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
// 实现业务逻辑
|
||||
// 使用holder.info()、holder.error()等方法反馈消息
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 关键注意事项
|
||||
|
||||
1. **继承与实现**:
|
||||
- 必须继承`Tasker<Object>`基类
|
||||
- 必须实现`WebSocketServerTasker`接口
|
||||
|
||||
2. **方法实现**:
|
||||
- **不要重复实现**Tasker基类已提供的handler设置方法:`setMessageHandler`、`setTitleHandler`、`setPropertyHandler`、`setProgressHandler`
|
||||
- 必须实现`init`方法,设置任务标题和初始化参数
|
||||
- 必须实现`execute`方法,实现具体业务逻辑
|
||||
|
||||
3. **进度和消息反馈**:
|
||||
- 使用`updateProgress`方法提供进度更新
|
||||
- 使用`MessageHolder`的`info`、`error`、`debug`等方法提供消息反馈
|
||||
|
||||
4. **任务取消**:
|
||||
- 在适当的地方检查`isCancelled()`状态,支持任务取消
|
||||
|
||||
5. **注册要求**:
|
||||
- 任务类必须在`tasker_mapper.json`中注册
|
||||
|
||||
## 3. 客户端Tasker实现规范
|
||||
|
||||
客户端Tasker实现应遵循:
|
||||
|
||||
```java
|
||||
public class YourTaskNameTask extends Tasker<Object> {
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
// 客户端任务逻辑
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 通信规范
|
||||
|
||||
### 4.1 命名规范
|
||||
|
||||
- 客户端和服务器端对应的Tasker类应使用**相同的类名**
|
||||
- 示例:客户端的`ContractSyncAllTask`对应服务器端的`ContractSyncAllTask`
|
||||
|
||||
### 4.2 消息传递
|
||||
|
||||
- 使用`MessageHolder`进行消息传递
|
||||
- 支持不同级别的消息:INFO、ERROR、DEBUG
|
||||
|
||||
## 5. 最佳实践
|
||||
|
||||
1. **任务拆分**:
|
||||
- 将大型任务拆分为多个小任务,提高可维护性
|
||||
|
||||
2. **异常处理**:
|
||||
- 捕获并正确处理异常,使用`holder.error()`提供详细错误信息
|
||||
|
||||
3. **资源管理**:
|
||||
- 确保及时释放资源,特别是在任务取消的情况下
|
||||
|
||||
4. **日志记录**:
|
||||
- 使用`holder.debug()`记录调试信息
|
||||
- 使用`holder.info()`记录进度信息
|
||||
|
||||
5. **状态检查**:
|
||||
- 定期检查`isCancelled()`状态,确保任务可以被及时取消
|
||||
|
||||
## 6. 代码示例
|
||||
|
||||
### 6.1 服务器端Tasker示例
|
||||
|
||||
```java
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ExampleSyncTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
@Setter
|
||||
private ExampleService exampleService;
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
updateTitle("示例同步任务");
|
||||
// 从argsNode初始化参数
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
try {
|
||||
// 获取总记录数
|
||||
long total = exampleService.getTotalCount();
|
||||
holder.info("开始同步数据,共" + total + "条记录");
|
||||
|
||||
// 分批处理
|
||||
long processed = 0;
|
||||
List<ExampleEntity> entities = exampleService.getAllEntities();
|
||||
|
||||
for (ExampleEntity entity : entities) {
|
||||
// 检查是否取消
|
||||
if (isCancelled()) {
|
||||
holder.info("任务已取消");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 处理单个实体
|
||||
exampleService.processEntity(entity);
|
||||
processed++;
|
||||
|
||||
// 更新进度
|
||||
updateProgress(processed, total);
|
||||
if (processed % 100 == 0) {
|
||||
holder.info("已处理" + processed + "/" + total + "条记录");
|
||||
}
|
||||
}
|
||||
|
||||
holder.info("同步完成,共处理" + processed + "条记录");
|
||||
return processed;
|
||||
} catch (Exception e) {
|
||||
holder.error("同步失败: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 常见错误和避免方法
|
||||
|
||||
1. **重复实现handler方法**:
|
||||
- 错误:在子类中重复实现setMessageHandler等方法
|
||||
- 解决:删除子类中的这些方法,直接使用Tasker基类提供的实现
|
||||
|
||||
2. **缺少任务注册**:
|
||||
- 错误:任务类没有在tasker_mapper.json中注册
|
||||
- 解决:确保所有服务器端Tasker类都在配置文件中正确注册
|
||||
|
||||
3. **类名不匹配**:
|
||||
- 错误:客户端和服务器端Tasker类名不一致
|
||||
- 解决:确保两端使用相同的类名
|
||||
|
||||
4. **进度更新不正确**:
|
||||
- 错误:进度计算错误或没有更新
|
||||
- 解决:正确计算和更新进度,提高用户体验
|
||||
|
||||
5. **资源泄漏**:
|
||||
- 错误:未及时关闭数据库连接等资源
|
||||
- 解决:使用try-with-resources或在finally块中关闭资源
|
||||
@@ -178,8 +178,11 @@ Contract-Manager/
|
||||
2. 配置连接到服务端的WebSocket地址
|
||||
3. 打包为可执行jar或使用jpackage创建安装包
|
||||
|
||||
## 开发环境要求
|
||||
## Tasker实现规范指南
|
||||
|
||||
有关Tasker框架的详细实现规范,请参阅 [Tasker实现规范指南](docs/task/tasker_implementation_guide.md)。
|
||||
|
||||
## 开发环境要求
|
||||
- JDK 21
|
||||
- Maven 3.6+
|
||||
- MySQL 8.0+
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
<parent>
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>Contract-Manager</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>client</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
@@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -206,6 +206,12 @@ public class WebSocketClientService {
|
||||
send(objectMapper.writeValueAsString(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* WebSocketServerCallbackManage#onMessage 负责接收处理
|
||||
*
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
public CompletableFuture<JsonNode> send(SimpleMessage msg) {
|
||||
CompletableFuture<JsonNode> future = new CompletableFuture<>();
|
||||
try {
|
||||
|
||||
@@ -91,27 +91,32 @@ public class YongYouU8ManagerWindowController
|
||||
|
||||
public void onContractGroupSyncAction(ActionEvent event) {
|
||||
ContractGroupSyncTask task = new ContractGroupSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
UITools.showTaskDialogAndWait("合同组数据同步", task, null);
|
||||
// Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onContractTypeSyncAction(ActionEvent event) {
|
||||
ContractTypeSyncTask task = new ContractTypeSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
UITools.showTaskDialogAndWait("合同类型数据同步", task, null);
|
||||
// Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onContractKindSyncAction(ActionEvent event) {
|
||||
ContractKindSyncTask task = new ContractKindSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
UITools.showTaskDialogAndWait("合同类型数据同步", task, null);
|
||||
// Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onVendorClassSyncAction(ActionEvent event) {
|
||||
VendorClassSyncTask task = new VendorClassSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
UITools.showTaskDialogAndWait("客户分类数据同步", task, null);
|
||||
// Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onCustomerClassSyncAction(ActionEvent event) {
|
||||
CustomerClassSyncTask task = new CustomerClassSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
UITools.showTaskDialogAndWait("客户分类数据同步", task, null);
|
||||
// Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class EmployeeManagerSkin
|
||||
controller.accountColumn.setCellValueFactory(param -> param.getValue().getAccount());
|
||||
|
||||
controller.departmentColumn.setCellValueFactory(param -> param.getValue().getDepartment());
|
||||
controller.departmentColumn.setCellFactory(param -> new DepartmentTableCell<>(getDepartmentService()));
|
||||
controller.departmentColumn.setCellFactory(DepartmentTableCell.forTableColumn(getDepartmentService()));
|
||||
|
||||
controller.emailColumn.setCellValueFactory(param -> param.getValue().getEmail());
|
||||
controller.createdColumn.setCellValueFactory(param -> param.getValue().getCreated());
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ecep.contract.controller.permission;
|
||||
|
||||
import com.ecep.contract.controller.tab.AbstEntityBasedTabSkin;
|
||||
import com.ecep.contract.service.FunctionService;
|
||||
import com.ecep.contract.service.PermissionService;
|
||||
import com.ecep.contract.vm.FunctionViewModel;
|
||||
import com.ecep.contract.vo.FunctionVo;
|
||||
|
||||
public abstract class AbstEmployeeFunctionBasedTabSkin
|
||||
extends AbstEntityBasedTabSkin<EmployeeFunctionWindowController, FunctionVo, FunctionViewModel> {
|
||||
|
||||
public AbstEmployeeFunctionBasedTabSkin(EmployeeFunctionWindowController controller) {
|
||||
super(controller);
|
||||
}
|
||||
|
||||
FunctionService getFunctionService() {
|
||||
return getCachedBean(FunctionService.class);
|
||||
}
|
||||
|
||||
public PermissionService getPermissionService() {
|
||||
return controller.permissionService;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ecep.contract.controller.permission;
|
||||
|
||||
import com.ecep.contract.controller.tab.TabSkin;
|
||||
|
||||
import javafx.scene.control.Tab;
|
||||
|
||||
public class EmployeeFunctionTabSkinBase extends AbstEmployeeFunctionBasedTabSkin implements TabSkin {
|
||||
|
||||
public EmployeeFunctionTabSkinBase(EmployeeFunctionWindowController controller) {
|
||||
super(controller);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tab getTab() {
|
||||
return controller.baseInfoTab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTab() {
|
||||
controller.nameField.textProperty().bindBidirectional(viewModel.getName());
|
||||
controller.keyField.textProperty().bindBidirectional(viewModel.getKey());
|
||||
controller.controllerField.textProperty().bindBidirectional(viewModel.getController());
|
||||
controller.iconField.textProperty().bindBidirectional(viewModel.getIcon());
|
||||
controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());
|
||||
controller.activeField.selectedProperty().bindBidirectional(viewModel.getActive());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.ecep.contract.controller.permission;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.service.FunctionService;
|
||||
import com.ecep.contract.service.PermissionService;
|
||||
import com.ecep.contract.util.FxmlPath;
|
||||
import com.ecep.contract.vm.FunctionViewModel;
|
||||
import com.ecep.contract.vo.FunctionVo;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.DatePicker;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.stage.Window;
|
||||
import javafx.stage.WindowEvent;
|
||||
|
||||
|
||||
@Lazy
|
||||
@Scope("prototype")
|
||||
@Component
|
||||
@FxmlPath("/ui/employee/function.fxml")
|
||||
public class EmployeeFunctionWindowController extends AbstEntityController<FunctionVo, FunctionViewModel> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(EmployeeFunctionWindowController.class);
|
||||
|
||||
|
||||
public static void show(FunctionViewModel viewModel, Window window) {
|
||||
show(EmployeeFunctionWindowController.class, viewModel, window);
|
||||
}
|
||||
|
||||
public BorderPane root;
|
||||
public TabPane tabPane;
|
||||
|
||||
/*
|
||||
* 基本信息标签页
|
||||
*/
|
||||
public Tab baseInfoTab;
|
||||
public TextField nameField;
|
||||
public TextField keyField;
|
||||
public TextField controllerField;
|
||||
public TextField iconField;
|
||||
public TextField descriptionField;
|
||||
|
||||
@FXML
|
||||
public CheckBox activeField;
|
||||
public Label versionLabel;
|
||||
|
||||
/*
|
||||
* 权限标签页
|
||||
*/
|
||||
public Tab permissionTab;
|
||||
|
||||
@Autowired
|
||||
PermissionService permissionService;
|
||||
@Autowired
|
||||
FunctionService functionService;
|
||||
|
||||
@Override
|
||||
public void onShown(WindowEvent windowEvent) {
|
||||
super.onShown(windowEvent);
|
||||
getTitle().bind(viewModel.getName().map(name -> "[" + viewModel.getId().get() + "] " + name + " 功能详情"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerTabSkins() {
|
||||
registerTabSkin(baseInfoTab, tab -> new EmployeeFunctionTabSkinBase(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionService getViewModelService() {
|
||||
return functionService;
|
||||
}
|
||||
}
|
||||
@@ -61,8 +61,6 @@ public class EmployeeFunctionsManagerWindowController
|
||||
public void onCreateNewAction(ActionEvent event) {
|
||||
}
|
||||
|
||||
public void onReBuildFilesAction(ActionEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionService getViewModelService() {
|
||||
|
||||
@@ -54,9 +54,6 @@ public class EmployeeRoleManagerWindowController
|
||||
public void onCreateNewAction(ActionEvent event) {
|
||||
}
|
||||
|
||||
public void onReBuildFilesAction(ActionEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmployeeRoleService getViewModelService() {
|
||||
return employeeRoleService;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class EmployeeRoleTabSkinFunctions extends AbstEmployeeRoleBasedTabSkin {
|
||||
}
|
||||
|
||||
private void loadSelectedRoles() {
|
||||
List<FunctionVo> selectedRoles = getRoleService().getFunctionsByRoleId(viewModel.getId().get());
|
||||
List<FunctionVo> selectedRoles = getRoleService().getFunctionsByRole(getEntity());
|
||||
if (selectedRoles != null) {
|
||||
functionsField.getTargetItems().setAll(selectedRoles);
|
||||
}
|
||||
@@ -100,8 +100,7 @@ public class EmployeeRoleTabSkinFunctions extends AbstEmployeeRoleBasedTabSkin {
|
||||
|
||||
private void saveRoles(ActionEvent event) {
|
||||
EmployeeRoleVo entity = getEntity();
|
||||
entity.setFunctions(functionsField.getTargetItems());
|
||||
save(entity);
|
||||
getRoleService().saveRoleFunctions(entity, functionsField.getTargetItems());
|
||||
loadSelectedRoles();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,12 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.ecep.contract.task.CompanyMergeClientTasker;
|
||||
import com.ecep.contract.util.ParamUtils;
|
||||
import com.ecep.contract.util.UITools;
|
||||
import com.ecep.contract.vo.CompanyOldNameVo;
|
||||
import com.ecep.contract.vo.CompanyVo;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -138,53 +142,20 @@ public class CompanyTabSkinOldName
|
||||
}
|
||||
|
||||
private void onTableMergeAction(ActionEvent event) {
|
||||
CompanyVo updater = getParent();
|
||||
HashSet<String> nameSet = new HashSet<>();
|
||||
nameSet.add(updater.getName());
|
||||
// 收集所有曾用名
|
||||
List<String> nameList = dataSet.stream()
|
||||
.map(viewModel -> viewModel.getName().get())
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
|
||||
List<CompanyOldNameViewModel> removes = new ArrayList<>();
|
||||
for (CompanyOldNameViewModel viewModel : dataSet) {
|
||||
// 创建独立的WebSocket客户端任务器
|
||||
CompanyMergeClientTasker task = new CompanyMergeClientTasker();
|
||||
|
||||
if (!nameSet.add(viewModel.getName().get())) {
|
||||
// fixed 曾用名中有重复时,删除重复的
|
||||
deleteRow(viewModel);
|
||||
removes.add(viewModel);
|
||||
}
|
||||
}
|
||||
if (!removes.isEmpty()) {
|
||||
Platform.runLater(() -> {
|
||||
dataSet.removeAll(removes);
|
||||
});
|
||||
setStatus("移除重复的曾用名" + removes.size());
|
||||
}
|
||||
task.setCompany(getParent());
|
||||
task.setNameList(nameList);
|
||||
UITools.showTaskDialogAndWait("合并曾用名", task, null);
|
||||
|
||||
int size = nameSet.size();
|
||||
int count = 1;
|
||||
int merge = 0;
|
||||
for (String name : nameSet) {
|
||||
controller.setRightStatus(count + "/" + size);
|
||||
if (StringUtils.hasText(name)) {
|
||||
List<CompanyVo> list = getParentService().findAllByName(name);
|
||||
for (CompanyVo company : list) {
|
||||
// fixed 曾用名中有可能有 updater 的名字,会导致自己删除自己
|
||||
if (Objects.equals(company.getId(), updater.getId())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
getCompanyService().merge(company, updater);
|
||||
setStatus("并户 " + company.getName() + "[" + company.getId() + "] 到当前公司");
|
||||
merge++;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("合并 " + company.getName() + " -> " + updater.getName() + " 失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (merge == 0) {
|
||||
setStatus("没有需要并户的公司");
|
||||
}
|
||||
controller.setRightStatus("");
|
||||
loadTableDataSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,7 +172,7 @@ public class CompanyTabSkinOldName
|
||||
return;
|
||||
}
|
||||
String path = viewModel.getPath().get();
|
||||
if (StringUtils.hasText(path)) {
|
||||
if (org.springframework.util.StringUtils.hasText(path)) {
|
||||
if (item.startsWith(path)) {
|
||||
item = "~" + item.substring(path.length());
|
||||
}
|
||||
|
||||
@@ -4,10 +4,15 @@ import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.service.DepartmentService;
|
||||
import com.ecep.contract.vo.DepartmentVo;
|
||||
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor
|
||||
public class DepartmentTableCell<T> extends AsyncUpdateTableCell<T, Integer, DepartmentVo> {
|
||||
|
||||
public DepartmentTableCell(DepartmentService service) {
|
||||
setService(service);
|
||||
}
|
||||
@@ -17,4 +22,20 @@ public class DepartmentTableCell<T> extends AsyncUpdateTableCell<T, Integer, Dep
|
||||
return SpringApp.getBean(DepartmentService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为表格列创建 DepartmentTableCell 的工厂方法
|
||||
*
|
||||
* @param service 部门服务
|
||||
* @param <T> 表格行数据类型
|
||||
* @return 表格列的回调函数
|
||||
*/
|
||||
public static <T> Callback<TableColumn<T, Integer>, TableCell<T, Integer>> forTableColumn(DepartmentService service) {
|
||||
return column -> new DepartmentTableCell<>(service);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String format(DepartmentVo entity) {
|
||||
return getService().getStringConverter().toString(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,37 @@
|
||||
package com.ecep.contract.converter;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.ecep.contract.service.DepartmentService;
|
||||
import com.ecep.contract.vo.DepartmentVo;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
public class DepartmentStringConverter extends EntityStringConverter<DepartmentVo> {
|
||||
@Lazy
|
||||
@Autowired
|
||||
/**
|
||||
* 部门字符串转换器
|
||||
*/
|
||||
public class DepartmentStringConverter extends StringConverter<DepartmentVo> {
|
||||
private DepartmentService service;
|
||||
|
||||
public DepartmentStringConverter() {
|
||||
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
setInitialized(department -> service.findById(department.getId()));
|
||||
setSuggestion(service::search);
|
||||
public DepartmentStringConverter(DepartmentService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(DepartmentVo department) {
|
||||
if (department == null) {
|
||||
return "-";
|
||||
}
|
||||
return department.getCode() + " " + department.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DepartmentVo fromString(String string) {
|
||||
if (service == null || string == null || string.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return service.findByCode(string.trim());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +1,26 @@
|
||||
package com.ecep.contract.converter;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import com.ecep.contract.service.VendorGroupService;
|
||||
import com.ecep.contract.vo.VendorGroupVo;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
public class VendorGroupStringConverter extends EntityStringConverter<VendorGroupVo> {
|
||||
@Lazy
|
||||
@Autowired
|
||||
public class VendorGroupStringConverter extends StringConverter<VendorGroupVo> {
|
||||
private VendorGroupService service;
|
||||
|
||||
public VendorGroupStringConverter() {
|
||||
|
||||
public VendorGroupStringConverter(VendorGroupService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
setInitialized(group -> service.findById(group.getId()));
|
||||
setSuggestion(service::search);
|
||||
@Override
|
||||
public String toString(VendorGroupVo object) {
|
||||
return object == null ? "" : object.getCode() + " " + object.getName();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VendorGroupVo fromString(String string) {
|
||||
return service.findByCode(string);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.controlsfx.control.TaskProgressView;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -21,6 +23,8 @@ import lombok.Data;
|
||||
|
||||
@Service
|
||||
public class CloudRkService extends QueryService<CloudRkVo, CloudRkViewModel> {
|
||||
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class EntInfo {
|
||||
@@ -69,6 +73,10 @@ public class CloudRkService extends QueryService<CloudRkVo, CloudRkViewModel> {
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public Page<CloudRkVo> findAllByCompany(CompanyVo company) {
|
||||
return findAll(ParamUtils.builder().equals("company", company.getId()).build(), Pageable.unpaged());
|
||||
}
|
||||
|
||||
public boolean checkBlackListUpdateElapse(CompanyVo company, CloudRkVo cloudRk) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'checkBlackListUpdateElapse'");
|
||||
@@ -78,4 +86,12 @@ public class CloudRkService extends QueryService<CloudRkVo, CloudRkViewModel> {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'updateBlackList'");
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
List<CloudRkVo> list = findAllByCompany(from).getContent();
|
||||
for (CloudRkVo item : list) {
|
||||
item.setCompanyId(to.getId());
|
||||
save(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -77,4 +79,16 @@ public class CloudTycService extends QueryService<CloudTycVo, CloudTycInfoViewMo
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public Page<CloudTycVo> findAllByCompany(CompanyVo company) {
|
||||
return findAll(ParamUtils.builder().equals("company", company.getId()).build(), Pageable.unpaged());
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
List<CloudTycVo> list = findAllByCompany(from).getContent();
|
||||
for (CloudTycVo item : list) {
|
||||
item.setCompanyId(to.getId());
|
||||
save(item);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -32,4 +33,21 @@ public class CompanyContactService extends QueryService<CompanyContactVo, Compan
|
||||
return page.getContent().getFirst();
|
||||
}
|
||||
|
||||
public List<CompanyContactVo> findAllByCompany(CompanyVo company, LocalDate beginDate, LocalDate endDate) {
|
||||
return findAll(ParamUtils.builder()
|
||||
.equals("company", company.getId())
|
||||
.between("setupDate", beginDate, endDate)
|
||||
.build(), Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
List<CompanyContactVo> contacts = findAllByCompany(from, LocalDate.MIN, LocalDate.MAX);
|
||||
if (contacts == null || contacts.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (CompanyContactVo contact : contacts) {
|
||||
contact.setCompanyId(to.getId());
|
||||
save(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,12 @@ public class CompanyCustomerEntityService extends QueryService<CompanyCustomerEn
|
||||
.equals("customer", customer.getId()).build(), Pageable.unpaged())
|
||||
.getContent();
|
||||
}
|
||||
|
||||
public void mergeTo(CustomerVo from, CustomerVo to) {
|
||||
List<CompanyCustomerEntityVo> fromEntities = findAllByCustomer(from);
|
||||
for (CompanyCustomerEntityVo fromEntity : fromEntities) {
|
||||
fromEntity.setCustomerId(to.getId());
|
||||
save(fromEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,4 +121,12 @@ public class CompanyCustomerFileService extends QueryService<CustomerFileVo, Cus
|
||||
public CustomerFileVo save(CustomerFileVo entity) {
|
||||
return super.save(entity);
|
||||
}
|
||||
|
||||
public void mergeTo(CustomerVo from, CustomerVo to) {
|
||||
List<CustomerFileVo> fromFiles = findAllByCustomer(from);
|
||||
for (CustomerFileVo fromFile : fromFiles) {
|
||||
fromFile.setCustomer(to.getId());
|
||||
save(fromFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.File;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import com.ecep.contract.util.MyStringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -70,16 +71,7 @@ public class CompanyOldNameService extends QueryService<CompanyOldNameVo, Compan
|
||||
}
|
||||
|
||||
public CompanyOldNameVo findMatchByDate(CompanyVo company, LocalDate localDate) {
|
||||
Page<CompanyOldNameVo> page = findAll(ParamUtils.builder()
|
||||
.equals("ambiguity", false)
|
||||
.equals("company", company.getId())
|
||||
.and(b -> b.isNotNull("beginDate").greaterThan("beginDate", localDate))
|
||||
.and(b -> b.isNotNull("endDate").lessThan("endDate", localDate))
|
||||
.build(), Pageable.ofSize(1));
|
||||
if (page.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return page.getContent().getFirst();
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<CompanyOldNameVo> findAllByCompanyAndName(CompanyVo company, String oldName) {
|
||||
@@ -90,4 +82,13 @@ public class CompanyOldNameService extends QueryService<CompanyOldNameVo, Compan
|
||||
public List<CompanyOldNameVo> findAllByCompany(IdentityEntity company) {
|
||||
return findAll(ParamUtils.equal("company", company.getId()), Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
List<CompanyOldNameVo> fromOldNames = findAllByCompany(from);
|
||||
for (CompanyOldNameVo fromOldName : fromOldNames) {
|
||||
fromOldName.setMemo(MyStringUtils.appendIfAbsent(fromOldName.getMemo(), "转自 " + from.getId()));
|
||||
fromOldName.setCompanyId(to.getId());
|
||||
save(fromOldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ecep.contract.SpringApp;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
@@ -62,9 +63,22 @@ public class CompanyService extends QueryService<CompanyVo, CompanyViewModel> {
|
||||
return findAll(params, Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public void merge(CompanyVo company, CompanyVo updater) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'merge'");
|
||||
public void merge(CompanyVo from, CompanyVo to) {
|
||||
|
||||
SpringApp.getBean(CloudRkService.class).mergeTo(from, to);
|
||||
SpringApp.getBean(CloudTycService.class).mergeTo(from, to);
|
||||
SpringApp.getBean(YongYouU8Service.class).mergeTo(from, to);
|
||||
|
||||
SpringApp.getBean(CompanyOldNameService.class).mergeTo(from, to);
|
||||
SpringApp.getBean(CompanyContactService.class).mergeTo(from, to);
|
||||
|
||||
// 供应商和客户
|
||||
SpringApp.getBean(VendorService.class).mergeTo(from, to);
|
||||
SpringApp.getBean(CustomerService.class).mergeTo(from, to);
|
||||
|
||||
SpringApp.getBean(ContractService.class).mergeTo(from, to);
|
||||
SpringApp.getBean(CompanyContactService.class).mergeTo(from, to);
|
||||
delete(from);
|
||||
}
|
||||
|
||||
public CompanyVo createNewCompany(String newCompanyName) {
|
||||
|
||||
@@ -5,6 +5,9 @@ import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.util.MyStringUtils;
|
||||
import com.ecep.contract.vo.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
@@ -20,10 +23,6 @@ import com.ecep.contract.constant.ContractConstant;
|
||||
import com.ecep.contract.util.ContractUtils;
|
||||
import com.ecep.contract.util.ParamUtils;
|
||||
import com.ecep.contract.vm.ContractViewModel;
|
||||
import com.ecep.contract.vo.ContractFileVo;
|
||||
import com.ecep.contract.vo.ContractVo;
|
||||
import com.ecep.contract.vo.ProjectVo;
|
||||
import com.ecep.contract.vo.VendorVo;
|
||||
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "contract")
|
||||
@@ -158,10 +157,24 @@ public class ContractService extends QueryService<ContractVo, ContractViewModel>
|
||||
.build(), Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public List<ContractVo> findAllByCompanyCustomer(CustomerVo customer, LocalDate beginDate, LocalDate endDate) {
|
||||
return findAll(ParamUtils.builder()
|
||||
.equals("company", customer.getCompanyId())
|
||||
.between("setupDate", beginDate, endDate)
|
||||
.build(), Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public List<ContractVo> findAllByCompany(CompanyVo company, LocalDate beginDate, LocalDate endDate) {
|
||||
return findAll(ParamUtils.builder()
|
||||
.equals("company", company.getId())
|
||||
.between("setupDate", beginDate, endDate)
|
||||
.build(), Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public List<ContractVo> findAllSalesByProject(ProjectVo project) {
|
||||
return findAll(ParamUtils.builder()
|
||||
.equals("parentCode", "")
|
||||
.equals("project", project.getId()).build(),
|
||||
.equals("parentCode", "")
|
||||
.equals("project", project.getId()).build(),
|
||||
Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
@@ -183,4 +196,18 @@ public class ContractService extends QueryService<ContractVo, ContractViewModel>
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'syncContractFile'");
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
|
||||
List<ContractVo> contracts = findAllByCompany(from, LocalDate.MIN, LocalDate.MAX);
|
||||
if (contracts == null || contracts.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ContractVo contract : contracts) {
|
||||
contract.setDescription(MyStringUtils.appendIfAbsent(contract.getDescription(), "转自 " + from.getId()));
|
||||
contract.setCompanyId(to.getId());
|
||||
save(contract);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ import org.springframework.stereotype.Service;
|
||||
import com.ecep.contract.vm.ContractTypeViewModel;
|
||||
import com.ecep.contract.vo.ContractTypeVo;
|
||||
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "contract-type")
|
||||
public class ContractTypeService extends QueryService<ContractTypeVo, ContractTypeViewModel> {
|
||||
|
||||
@@ -30,11 +30,7 @@ public class CustomerService extends QueryService<CustomerVo, CompanyCustomerVie
|
||||
}
|
||||
|
||||
public CustomerVo findByCompany(CompanyVo company) {
|
||||
Page<CustomerVo> page = findAll(ParamUtils.equal("company", company.getId()), Pageable.ofSize(1));
|
||||
if (page.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return page.getContent().getFirst();
|
||||
return findOneByProperty("company", company.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,4 +136,43 @@ public class CustomerService extends QueryService<CustomerVo, CompanyCustomerVie
|
||||
// 替换文件名中的非法字符
|
||||
return fileName.replaceAll("[/\\:*?\"<>|]", "_");
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
CustomerVo fromCustomer = findByCompany(from);
|
||||
if (fromCustomer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CustomerVo toCustomer = findByCompany(to);
|
||||
if (toCustomer == null) {
|
||||
// 直接修改关联
|
||||
fromCustomer.setCompanyId(to.getId());
|
||||
save(fromCustomer);
|
||||
return;
|
||||
}
|
||||
|
||||
mergeTo(fromCustomer, toCustomer);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并客户
|
||||
* 1. 删除源客户对象
|
||||
* 2. 删除源客户对象关联的文件
|
||||
* 3. 修改目标客户对象的关联公司
|
||||
* 4. 修改目标客户对象的关联文件
|
||||
*
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
public void mergeTo(CustomerVo from, CustomerVo to) {
|
||||
// file
|
||||
CompanyCustomerFileService companyCustomerFileService = SpringApp.getBean(CompanyCustomerFileService.class);
|
||||
companyCustomerFileService.mergeTo(from, to);
|
||||
// entity
|
||||
CompanyCustomerEntityService companyCustomerEntityService = SpringApp.getBean(CompanyCustomerEntityService.class);
|
||||
companyCustomerEntityService.mergeTo(from, to);
|
||||
// 删除源客户对象
|
||||
delete(from);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,81 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.ecep.contract.converter.DepartmentStringConverter;
|
||||
import com.ecep.contract.vm.DepartmentViewModel;
|
||||
import com.ecep.contract.vo.DepartmentVo;
|
||||
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "department")
|
||||
public class DepartmentService extends QueryService<DepartmentVo, DepartmentViewModel> {
|
||||
|
||||
private final DepartmentStringConverter stringConverter = new DepartmentStringConverter(this);
|
||||
|
||||
@Cacheable(key = "#p0")
|
||||
@Override
|
||||
public DepartmentVo findById(Integer id) {
|
||||
return super.findById(id);
|
||||
}
|
||||
|
||||
public DepartmentVo findByName(String name) {
|
||||
try {
|
||||
return async("findByName", name, String.class).handle((response, ex) -> {
|
||||
DepartmentVo newEntity = createNewEntity();
|
||||
return updateValue(newEntity, response);
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("查询实体失败" + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
public DepartmentVo findByCode(String code) {
|
||||
try {
|
||||
return async("findByCode", code, String.class).handle((response, ex) -> {
|
||||
if (ex != null) {
|
||||
throw new RuntimeException("远程方法+findByCode+调用失败", ex);
|
||||
}
|
||||
DepartmentVo newEntity = createNewEntity();
|
||||
return updateValue(newEntity, response);
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("查询实体失败" + code, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Cacheable(key = "'departments'")
|
||||
@Override
|
||||
public List<DepartmentVo> findAll() {
|
||||
return super.findAll();
|
||||
}
|
||||
|
||||
@Caching(evict = {
|
||||
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'departments'"),
|
||||
})
|
||||
@Override
|
||||
public void delete(DepartmentVo entity) {
|
||||
super.delete(entity);
|
||||
}
|
||||
|
||||
@Caching(evict = {
|
||||
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'departments'"),
|
||||
})
|
||||
@Override
|
||||
public DepartmentVo save(DepartmentVo entity) {
|
||||
return super.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringConverter<DepartmentVo> getStringConverter() {
|
||||
return stringConverter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.ecep.contract.vo.DepartmentVo;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.ecep.contract.vm.EmployeeRoleViewModel;
|
||||
@@ -11,11 +15,38 @@ import com.ecep.contract.vo.FunctionVo;
|
||||
@Service
|
||||
public class EmployeeRoleService extends QueryService<EmployeeRoleVo, EmployeeRoleViewModel> {
|
||||
|
||||
public List<FunctionVo> getFunctionsByRoleId(int roleId) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getFunctionsByRoleId'");
|
||||
public List<FunctionVo> getFunctionsByRole(EmployeeRoleVo role) {
|
||||
try {
|
||||
return async("getFunctionsByRoleId", role.getId(), Integer.class).handle((response, ex) -> {
|
||||
if (ex != null) {
|
||||
throw new RuntimeException("远程方法+getFunctionsByRoleId+调用失败", ex);
|
||||
}
|
||||
List<FunctionVo> list = new ArrayList<>();
|
||||
try {
|
||||
objectMapper.readerForUpdating(list)
|
||||
.forType(objectMapper.getTypeFactory().constructCollectionType(List.class, FunctionVo.class))
|
||||
.readValue(response);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return list;
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("查询实体失败, Function#" + role.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void saveRoleFunctions(EmployeeRoleVo role, List<FunctionVo> functions) {
|
||||
try {
|
||||
async("saveRoleFunctions", new Object[]{role.getId(), functions.stream().mapToInt(FunctionVo::getId).toArray()}, new Object[]{Integer.class, Integer[].class}).handle((response, ex) -> {
|
||||
if (ex != null) {
|
||||
throw new RuntimeException("远程方法+saveRoleFunctions+调用失败", ex);
|
||||
}
|
||||
return null;
|
||||
}).get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("保存角色的功能失败, 角色#" + role.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,4 +49,12 @@ public class VendorEntityService extends QueryService<VendorEntityVo, CompanyVen
|
||||
// 确保返回正确的服务名称
|
||||
return "vendorEntityService";
|
||||
}
|
||||
|
||||
public void mergeTo(VendorVo from, VendorVo to) {
|
||||
List<VendorEntityVo> fromEntities = findByVendor(from);
|
||||
for (VendorEntityVo fromEntity : fromEntities) {
|
||||
fromEntity.setVendorId(to.getId());
|
||||
save(fromEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,33 +97,13 @@ public class VendorFileService extends QueryService<VendorFileVo, CompanyVendorF
|
||||
}
|
||||
|
||||
public void verify(VendorVo companyVendor, LocalDate verifyDate, MessageHolder holder) {
|
||||
// 查询所有评价表
|
||||
List<VendorFileVo> files = findAllByVendorAndType(companyVendor, VendorFileType.EvaluationForm);
|
||||
if (files == null || files.isEmpty()) {
|
||||
holder.error("未见供应商评价");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检索 验证日期最近一年内的有效评价表,日期宽限7天
|
||||
LocalDate begin = verifyDate.plusYears(-1);
|
||||
VendorFileVo vendorFile = files.stream()
|
||||
.filter(v -> v.getSignDate() != null && v.isValid())
|
||||
.filter(v -> MyDateTimeUtils.dateValidFilter(v.getSignDate(), begin, verifyDate, 7))
|
||||
.findFirst().orElse(null);
|
||||
if (vendorFile == null) {
|
||||
// 检索最后一个有效评价表
|
||||
VendorFileVo latestFile = files.stream()
|
||||
.filter(v -> v.getSignDate() != null && v.isValid())
|
||||
.max(Comparator.comparing(VendorFileVo::getSignDate))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
if (latestFile == null) {
|
||||
holder.error("未匹配的供应商评价");
|
||||
return;
|
||||
}
|
||||
// 提示评价表已过期
|
||||
holder.error("供应商评价已过期:" + latestFile.getSignDate() + ", 检测日期:" + verifyDate);
|
||||
}
|
||||
public List<VendorFileVo> findAllByVendor(VendorVo vendor) {
|
||||
return findAll(ParamUtils.builder()
|
||||
.equals("vendor", vendor.getId())
|
||||
.build(), Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public List<VendorFileVo> findAllByVendorAndType(VendorVo vendor, VendorFileType type) {
|
||||
@@ -132,4 +112,12 @@ public class VendorFileService extends QueryService<VendorFileVo, CompanyVendorF
|
||||
.equals("type", type.name())
|
||||
.build(), Pageable.unpaged()).getContent();
|
||||
}
|
||||
|
||||
public void mergeTo(VendorVo from, VendorVo to) {
|
||||
List<VendorFileVo> fromFiles = findAllByVendor(from);
|
||||
for (VendorFileVo fromFile : fromFiles) {
|
||||
fromFile.setVendorId(to.getId());
|
||||
save(fromFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import com.ecep.contract.converter.VendorGroupStringConverter;
|
||||
import com.ecep.contract.model.VendorGroup;
|
||||
import com.ecep.contract.util.ParamUtils;
|
||||
import com.ecep.contract.vm.VendorGroupViewModel;
|
||||
import com.ecep.contract.vo.VendorGroupVo;
|
||||
import javafx.util.StringConverter;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
@@ -15,6 +17,8 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "vendor-group")
|
||||
public class VendorGroupService extends QueryService<VendorGroupVo, VendorGroupViewModel> {
|
||||
|
||||
private VendorGroupStringConverter stringConverter = new VendorGroupStringConverter(this);
|
||||
@Cacheable(key = "#id")
|
||||
@Override
|
||||
public VendorGroupVo findById(Integer id) {
|
||||
@@ -53,4 +57,9 @@ public class VendorGroupService extends QueryService<VendorGroupVo, VendorGroupV
|
||||
public void delete(VendorGroupVo entity) {
|
||||
super.delete(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VendorGroupStringConverter getStringConverter() {
|
||||
return stringConverter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.VendorType;
|
||||
@@ -21,11 +8,20 @@ import com.ecep.contract.model.VendorCatalog;
|
||||
import com.ecep.contract.util.CompanyUtils;
|
||||
import com.ecep.contract.util.FileUtils;
|
||||
import com.ecep.contract.util.MyStringUtils;
|
||||
import com.ecep.contract.util.ParamUtils;
|
||||
import com.ecep.contract.vm.CompanyVendorViewModel;
|
||||
import com.ecep.contract.vo.VendorVo;
|
||||
import com.ecep.contract.vo.CompanyVo;
|
||||
import com.ecep.contract.vo.ContractVo;
|
||||
import com.ecep.contract.vo.VendorVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "vendor")
|
||||
@@ -58,11 +54,7 @@ public class VendorService extends QueryService<VendorVo, CompanyVendorViewModel
|
||||
|
||||
@Cacheable(key = "'company-'+#p0.id")
|
||||
public VendorVo findByCompany(CompanyVo company) {
|
||||
Page<VendorVo> page = findAll(ParamUtils.equal("company", company.getId()), Pageable.ofSize(1));
|
||||
if (page.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return page.getContent().getFirst();
|
||||
return findOneByProperty("company", company.getId());
|
||||
}
|
||||
|
||||
public void verify(ContractVo contract, MessageHolder holder) {
|
||||
@@ -189,4 +181,32 @@ public class VendorService extends QueryService<VendorVo, CompanyVendorViewModel
|
||||
public void delete(VendorVo entity) {
|
||||
super.delete(entity);
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
VendorVo fromCustomer = findByCompany(from);
|
||||
if (fromCustomer == null) {
|
||||
return;
|
||||
}
|
||||
VendorVo toCustomer = findByCompany(to);
|
||||
if (toCustomer == null) {
|
||||
// 直接修改关联
|
||||
fromCustomer.setCompanyId(to.getId());
|
||||
save(fromCustomer);
|
||||
return;
|
||||
}
|
||||
|
||||
mergeTo(fromCustomer, toCustomer);
|
||||
}
|
||||
|
||||
public void mergeTo(VendorVo from, VendorVo to) {
|
||||
// file
|
||||
VendorFileService companyVendorFileService = SpringApp.getBean(VendorFileService.class);
|
||||
companyVendorFileService.mergeTo(from, to);
|
||||
// entity
|
||||
VendorEntityService companyCustomerEntityService = SpringApp.getBean(VendorEntityService.class);
|
||||
companyCustomerEntityService.mergeTo(from, to);
|
||||
// 删除源客户对象
|
||||
delete(from);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.ecep.contract.service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.controlsfx.control.TaskProgressView;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -78,4 +81,15 @@ public class YongYouU8Service extends QueryService<CloudYuVo, CloudYuInfoViewMod
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public Page<CloudYuVo> findAllByCompany(CompanyVo company) {
|
||||
return findAll(ParamUtils.builder().equals("company", company.getId()).build(), Pageable.unpaged());
|
||||
}
|
||||
|
||||
public void mergeTo(CompanyVo from, CompanyVo to) {
|
||||
List<CloudYuVo> list = findAllByCompany(from).getContent();
|
||||
for (CloudYuVo item : list) {
|
||||
item.setCompanyId(to.getId());
|
||||
save(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.ecep.contract.task;
|
||||
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.vo.CompanyVo;
|
||||
import javafx.application.Platform;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* 公司合并客户端任务器
|
||||
* 通过WebSocket连接与服务器端通信,执行公司合并操作
|
||||
*/
|
||||
|
||||
public class CompanyMergeClientTasker extends Tasker<Object> implements WebSocketClientTasker {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private CompanyVo company;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private List<String> nameList;
|
||||
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return "CompanyMergeTask";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(long current, long total) {
|
||||
super.updateProgress(current, total);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
return callRemoteTask(holder, getLocale(), company.getId(), nameList.toArray());
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,21 @@
|
||||
package com.ecep.contract.task;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
|
||||
public class ContractGroupSyncTask extends Tasker<Object>{
|
||||
public class ContractGroupSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
@Override
|
||||
public Object execute(MessageHolder holder) {
|
||||
return null;
|
||||
public String getTaskName() {
|
||||
return "ContractGroupSyncTask";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(MessageHolder holder) {
|
||||
return callRemoteTask(holder, getLocale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(long current, long total) {
|
||||
super.updateProgress(current, total);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
package com.ecep.contract.task;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
|
||||
public class ContractKindSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
public static final String TASK_NAME = "ContractKindSyncTask";
|
||||
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return TASK_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(long workDone, long max) {
|
||||
super.updateProgress(workDone, max);
|
||||
}
|
||||
|
||||
public class ContractKindSyncTask extends Tasker<Object> {
|
||||
@Override
|
||||
public Object execute(MessageHolder holder) {
|
||||
return null;
|
||||
return callRemoteTask(holder, getLocale());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
import com.ecep.contract.service.YongYouU8Service;
|
||||
|
||||
/**
|
||||
* 合同同步任务
|
||||
@@ -14,15 +12,6 @@ import com.ecep.contract.service.YongYouU8Service;
|
||||
public class ContractSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractSyncTask.class);
|
||||
|
||||
private YongYouU8Service yongYouU8Service;
|
||||
|
||||
private YongYouU8Service getYongYouU8Service() {
|
||||
if (yongYouU8Service == null) {
|
||||
yongYouU8Service = SpringApp.getBean(YongYouU8Service.class);
|
||||
}
|
||||
return yongYouU8Service;
|
||||
}
|
||||
|
||||
public String getTaskName() {
|
||||
return "ContractSyncTask";
|
||||
}
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
package com.ecep.contract.task;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
|
||||
/**
|
||||
* 合同类型同步任务
|
||||
*/
|
||||
public class ContractTypeSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return "ContractTypeSyncTask";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(long current, long total) {
|
||||
super.updateProgress(current, total);
|
||||
}
|
||||
|
||||
public class ContractTypeSyncTask extends Tasker<Object> {
|
||||
@Override
|
||||
public Object execute(MessageHolder holder) {
|
||||
return null;
|
||||
// 调用远程WebSocket任务
|
||||
return callRemoteTask(holder, Locale.getDefault());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
package com.ecep.contract.task;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import java.util.Locale;
|
||||
|
||||
public class CustomerClassSyncTask extends Tasker<Object> {
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
|
||||
public class CustomerClassSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
public static final String TASK_NAME = "CustomerClassSyncTask";
|
||||
private static final Logger logger = LoggerFactory.getLogger(CustomerClassSyncTask.class);
|
||||
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return TASK_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'execute'");
|
||||
updateTitle("用友U8系统-同步客户分类");
|
||||
return callRemoteTask(holder, Locale.getDefault());
|
||||
}
|
||||
|
||||
// 显式重写 updateProgress 以解决方法隐藏冲突
|
||||
@Override
|
||||
public void updateProgress(long workDone, long max) {
|
||||
super.updateProgress(workDone, max);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
package com.ecep.contract.task;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
|
||||
/**
|
||||
* 同步客户任务
|
||||
*/
|
||||
public class CustomerSyncTask extends Tasker<Object> {
|
||||
public class CustomerSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
|
||||
public static final String TASK_NAME = "CustomerSyncTask";
|
||||
private static final Logger logger = LoggerFactory.getLogger(CustomerSyncTask.class);
|
||||
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return TASK_NAME;
|
||||
}
|
||||
|
||||
// 显式重写 updateProgress 以解决方法隐藏冲突
|
||||
@Override
|
||||
public void updateProgress(long workDone, long max) {
|
||||
super.updateProgress(workDone, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
updateTitle("用友U8系统-同步客户");
|
||||
return null;
|
||||
return callRemoteTask(holder, Locale.getDefault());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
package com.ecep.contract.task;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
|
||||
public class VendorClassSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
public static final String TASK_NAME = "VendorClassSyncTask";
|
||||
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return TASK_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(long current, long total) {
|
||||
// 直接使用父类的updateProgress方法
|
||||
super.updateProgress(current, total);
|
||||
}
|
||||
|
||||
public class VendorClassSyncTask extends Tasker<Object> {
|
||||
@Override
|
||||
public Object execute(MessageHolder holder) {
|
||||
return null;
|
||||
// 使用callRemoteTask调用远程任务
|
||||
updateTitle("用友U8系统-同步供应商分类");
|
||||
return callRemoteTask(holder, Locale.getDefault());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,28 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.WebSocketClientTasker;
|
||||
|
||||
/**
|
||||
* 供应商同步任务
|
||||
*/
|
||||
public class VendorSyncTask extends Tasker<Object> {
|
||||
public class VendorSyncTask extends Tasker<Object> implements WebSocketClientTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(VendorSyncTask.class);
|
||||
private static final String TASK_NAME = "VendorSyncTask";
|
||||
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return TASK_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProgress(long current, long total) {
|
||||
super.updateProgress(current, total);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
updateTitle("用友U8系统-同步供应商");
|
||||
return null;
|
||||
return callRemoteTask(holder, getLocale());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.ecep.contract.manager.cloud.rk.CloudRkManagerWindowController">
|
||||
fx:controller="com.ecep.contract.controller.cloud.rk.CloudRkManagerWindowController">
|
||||
<children>
|
||||
<MenuBar VBox.vgrow="NEVER">
|
||||
<menus>
|
||||
@@ -39,7 +39,6 @@
|
||||
<Menu mnemonicParsing="false" text="Help">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="数据修复" onAction="#onDataRepairAction"/>
|
||||
<MenuItem mnemonicParsing="false" text="数据迁移" onAction="#onDateTransferAction"/>
|
||||
<MenuItem mnemonicParsing="false" text="About MyHelloApp"/>
|
||||
</items>
|
||||
</Menu>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<?import org.controlsfx.control.ListSelectionView?>
|
||||
<BorderPane fx:id="root" maxHeight="900" maxWidth="1024" minHeight="300" minWidth="200" prefHeight="500.0"
|
||||
prefWidth="800.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.ecep.contract.controller.permission.EmployeeFunctionsManagerWindowController">
|
||||
fx:controller="com.ecep.contract.controller.permission.EmployeeFunctionWindowController">
|
||||
<center>
|
||||
<TabPane fx:id="tabPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minWidth="150.0"
|
||||
tabClosingPolicy="UNAVAILABLE" tabMaxWidth="100.0" tabMinWidth="40.0">
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<Menu text="文件(_F)">
|
||||
<items>
|
||||
<MenuItem onAction="#onCreateNewAction" text="新建…(_N)"/>
|
||||
<MenuItem onAction="#onReBuildFilesAction" text="同步…(_R)"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem mnemonicParsing="false" text="Preferences…"/>
|
||||
</items>
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import org.controlsfx.control.ListSelectionView?>
|
||||
|
||||
<BorderPane fx:id="root" maxHeight="900" maxWidth="1024" minHeight="300" minWidth="200" prefHeight="500.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ecep.contract.controller.permission.EmployeeRoleManagerWindowController">
|
||||
<BorderPane fx:id="root" maxHeight="900" maxWidth="1024" minHeight="300" minWidth="200" prefHeight="500.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/22"
|
||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ecep.contract.controller.permission.EmployeeRoleWindowController">
|
||||
<center>
|
||||
<TabPane fx:id="tabPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minWidth="150.0" tabClosingPolicy="UNAVAILABLE" tabMaxWidth="100.0" tabMinWidth="40.0">
|
||||
<tabs>
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<Menu text="文件(_F)">
|
||||
<items>
|
||||
<MenuItem onAction="#onCreateNewAction" text="新建…(_N)" />
|
||||
<MenuItem onAction="#onReBuildFilesAction" text="同步…(_R)" />
|
||||
<SeparatorMenuItem mnemonicParsing="false" />
|
||||
<MenuItem mnemonicParsing="false" text="Preferences…" />
|
||||
</items>
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
<parent>
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>Contract-Manager</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
package com.ecep.contract.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.ecep.contract.util.HibernateProxyUtils;
|
||||
import com.ecep.contract.vo.EmployeeRoleVo;
|
||||
import com.ecep.contract.vo.FunctionVo;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@jakarta.persistence.Entity
|
||||
@@ -56,12 +43,12 @@ public class EmployeeRole implements IdentityEntity, NamedEntity, Voable<Employe
|
||||
@Column(name = "IS_ACTIVE")
|
||||
private boolean active = true;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
|
||||
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinTable(name = "EMPLOYEE_ROLE_FUNCTIONS", joinColumns = @JoinColumn(name = "ROLE_ID"), inverseJoinColumns = @JoinColumn(name = "FUNC_ID"))
|
||||
@JsonIgnore
|
||||
private java.util.List<Function> functions = new java.util.ArrayList<>();
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
|
||||
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinTable(name = "EMPLOYEE_ROLES", joinColumns = @JoinColumn(name = "ROLE_ID"), inverseJoinColumns = @JoinColumn(name = "EMPLOYEE_ID"))
|
||||
@JsonIgnore
|
||||
private java.util.List<Employee> employees = new java.util.ArrayList<>();
|
||||
@@ -93,22 +80,6 @@ public class EmployeeRole implements IdentityEntity, NamedEntity, Voable<Employe
|
||||
vo.setSystemAdministrator(isSystemAdministrator());
|
||||
vo.setManager(isManager());
|
||||
vo.setActive(isActive());
|
||||
|
||||
// 转换functions列表
|
||||
if (getFunctions() != null && !getFunctions().isEmpty()) {
|
||||
List<FunctionVo> functionVos = new ArrayList<>();
|
||||
for (Function function : getFunctions()) {
|
||||
if (function != null) {
|
||||
FunctionVo functionVo = new FunctionVo();
|
||||
functionVo.setId(function.getId());
|
||||
functionVo.setName(function.getName());
|
||||
functionVo.setKey(function.getKey());
|
||||
functionVos.add(functionVo);
|
||||
}
|
||||
}
|
||||
vo.setFunctions(functionVos);
|
||||
}
|
||||
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class HttpJsonUtils {
|
||||
public static void post(String url,
|
||||
public static void post(String url, Map<String, String> headers,
|
||||
Consumer<Map<String, Object>> data,
|
||||
Consumer<JsonNode> consumer,
|
||||
ObjectMapper objectMapper, Proxy proxy) throws IOException {
|
||||
@@ -24,6 +24,10 @@ public class HttpJsonUtils {
|
||||
conn.usingProxy();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
if (headers != null) {
|
||||
headers.forEach(conn::setRequestProperty);
|
||||
}
|
||||
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
PrintWriter writer = new PrintWriter(conn.getOutputStream());
|
||||
@@ -37,12 +41,16 @@ public class HttpJsonUtils {
|
||||
|
||||
}
|
||||
|
||||
public static void get(String url, Consumer<JsonNode> consumer, ObjectMapper objectMapper, Proxy proxy) throws IOException {
|
||||
public static void get(String url, Map<String, String> headers,
|
||||
Consumer<JsonNode> consumer, ObjectMapper objectMapper, Proxy proxy) throws IOException {
|
||||
URI uri = URI.create(url);
|
||||
HttpURLConnection conn = (HttpURLConnection) (proxy == null ? uri.toURL().openConnection() : uri.toURL().openConnection(proxy));
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setRequestProperty("Accept", "application/json, text/plain, */*");
|
||||
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36");
|
||||
if (headers != null) {
|
||||
headers.forEach(conn::setRequestProperty);
|
||||
}
|
||||
try (InputStream is = conn.getInputStream()) {
|
||||
JsonNode json = objectMapper.readTree(is);
|
||||
consumer.accept(json);
|
||||
|
||||
@@ -18,6 +18,7 @@ public class EmployeeRoleVo implements IdentityEntity, NamedEntity, Serializable
|
||||
private boolean manager = false;
|
||||
private boolean active = true;
|
||||
private String description;
|
||||
private List<FunctionVo> functions;
|
||||
// 角色功能通过功能列表查询
|
||||
// private List<FunctionVo> functions;
|
||||
|
||||
}
|
||||
182
docs/task/tasker_implementation_guide.md
Normal file
182
docs/task/tasker_implementation_guide.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Tasker实现规范指南
|
||||
|
||||
## 1. Tasker架构概述
|
||||
|
||||
Tasker是系统中用于执行异步任务的核心框架,主要用于处理耗时操作并提供实时进度反馈。Tasker架构包括:
|
||||
|
||||
- **Tasker基类**:提供任务执行的基础框架和通信功能
|
||||
- **WebSocketServerTasker接口**:定义WebSocket通信任务的规范
|
||||
- **MessageHolder**:用于在任务执行过程中传递消息和更新进度
|
||||
|
||||
## 2. 服务器端Tasker实现规范
|
||||
|
||||
### 2.1 基本结构
|
||||
|
||||
服务器端Tasker实现应遵循以下结构:
|
||||
|
||||
```java
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class YourTaskNameTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
// 服务依赖
|
||||
@Setter
|
||||
private YourService service;
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化任务标题
|
||||
updateTitle("任务标题");
|
||||
// 初始化参数
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
// 实现业务逻辑
|
||||
// 使用holder.info()、holder.error()等方法反馈消息
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 关键注意事项
|
||||
|
||||
1. **继承与实现**:
|
||||
- 必须继承`Tasker<Object>`基类
|
||||
- 必须实现`WebSocketServerTasker`接口
|
||||
|
||||
2. **方法实现**:
|
||||
- **不要重复实现**Tasker基类已提供的handler设置方法:`setMessageHandler`、`setTitleHandler`、`setPropertyHandler`、`setProgressHandler`
|
||||
- 必须实现`init`方法,设置任务标题和初始化参数
|
||||
- 必须实现`execute`方法,实现具体业务逻辑
|
||||
|
||||
3. **进度和消息反馈**:
|
||||
- 使用`updateProgress`方法提供进度更新
|
||||
- 使用`MessageHolder`的`info`、`error`、`debug`等方法提供消息反馈
|
||||
|
||||
4. **任务取消**:
|
||||
- 在适当的地方检查`isCancelled()`状态,支持任务取消
|
||||
|
||||
5. **注册要求**:
|
||||
- 任务类必须在`tasker_mapper.json`中注册
|
||||
|
||||
## 3. 客户端Tasker实现规范
|
||||
|
||||
客户端Tasker实现应遵循:
|
||||
|
||||
```java
|
||||
public class YourTaskNameTask extends Tasker<Object> {
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
// 客户端任务逻辑
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 通信规范
|
||||
|
||||
### 4.1 命名规范
|
||||
|
||||
- 客户端和服务器端对应的Tasker类应使用**相同的类名**
|
||||
- 示例:客户端的`ContractSyncAllTask`对应服务器端的`ContractSyncAllTask`
|
||||
|
||||
### 4.2 消息传递
|
||||
|
||||
- 使用`MessageHolder`进行消息传递
|
||||
- 支持不同级别的消息:INFO、ERROR、DEBUG
|
||||
|
||||
## 5. 最佳实践
|
||||
|
||||
1. **任务拆分**:
|
||||
- 将大型任务拆分为多个小任务,提高可维护性
|
||||
|
||||
2. **异常处理**:
|
||||
- 捕获并正确处理异常,使用`holder.error()`提供详细错误信息
|
||||
|
||||
3. **资源管理**:
|
||||
- 确保及时释放资源,特别是在任务取消的情况下
|
||||
|
||||
4. **日志记录**:
|
||||
- 使用`holder.debug()`记录调试信息
|
||||
- 使用`holder.info()`记录进度信息
|
||||
|
||||
5. **状态检查**:
|
||||
- 定期检查`isCancelled()`状态,确保任务可以被及时取消
|
||||
|
||||
## 6. 代码示例
|
||||
|
||||
### 6.1 服务器端Tasker示例
|
||||
|
||||
```java
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ExampleSyncTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
@Setter
|
||||
private ExampleService exampleService;
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
updateTitle("示例同步任务");
|
||||
// 从argsNode初始化参数
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
try {
|
||||
// 获取总记录数
|
||||
long total = exampleService.getTotalCount();
|
||||
holder.info("开始同步数据,共" + total + "条记录");
|
||||
|
||||
// 分批处理
|
||||
long processed = 0;
|
||||
List<ExampleEntity> entities = exampleService.getAllEntities();
|
||||
|
||||
for (ExampleEntity entity : entities) {
|
||||
// 检查是否取消
|
||||
if (isCancelled()) {
|
||||
holder.info("任务已取消");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 处理单个实体
|
||||
exampleService.processEntity(entity);
|
||||
processed++;
|
||||
|
||||
// 更新进度
|
||||
updateProgress(processed, total);
|
||||
if (processed % 100 == 0) {
|
||||
holder.info("已处理" + processed + "/" + total + "条记录");
|
||||
}
|
||||
}
|
||||
|
||||
holder.info("同步完成,共处理" + processed + "条记录");
|
||||
return processed;
|
||||
} catch (Exception e) {
|
||||
holder.error("同步失败: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 常见错误和避免方法
|
||||
|
||||
1. **重复实现handler方法**:
|
||||
- 错误:在子类中重复实现setMessageHandler等方法
|
||||
- 解决:删除子类中的这些方法,直接使用Tasker基类提供的实现
|
||||
|
||||
2. **缺少任务注册**:
|
||||
- 错误:任务类没有在tasker_mapper.json中注册
|
||||
- 解决:确保所有服务器端Tasker类都在配置文件中正确注册
|
||||
|
||||
3. **类名不匹配**:
|
||||
- 错误:客户端和服务器端Tasker类名不一致
|
||||
- 解决:确保两端使用相同的类名
|
||||
|
||||
4. **进度更新不正确**:
|
||||
- 错误:进度计算错误或没有更新
|
||||
- 解决:正确计算和更新进度,提高用户体验
|
||||
|
||||
5. **资源泄漏**:
|
||||
- 错误:未及时关闭数据库连接等资源
|
||||
- 解决:使用try-with-resources或在finally块中关闭资源
|
||||
@@ -0,0 +1,58 @@
|
||||
# 天眼查企业信用报告下载操作指南
|
||||
|
||||
## 操作目标
|
||||
使用 playwright MCP服务在天眼查平台上查询并下载目标企业的各类信用报告,包括:
|
||||
- 企业分析报告
|
||||
- 基础版企业信用报告
|
||||
- 专业版企业信用报告
|
||||
- 工商官网信息快照(图片格式)
|
||||
|
||||
## 准备工作
|
||||
1. 确保已登录天眼查账户
|
||||
2. 确认浏览器下载路径设置为:`C:\Users\SQQ\Downloads\`
|
||||
3. 确保网络连接稳定
|
||||
|
||||
## 操作步骤
|
||||
|
||||
### 1. 企业搜索
|
||||
- 页面导航到 `https://www.tianyancha.com/nsearch?key={企业名称}`
|
||||
- 或者使用如下步骤:
|
||||
- 在天眼查首页搜索框中输入目标企业全称
|
||||
- 点击搜索按钮或按回车键
|
||||
- 在搜索结果中点击目标企业进入详情页
|
||||
|
||||
### 2. 生成企业报告
|
||||
- 在企业详情页找到并点击"报告"按钮
|
||||
- 在弹出的报告选择框中,依次点击以下报告的"下载报告"按钮:
|
||||
- 企业分析报告
|
||||
- 专业版企业信用报告
|
||||
- 基础版企业信用报告
|
||||
- 每个报告下载点击有效时,页面上将提示会"报告已生成"
|
||||
|
||||
### 3. 下载PDF报告
|
||||
- 进入个人中心报告页面:https://www.tianyancha.com/usercenter/report
|
||||
- 却换到 `报告下载`
|
||||
- 等待对应的三个报告的状态变为"报告完成"
|
||||
- 依次找到对应的报告行
|
||||
- 点击对应报告行的操作列中的下载图标(操作列里有4个图标,第二个图标是下载,需要鼠标点击才会出现下载界面,这个图标是一个 SVG 图片,DOM 对象上没有任何文本,不能通过文本定位到这个按钮),不要使用"在线预览"的段落
|
||||
- 出现 报告下载 窗口
|
||||
- 格式选中:选中PDF格式
|
||||
- 点击下载按钮,
|
||||
- 关闭 报告下载 窗口
|
||||
- 不要使用"在线预览"的段落,那样会打开一个新页面,而不是下载文件
|
||||
- 不要使用 page.pdf 方法
|
||||
|
||||
### 4. 下载工商官网快照
|
||||
- 在企业详情页找到"工商信息"模块
|
||||
- 点击"工商官网快照"链接
|
||||
- 在新打开的页面中点击"下载图片"按钮
|
||||
|
||||
### 5. 移动文件
|
||||
- 将下载的PDF报告和图片文件移动至指定目录:`C:\Users\SQQ\Downloads\`
|
||||
|
||||
## 注意事项
|
||||
1. 报告生成需要一定时间,请耐心等待
|
||||
2. 下载前确保报告状态为"报告完成"
|
||||
3. 如果报告下载失败,可尝试重新点击下载按钮
|
||||
4. 工商官网快照为图片格式,其他报告为PDF格式
|
||||
5. 部分高级报告可能需要会员权限才能下载
|
||||
2
pom.xml
2
pom.xml
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>Contract-Manager</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>server</module>
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
<parent>
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>Contract-Manager</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>server</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
@@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>0.0.134-SNAPSHOT</version>
|
||||
<version>0.0.135-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.ecep.contract.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -25,10 +26,6 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.BlackReasonType;
|
||||
import com.ecep.contract.IEntityService;
|
||||
import com.ecep.contract.QueryService;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.cloud.CloudInfo;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.ds.company.model.CompanyBlackReason;
|
||||
@@ -146,80 +143,6 @@ public class CloudRkService implements IEntityService<CloudRk>, QueryService<Clo
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新黑名单列表
|
||||
*/
|
||||
public void updateBlackList(
|
||||
Company company, CloudRk cloudRk, BlackListUpdateContext context) throws IOException {
|
||||
List<String> companyNames = new ArrayList<>();
|
||||
companyNames.add(company.getName());
|
||||
// fixed 平台API使用企业名称,可能记录的是曾用名
|
||||
companyOldNameRepository.findAllByCompanyId(company.getId()).forEach(oldName -> {
|
||||
// 歧义的曾用名不采用
|
||||
if (oldName.getAmbiguity()) {
|
||||
return;
|
||||
}
|
||||
companyNames.add(oldName.getName());
|
||||
});
|
||||
|
||||
List<CompanyBlackReason> reasonList = new ArrayList<>();
|
||||
List<CompanyBlackReason> dbReasons = companyBlackReasonRepository.findAllByCompany(company);
|
||||
|
||||
companyNames.forEach(name -> {
|
||||
String url = context.getUrl() + URLEncoder.encode(name, StandardCharsets.UTF_8);
|
||||
try {
|
||||
HttpJsonUtils.get(url, json -> {
|
||||
if (!json.has("success") || !json.get("success").asBoolean()) {
|
||||
System.out.println("json = " + json.toPrettyString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (json.has("data")) {
|
||||
JsonNode data = json.get("data");
|
||||
try {
|
||||
if (data.has("blackReason")) {
|
||||
for (JsonNode reason : data.get("blackReason")) {
|
||||
toCompanyBlackReasonList(company, BlackReasonType.BLACK, reason, dbReasons,
|
||||
reasonList, context.getObjectMapper());
|
||||
}
|
||||
}
|
||||
if (data.has("greyReason")) {
|
||||
for (JsonNode reason : data.get("greyReason")) {
|
||||
toCompanyBlackReasonList(company, BlackReasonType.GRAY, reason, dbReasons,
|
||||
reasonList, context.getObjectMapper());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.error("{} {},json = {}", company.getName(), ex.getMessage(), json, ex);
|
||||
throw new RuntimeException(json.toString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存JSON数据到公司目录
|
||||
String companyPath = company.getPath();
|
||||
if (StringUtils.hasText(companyPath)) {
|
||||
File dir = new File(companyPath);
|
||||
if (dir.exists()) {
|
||||
File file = new File(dir, FileUtils.FILE_BLACK_LIST_JSON);
|
||||
try {
|
||||
objectMapper.writeValue(file, json);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Unable Save BlackList to {}, company:{}", file, company.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, context.getObjectMapper(), context.getSocksProxy());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
if (!reasonList.isEmpty()) {
|
||||
companyBlackReasonRepository.saveAll(reasonList);
|
||||
}
|
||||
cloudRk.setCloudBlackListUpdated(LocalDateTime.now());
|
||||
}
|
||||
|
||||
private void toCompanyBlackReasonList(
|
||||
Company company, BlackReasonType type,
|
||||
JsonNode reason, List<CompanyBlackReason> dbReasons,
|
||||
@@ -381,15 +304,19 @@ public class CloudRkService implements IEntityService<CloudRk>, QueryService<Clo
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 这个可以无法更新缓存
|
||||
@Caching(evict = {
|
||||
@CacheEvict(key = "#p0.id"),
|
||||
@CacheEvict(key = "#p1.id"),
|
||||
})
|
||||
public void resetTo(Company from, Company to) {
|
||||
public void resetTo(Company from, Company to, MessageHolder holder) {
|
||||
List<CloudRk> list = cloudRKRepository.findAllByCompanyId(from.getId());
|
||||
if (list.isEmpty()) {
|
||||
holder.debug("No records to reset");
|
||||
return;
|
||||
}
|
||||
for (CloudRk item : list) {
|
||||
item.setCompany(to);
|
||||
holder.info("Reset #" + item.getId());
|
||||
}
|
||||
cloudRKRepository.saveAll(list);
|
||||
}
|
||||
|
||||
@@ -14,10 +14,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
@@ -73,7 +70,15 @@ public class CloudRkCtx extends AbstractCtx implements CloudRkContext {
|
||||
}
|
||||
|
||||
public void post(String url, Consumer<Map<String, Object>> data, Consumer<JsonNode> consumer) throws IOException {
|
||||
HttpJsonUtils.post(url, data, consumer, getObjectMapper(), getSocksProxy());
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("token", "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXB0X2NvZGUiOiJDNEU0M0lQVCIsImx0cGFfdG9rZW4iOm51bGwsImV4cGlyZV");
|
||||
HttpJsonUtils.post(url, headers, data, consumer, getObjectMapper(), getSocksProxy());
|
||||
}
|
||||
|
||||
public void get(String url, Consumer<JsonNode> consumer) throws IOException {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("token", "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXB0X2NvZGUiOiJDNEU0M0lQVCIsImx0cGFfdG9rZW4iOm51bGwsImV4cGlyZV");
|
||||
HttpJsonUtils.get(url, headers, consumer, getObjectMapper(), getSocksProxy());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,10 +167,10 @@ public class CloudRkCtx extends AbstractCtx implements CloudRkContext {
|
||||
for (String name : companyNames) {
|
||||
String url = api + URLEncoder.encode(name, StandardCharsets.UTF_8);
|
||||
try {
|
||||
HttpJsonUtils.get(url, json -> {
|
||||
get(url, json -> {
|
||||
applyBlackReason(json, company, cloudRk, reasonList, dbReasons, holder);
|
||||
saveJsonToFile(company, json, "black-" + name + ".json", holder);
|
||||
}, getObjectMapper(), getSocksProxy());
|
||||
});
|
||||
} catch (IOException e) {
|
||||
catchException(e, holder);
|
||||
}
|
||||
@@ -466,16 +471,15 @@ public class CloudRkCtx extends AbstractCtx implements CloudRkContext {
|
||||
Company company, CloudRk cloudRk, MessageHolder holder) throws IOException {
|
||||
String url = getConfService().getString(CloudRkService.KEY_ENT_FUZZY_URL);
|
||||
List<CloudRkService.EntInfo> results = new ArrayList<>();
|
||||
ObjectMapper objectMapper = getObjectMapper();
|
||||
try {
|
||||
holder.debug("POST " + url);
|
||||
HttpJsonUtils.post(url, data -> {
|
||||
post(url, data -> {
|
||||
data.put("theKey", company.getName());
|
||||
data.put("get", true);
|
||||
}, json -> {
|
||||
applyEnterpriseQuery(json, company, cloudRk, results, holder);
|
||||
saveJsonToFile(company, json, "fuzzy.json", holder);
|
||||
}, objectMapper, getSocksProxy());
|
||||
});
|
||||
} catch (IOException ex) {
|
||||
catchException(ex, holder);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.ecep.contract.QueryService;
|
||||
import com.ecep.contract.ds.other.model.CloudRk;
|
||||
import com.ecep.contract.util.SpecificationUtils;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.slf4j.Logger;
|
||||
@@ -146,10 +145,15 @@ public class CloudTycService implements IEntityService<CloudTyc>, QueryService<C
|
||||
}
|
||||
}
|
||||
|
||||
public void resetTo(Company from, Company to) {
|
||||
public void resetTo(Company from, Company to, MessageHolder holder) {
|
||||
List<CloudTyc> list = cloudTycRepository.findAllByCompanyId(from.getId());
|
||||
if (list.isEmpty()) {
|
||||
holder.debug("No records to reset");
|
||||
return;
|
||||
}
|
||||
for (CloudTyc item : list) {
|
||||
item.setCompany(to);
|
||||
holder.info("Reset #" + item.getId());
|
||||
}
|
||||
cloudTycRepository.saveAll(list);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.ecep.contract.vo.ContractGroupVo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -13,28 +12,53 @@ import org.springframework.beans.BeansException;
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.contract.service.ContractGroupService;
|
||||
import com.ecep.contract.model.ContractGroup;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步合同分组
|
||||
* 合同分组同步任务
|
||||
* <p>
|
||||
* 该类实现了从U8系统同步合同分组到本地系统的功能
|
||||
* <p>
|
||||
* <b>实现特点:</b>
|
||||
* 1. 继承Tasker基类获取通信框架和消息处理功能
|
||||
* 2. 实现WebSocketServerTasker接口以支持WebSocket通信
|
||||
* 3. 使用ContractGroupService处理具体的分组数据同步逻辑
|
||||
* 4. 提供进度反馈和状态更新
|
||||
* <p>
|
||||
* <b>工作流程:</b>
|
||||
* 1. init方法初始化任务标题
|
||||
* 2. execute方法读取U8系统中的所有合同分组
|
||||
* 3. 遍历并同步每个分组数据到本地
|
||||
* 4. 提供实时进度更新
|
||||
* <p>
|
||||
* <b>注意事项:</b>
|
||||
* 1. 不重复实现Tasker基类已提供的handler设置方法
|
||||
* 2. 使用MessageHolder进行消息反馈
|
||||
* 3. 在执行过程中检查cancelled状态以支持任务取消
|
||||
* <p>
|
||||
* <b>使用示例:</b>
|
||||
* 该任务通常由WebSocketServerTaskManager自动实例化和执行,通过WebSocket与客户端通信
|
||||
*/
|
||||
public class ContractGroupSyncTask extends Tasker<Object> {
|
||||
public class ContractGroupSyncTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractGroupSyncTask.class);
|
||||
@Setter
|
||||
private ContractGroupService contractGroupService;
|
||||
|
||||
public ContractGroupSyncTask() {
|
||||
updateTitle("用友U8系统-同步合同分组信息");
|
||||
// 初始化逻辑已移至init方法
|
||||
}
|
||||
|
||||
ContractGroupService getContractGroupService() {
|
||||
if (contractGroupService == null) {
|
||||
contractGroupService = SpringApp.getBean(ContractGroupService.class);
|
||||
}
|
||||
return contractGroupService;
|
||||
public ContractGroupService getContractGroupService() {
|
||||
return getCachedBean(ContractGroupService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
updateTitle("用友U8系统-同步合同分组信息");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,7 +68,7 @@ public class ContractGroupSyncTask extends Tasker<Object> {
|
||||
service = SpringApp.getBean(YongYouU8Service.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Service", e);
|
||||
holder.error("can't get bean of YongYouU8Service");
|
||||
holder.info("can't get bean of YongYouU8Service");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -53,7 +77,6 @@ public class ContractGroupSyncTask extends Tasker<Object> {
|
||||
List<Map<String, Object>> list = service.queryAllContractGroup();
|
||||
int size = list.size();
|
||||
holder.debug("总共读取 CM_Group 数据 " + size + " 条");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
holder.info("Cancelled");
|
||||
@@ -64,7 +87,6 @@ public class ContractGroupSyncTask extends Tasker<Object> {
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,22 +13,20 @@ import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.contract.service.ContractKindService;
|
||||
import com.ecep.contract.model.ContractKind;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步合同分类
|
||||
*/
|
||||
public class ContractKindSyncTask extends Tasker<Object> {
|
||||
public class ContractKindSyncTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractKindSyncTask.class);
|
||||
@Setter
|
||||
private ContractKindService contractKindService;
|
||||
|
||||
public ContractKindSyncTask() {
|
||||
updateTitle("用友U8系统-同步合同分类信息");
|
||||
}
|
||||
|
||||
ContractKindService getContractKindService() {
|
||||
if (contractKindService == null) {
|
||||
contractKindService = SpringApp.getBean(ContractKindService.class);
|
||||
@@ -36,35 +34,54 @@ public class ContractKindSyncTask extends Tasker<Object> {
|
||||
return contractKindService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化任务标题
|
||||
updateTitle("用友U8系统-同步合同分类信息");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
holder.info("开始执行合同类型同步任务...");
|
||||
updateProgress(0, 100);
|
||||
|
||||
YongYouU8Repository repository = null;
|
||||
try {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Repository", e);
|
||||
holder.error("can't get bean of YongYouU8Repository");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
logger.info("读取 U8 系统 CM_Kind 数据表...");
|
||||
List<Map<String, Object>> list = repository.queryAllContractKind();
|
||||
int size = list.size();
|
||||
holder.debug("总共读取 CM_Kind 数据 " + size + " 条");
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
logger.info("正在读取U8系统中的合同分类数据...");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
holder.info("Cancelled");
|
||||
return null;
|
||||
List<Map<String, Object>> list = repository.queryAllContractKind();
|
||||
int size = list.size();
|
||||
holder.debug("共读取到" + size + "条合同分类数据,开始同步...");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
holder.info("任务已取消");
|
||||
return null;
|
||||
}
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">");
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
int progress = (int) ((counter.incrementAndGet() * 100.0) / size);
|
||||
updateProgress(counter.get(), size);
|
||||
holder.info("同步进度: " + progress + "%");
|
||||
}
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">");
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
|
||||
return null;
|
||||
holder.info("合同类型同步任务执行完成");
|
||||
updateProgress(100, 100);
|
||||
|
||||
return null;
|
||||
} catch (BeansException e) {
|
||||
logger.error("无法获取YongYouU8Repository实例", e);
|
||||
holder.error("无法获取YongYouU8Repository实例");
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
logger.error("合同类型同步任务执行失败", e);
|
||||
holder.error("合同类型同步任务执行失败: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void sync(Map<String, Object> map, MessageHolder holder) {
|
||||
|
||||
@@ -13,58 +13,75 @@ import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.contract.service.ContractTypeService;
|
||||
import com.ecep.contract.model.ContractType;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步合同类型
|
||||
*/
|
||||
public class ContractTypeSyncTask extends Tasker<Object> {
|
||||
public class ContractTypeSyncTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractTypeSyncTask.class);
|
||||
@Setter
|
||||
private ContractTypeService contractTypeService;
|
||||
|
||||
public ContractTypeSyncTask() {
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化任务标题
|
||||
updateTitle("用友U8系统-同步合同类型信息");
|
||||
}
|
||||
|
||||
ContractTypeService getContractTypeService() {
|
||||
if (contractTypeService == null) {
|
||||
contractTypeService = SpringApp.getBean(ContractTypeService.class);
|
||||
}
|
||||
return contractTypeService;
|
||||
return getCachedBean(ContractTypeService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
// 初始化消息
|
||||
holder.info("开始执行合同类型同步任务...");
|
||||
updateProgress(0, 100);
|
||||
|
||||
YongYouU8Repository repository = null;
|
||||
try {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Service", e);
|
||||
holder.error("can't get bean of YongYouU8Service");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
logger.info("读取 U8 系统 CM_Type,CM_TypeClass 数据表...");
|
||||
List<Map<String, Object>> list = repository.queryAllContractType();
|
||||
int size = list.size();
|
||||
holder.debug("总共读取 CM_Type,CM_TypeClass 数据 " + size + " 条");
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
logger.info("正在读取U8系统中的合同类型数据...");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
holder.info("Cancelled");
|
||||
return null;
|
||||
List<Map<String, Object>> list = repository.queryAllContractType();
|
||||
int size = list.size();
|
||||
holder.debug("共读取到" + size + "条合同类型数据,开始同步...");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
holder.info("任务已取消");
|
||||
return null;
|
||||
}
|
||||
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + "> ");
|
||||
sync(map, sub);
|
||||
|
||||
// 更新进度
|
||||
int progress = (int) ((counter.incrementAndGet() * 100.0) / size);
|
||||
updateProgress(counter.get(), size);
|
||||
sub.info("同步进度: " + progress + "%");
|
||||
}
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">");
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
|
||||
return null;
|
||||
holder.info("合同类型同步任务执行完成");
|
||||
updateProgress(100, 100);
|
||||
|
||||
return null;
|
||||
} catch (BeansException e) {
|
||||
logger.error("无法获取YongYouU8Repository实例", e);
|
||||
holder.error("无法获取YongYouU8Repository实例");
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
logger.error("合同类型同步任务执行失败", e);
|
||||
holder.error("合同类型同步任务执行失败: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void sync(Map<String, Object> map, MessageHolder holder) {
|
||||
|
||||
@@ -5,37 +5,38 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.ecep.contract.ds.customer.service.CustomerCatalogService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.customer.service.CustomerCatalogService;
|
||||
import com.ecep.contract.ds.customer.service.CustomerService;
|
||||
import com.ecep.contract.model.CustomerCatalog;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
import com.ecep.contract.vo.CustomerCatalogVo;
|
||||
|
||||
import lombok.Setter;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
/**
|
||||
* 同步客户分类
|
||||
*/
|
||||
public class CustomerClassSyncTask extends Tasker<Object> {
|
||||
public class CustomerClassSyncTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CustomerClassSyncTask.class);
|
||||
@Setter
|
||||
private CustomerService companyCustomerService;
|
||||
|
||||
public CustomerClassSyncTask() {
|
||||
updateTitle("用友U8系统-同步客户分类信息");
|
||||
|
||||
}
|
||||
|
||||
CustomerService getCompanyCustomerService() {
|
||||
if (companyCustomerService == null) {
|
||||
companyCustomerService = SpringApp.getBean(CustomerService.class);
|
||||
}
|
||||
return companyCustomerService;
|
||||
return getCachedBean(CustomerService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化参数,当前任务不需要特殊参数
|
||||
updateTitle("用友U8系统-同步客户分类信息");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,27 +46,29 @@ public class CustomerClassSyncTask extends Tasker<Object> {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Repository", e);
|
||||
holder.error("can't get bean of YongYouU8Repository");
|
||||
holder.error("获取YongYouU8Repository失败: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
logger.info("读取 U8 系统 CustomerClass 数据表...");
|
||||
logger.info("开始读取U8系统客户分类数据...");
|
||||
List<Map<String, Object>> list = repository.queryAllCustomerClass();
|
||||
int size = list.size();
|
||||
holder.debug("总共读取 CustomerClass 数据 " + size + " 条");
|
||||
holder.debug("总共读取到" + size + "条客户分类数据");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
holder.info("Cancelled");
|
||||
holder.info("任务已取消");
|
||||
return null;
|
||||
}
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">");
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
int current = counter.incrementAndGet();
|
||||
updateProgress(current, size);
|
||||
}
|
||||
|
||||
holder.info("客户分类数据同步完成");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -74,33 +77,40 @@ public class CustomerClassSyncTask extends Tasker<Object> {
|
||||
|
||||
String code = (String) map.get("cCCCode");
|
||||
String name = (String) map.get("cCCName");
|
||||
|
||||
holder.debug("处理客户分类:" + code + " - " + name);
|
||||
var catalogService = getCachedBean(CustomerCatalogService.class);
|
||||
|
||||
CustomerCatalogVo customerCatalog = catalogService.findByCode(code);
|
||||
if (customerCatalog == null) {
|
||||
CustomerCatalog v1 = new CustomerCatalog();
|
||||
v1.setCode(code);
|
||||
v1.setName(name);
|
||||
v1 = catalogService.save(v1);
|
||||
holder.info("新建客户分类:" + code);
|
||||
customerCatalog = v1.toVo();
|
||||
}
|
||||
try {
|
||||
CustomerCatalogVo customerCatalog = catalogService.findByCode(code);
|
||||
if (customerCatalog == null) {
|
||||
CustomerCatalog v1 = new CustomerCatalog();
|
||||
v1.setCode(code);
|
||||
v1.setName(name);
|
||||
v1 = catalogService.save(v1);
|
||||
holder.info("新建客户分类:" + code);
|
||||
customerCatalog = v1.toVo();
|
||||
}
|
||||
|
||||
if (!Objects.equals(customerCatalog.getCode(), code)) {
|
||||
customerCatalog.setCode(code);
|
||||
holder.info("客户分类代码:" + customerCatalog.getCode() + " -> " + code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(customerCatalog.getName(), name)) {
|
||||
customerCatalog.setName(name);
|
||||
holder.info("客户分类名称:" + customerCatalog.getName() + " -> " + name);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(customerCatalog.getCode(), code)) {
|
||||
customerCatalog.setCode(code);
|
||||
holder.info("客户分类代码:" + customerCatalog.getCode() + " -> " + code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(customerCatalog.getName(), name)) {
|
||||
customerCatalog.setName(name);
|
||||
holder.info("客户分类名称:" + customerCatalog.getName() + " -> " + name);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
var v1 = catalogService.getById(customerCatalog.getId());
|
||||
catalogService.updateByVo(v1, customerCatalog);
|
||||
catalogService.save(v1);
|
||||
if (modified) {
|
||||
var v1 = catalogService.getById(customerCatalog.getId());
|
||||
catalogService.updateByVo(v1, customerCatalog);
|
||||
catalogService.save(v1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("同步客户分类失败: " + code, e);
|
||||
holder.error("同步客户分类失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.ecep.contract.ds.customer.service.CompanyCustomerEntityService;
|
||||
import com.ecep.contract.vo.CompanyCustomerEntityVo;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -18,32 +16,44 @@ import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.cloud.u8.ctx.CompanyCtx;
|
||||
import com.ecep.contract.cloud.u8.ctx.CustomerCtx;
|
||||
import com.ecep.contract.constant.CloudServiceConstant;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.ds.contract.tasker.AbstContractRepairTasker;
|
||||
import com.ecep.contract.ds.customer.service.CustomerService;
|
||||
import com.ecep.contract.ds.other.model.CloudYu;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.ds.customer.model.CompanyCustomer;
|
||||
import com.ecep.contract.ds.customer.model.CompanyCustomerEntity;
|
||||
import com.ecep.contract.ds.customer.service.CompanyCustomerEntityService;
|
||||
import com.ecep.contract.ds.customer.service.CustomerService;
|
||||
import com.ecep.contract.ds.other.model.CloudYu;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.vo.CompanyCustomerEntityVo;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步客户任务
|
||||
*/
|
||||
public class CustomerSyncTask extends AbstContractRepairTasker {
|
||||
public class CustomerSyncTask extends AbstContractRepairTasker implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CustomerSyncTask.class);
|
||||
private YongYouU8Repository repository;
|
||||
private final CustomerCtx customerCtx = new CustomerCtx();
|
||||
@Setter
|
||||
private YongYouU8Service yongYouU8Service;
|
||||
|
||||
public CustomerSyncTask() {
|
||||
private CustomerService getCustomerService() {
|
||||
return getCachedBean(CustomerService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化参数,当前任务不需要特殊参数
|
||||
updateTitle("用友U8系统-同步客户");
|
||||
}
|
||||
|
||||
private CustomerService getCompanyCustomerService() {
|
||||
return customerCtx.getCompanyCustomerService();
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
repair(holder);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,7 +116,7 @@ public class CustomerSyncTask extends AbstContractRepairTasker {
|
||||
return;
|
||||
}
|
||||
if (!Hibernate.isInitialized(customer)) {
|
||||
customer = getCompanyCustomerService().getById(customer.getId());
|
||||
customer = getCustomerService().getById(customer.getId());
|
||||
}
|
||||
Company company = customer.getCompany();
|
||||
if (company == null) {
|
||||
@@ -130,7 +140,7 @@ public class CustomerSyncTask extends AbstContractRepairTasker {
|
||||
return;
|
||||
}
|
||||
if (!Hibernate.isInitialized(customer)) {
|
||||
customer = getCompanyCustomerService().getById(customer.getId());
|
||||
customer = getCustomerService().getById(customer.getId());
|
||||
}
|
||||
Company company = customer.getCompany();
|
||||
if (company == null) {
|
||||
|
||||
@@ -15,7 +15,6 @@ import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.other.service.DepartmentService;
|
||||
import com.ecep.contract.ds.other.service.EmployeeService;
|
||||
import com.ecep.contract.model.Department;
|
||||
import com.ecep.contract.model.Employee;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
|
||||
@@ -13,19 +13,26 @@ import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.vendor.repository.VendorClassRepository;
|
||||
import com.ecep.contract.model.VendorCatalog;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步供应商分类
|
||||
*/
|
||||
public class VendorClassSyncTask extends Tasker<Object> {
|
||||
public class VendorClassSyncTask extends Tasker<Object> implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(VendorClassSyncTask.class);
|
||||
@Setter
|
||||
private VendorClassRepository vendorClassRepository;
|
||||
|
||||
public VendorClassSyncTask() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化参数,当前任务不需要特殊参数
|
||||
updateTitle("用友U8系统-同步供应商分类信息");
|
||||
}
|
||||
|
||||
@@ -43,7 +50,7 @@ public class VendorClassSyncTask extends Tasker<Object> {
|
||||
service = SpringApp.getBean(YongYouU8Service.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Service", e);
|
||||
holder.error("can't get bean of YongYouU8Service");
|
||||
holder.error("获取YongYouU8Service失败: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -51,7 +58,7 @@ public class VendorClassSyncTask extends Tasker<Object> {
|
||||
logger.info("读取 U8 系统 VendorClass 数据表...");
|
||||
List<Map<String, Object>> list = service.queryAllVendorClass();
|
||||
int size = list.size();
|
||||
holder.debug("总共读取 VendorClass 数据 " + size + " 条");
|
||||
holder.debug("总共读取到" + size + "条供应商分类数据");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
@@ -64,6 +71,8 @@ public class VendorClassSyncTask extends Tasker<Object> {
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
|
||||
updateMessage("供应商分类数据同步完成");
|
||||
updateProperty("completed", true);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -73,27 +82,33 @@ public class VendorClassSyncTask extends Tasker<Object> {
|
||||
String code = (String) map.get("cVCCode");
|
||||
String name = (String) map.get("cVCName");
|
||||
|
||||
VendorClassRepository repository = getVendorClassRepository();
|
||||
VendorCatalog vendorCatalog = repository.findByCode(code).orElse(null);
|
||||
if (vendorCatalog == null) {
|
||||
vendorCatalog = new VendorCatalog();
|
||||
holder.info("新建供应商分类:" + code);
|
||||
modified = true;
|
||||
}
|
||||
try {
|
||||
VendorClassRepository repository = getVendorClassRepository();
|
||||
VendorCatalog vendorCatalog = repository.findByCode(code).orElse(null);
|
||||
if (vendorCatalog == null) {
|
||||
vendorCatalog = new VendorCatalog();
|
||||
holder.info("新建供应商分类:" + code);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(vendorCatalog.getCode(), code)) {
|
||||
vendorCatalog.setCode(code);
|
||||
holder.info("供应商分类代码:" + vendorCatalog.getCode() + " -> " + code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(vendorCatalog.getName(), name)) {
|
||||
vendorCatalog.setName(name);
|
||||
holder.info("供应商分类名称:" + vendorCatalog.getName() + " -> " + name);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(vendorCatalog.getCode(), code)) {
|
||||
vendorCatalog.setCode(code);
|
||||
holder.info("供应商分类代码:" + vendorCatalog.getCode() + " -> " + code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(vendorCatalog.getName(), name)) {
|
||||
vendorCatalog.setName(name);
|
||||
holder.info("供应商分类名称:" + vendorCatalog.getName() + " -> " + name);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
repository.save(vendorCatalog);
|
||||
if (modified) {
|
||||
repository.save(vendorCatalog);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("同步供应商分类失败: " + code, e);
|
||||
holder.error("同步供应商分类失败: " + e.getMessage());
|
||||
updateMessage("同步供应商分类失败: " + code + " - " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.ecep.contract.cloud.u8;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -12,6 +14,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.Message;
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.cloud.u8.ctx.CompanyCtx;
|
||||
@@ -25,17 +28,17 @@ import com.ecep.contract.ds.other.model.CloudYu;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.ds.vendor.model.Vendor;
|
||||
import com.ecep.contract.ds.vendor.model.VendorEntity;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 供应商同步任务
|
||||
*/
|
||||
public class VendorSyncTask extends AbstContractRepairTasker {
|
||||
public class VendorSyncTask extends AbstContractRepairTasker implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(VendorSyncTask.class);
|
||||
private final VendorCtx vendorCtx = new VendorCtx();
|
||||
private VendorService vendorService;
|
||||
private VendorEntityService vendorEntityService;
|
||||
private YongYouU8Repository repository;
|
||||
@Setter
|
||||
private YongYouU8Service yongYouU8Service;
|
||||
@@ -45,17 +48,22 @@ public class VendorSyncTask extends AbstContractRepairTasker {
|
||||
}
|
||||
|
||||
private VendorService getVendorService() {
|
||||
if (vendorService == null) {
|
||||
vendorService = SpringApp.getBean(VendorService.class);
|
||||
}
|
||||
return vendorService;
|
||||
return getCachedBean(VendorService.class);
|
||||
}
|
||||
|
||||
private VendorEntityService getVendorEntityService() {
|
||||
if (vendorEntityService == null) {
|
||||
vendorEntityService = SpringApp.getBean(VendorEntityService.class);
|
||||
}
|
||||
return vendorEntityService;
|
||||
return getCachedBean(VendorEntityService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
// 初始化参数,当前任务不需要特殊参数
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
repair(holder);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.util.SpecificationUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -119,13 +120,13 @@ public class YongYouU8Service
|
||||
* @param cloudYu Cloud Yu 对象
|
||||
* @return 更新的 Cloud Yu
|
||||
*/
|
||||
@Caching(evict = { @CacheEvict(key = "#cloudYu.id") })
|
||||
@Caching(evict = {@CacheEvict(key = "#cloudYu.id")})
|
||||
@Override
|
||||
public CloudYu save(CloudYu cloudYu) {
|
||||
return cloudYuRepository.save(cloudYu);
|
||||
}
|
||||
|
||||
@Caching(evict = { @CacheEvict(key = "#cloudYu.id") })
|
||||
@Caching(evict = {@CacheEvict(key = "#cloudYu.id")})
|
||||
@Override
|
||||
public void delete(CloudYu vo) {
|
||||
CloudYu entity = cloudYuRepository.findById(vo.getId()).orElse(null);
|
||||
@@ -143,10 +144,15 @@ public class YongYouU8Service
|
||||
}
|
||||
}
|
||||
|
||||
public void resetTo(Company from, Company to) {
|
||||
public void resetTo(Company from, Company to, MessageHolder holder) {
|
||||
List<CloudYu> list = cloudYuRepository.findAllByCompanyId(from.getId());
|
||||
if (list.isEmpty()) {
|
||||
holder.debug("No records to reset");
|
||||
return;
|
||||
}
|
||||
for (CloudYu item : list) {
|
||||
item.setCompany(to);
|
||||
holder.info("Reset #" + item.getId());
|
||||
}
|
||||
cloudYuRepository.saveAll(list);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ecep.contract.ds.company.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -51,15 +52,17 @@ public class CompanyContactService implements IEntityService<CompanyContact>, Qu
|
||||
return repository.save(contact);
|
||||
}
|
||||
|
||||
public void resetTo(Company from, Company to) {
|
||||
// 曾用名 关联到 updater
|
||||
public void resetTo(Company from, Company to, MessageHolder holder) {
|
||||
// 联系人 关联到 updater
|
||||
List<CompanyContact> list = repository.findAllByCompany(from);
|
||||
if (list.isEmpty()) {
|
||||
holder.info("无联系人");
|
||||
return;
|
||||
}
|
||||
for (CompanyContact oldName : list) {
|
||||
oldName.setMemo(MyStringUtils.appendIfAbsent(oldName.getMemo(), "转自 " + from.getId()));
|
||||
oldName.setCompany(to);
|
||||
for (CompanyContact contact : list) {
|
||||
contact.setMemo(MyStringUtils.appendIfAbsent(contact.getMemo(), "转自 " + from.getId()));
|
||||
contact.setCompany(to);
|
||||
holder.info("关联了 " + contact.getName() + " 至 " + to.getName());
|
||||
}
|
||||
repository.saveAll(list);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.io.File;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import com.ecep.contract.Message;
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -163,17 +165,21 @@ public class CompanyOldNameService implements IEntityService<CompanyOldName>, Qu
|
||||
* @param from from
|
||||
* @param to to
|
||||
*/
|
||||
public void resetTo(Company from, Company to) {
|
||||
public void resetTo(Company from, Company to, MessageHolder holder) {
|
||||
// 曾用名 关联到 to
|
||||
List<CompanyOldName> list = companyOldNameRepository.findAllByCompanyId(from.getId());
|
||||
if (list.isEmpty()) {
|
||||
holder.info("无曾用名");
|
||||
return;
|
||||
}
|
||||
for (CompanyOldName oldName : list) {
|
||||
oldName.setMemo(MyStringUtils.appendIfAbsent(oldName.getMemo(), "转自 " + from.getId()));
|
||||
oldName.setCompanyId(to.getId());
|
||||
holder.info("关联了 " + oldName.getName() + " 至 " + to.getName());
|
||||
}
|
||||
companyOldNameRepository.saveAll(list);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void deleteByCompany(Company company) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.ecep.contract.ds.project.service.ProjectService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -92,6 +93,8 @@ public class CompanyService extends EntityService<Company, CompanyVo, Integer>
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
private YongYouU8Service yongYouU8Service;
|
||||
@Autowired
|
||||
private ProjectService projectService;
|
||||
|
||||
@Override
|
||||
protected CompanyRepository getRepository() {
|
||||
@@ -130,7 +133,7 @@ public class CompanyService extends EntityService<Company, CompanyVo, Integer>
|
||||
protected Specification<Company> buildParameterSpecification(JsonNode paramsNode) {
|
||||
Specification<Company> spec = null;
|
||||
// field
|
||||
spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "name","uniscid", "abbName");
|
||||
spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "name", "uniscid", "abbName");
|
||||
return spec;
|
||||
}
|
||||
|
||||
@@ -251,7 +254,7 @@ public class CompanyService extends EntityService<Company, CompanyVo, Integer>
|
||||
// 合并重复的
|
||||
for (Company company : removes) {
|
||||
try {
|
||||
merge(company, updater);
|
||||
merge(company, updater, null);
|
||||
} catch (Exception e) {
|
||||
logger.error("合并 {} -> {} 时发生错误:{}", company.toPrettyString(), updater.toPrettyString(), e.getMessage(),
|
||||
e);
|
||||
@@ -275,11 +278,11 @@ public class CompanyService extends EntityService<Company, CompanyVo, Integer>
|
||||
* </ul>
|
||||
* 或者 把关联数据转移到其他公司
|
||||
* <ul>
|
||||
* <li>{@link VendorService#resetTo(Company, Company)}</li>
|
||||
* <li>{@link CustomerService#resetTo(Company, Company)}</li>
|
||||
* <li>{@link VendorService#resetTo(Company, Company, MessageHolder)}</li>
|
||||
* <li>{@link CustomerService#mergeTo(Company, Company)}</li>
|
||||
* <li>{@link CompanyOldNameService#resetTo(Company, Company)}</li>
|
||||
* <li>{@link CompanyContactService#resetTo(Company, Company)}</li>
|
||||
* <li>{@link ContractService#resetTo(Company, Company)}</li>
|
||||
* <li>{@link ContractService#mergeTo(Company, Company, MessageHolder)}</li>
|
||||
* <li>{@link CompanyContactService#resetTo(Company, Company)}</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
@@ -323,20 +326,20 @@ public class CompanyService extends EntityService<Company, CompanyVo, Integer>
|
||||
* </ol>
|
||||
* </p>
|
||||
*/
|
||||
public void merge(Company from, Company to) {
|
||||
// cloudRkService.findById(from.getId());
|
||||
cloudRkService.resetTo(from, to);
|
||||
cloudTycService.resetTo(from, to);
|
||||
yongYouU8Service.resetTo(from, to);
|
||||
public void merge(Company from, Company to, MessageHolder holder) {
|
||||
cloudRkService.resetTo(from, to, holder);
|
||||
cloudTycService.resetTo(from, to, holder);
|
||||
yongYouU8Service.resetTo(from, to, holder);
|
||||
|
||||
companyOldNameService.resetTo(from, to);
|
||||
companyContactService.resetTo(from, to);
|
||||
companyOldNameService.resetTo(from, to, holder);
|
||||
companyContactService.resetTo(from, to, holder);
|
||||
// 供应商和客户
|
||||
vendorService.resetTo(from, to);
|
||||
companyCustomerService.resetTo(from, to);
|
||||
vendorService.resetTo(from, to, holder);
|
||||
companyCustomerService.mergeTo(from, to, holder);
|
||||
|
||||
contractService.resetTo(from, to);
|
||||
companyContactService.resetTo(from, to);
|
||||
contractService.mergeTo(from, to, holder);
|
||||
|
||||
projectService.mergeTo(from, to, holder);
|
||||
repository.delete(from);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Merge {} to {}", from, to);
|
||||
@@ -428,7 +431,6 @@ public class CompanyService extends EntityService<Company, CompanyVo, Integer>
|
||||
*
|
||||
* @param company 要验证的公司
|
||||
* @param verifyDate 验证日期
|
||||
* @param status 状态输出
|
||||
*/
|
||||
public boolean verifyEnterpriseStatus(Company company, LocalDate verifyDate, MessageHolder holder) {
|
||||
// 检查营业状态
|
||||
@@ -506,7 +508,7 @@ public class CompanyService extends EntityService<Company, CompanyVo, Integer>
|
||||
}
|
||||
|
||||
public Predicate buildSearchPredicate(String searchText, Path<Company> root, CriteriaQuery<?> query,
|
||||
CriteriaBuilder builder) {
|
||||
CriteriaBuilder builder) {
|
||||
return builder.or(
|
||||
builder.like(root.get("name"), "%" + searchText + "%"),
|
||||
builder.like(root.get("shortName"), "%" + searchText + "%"),
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.ecep.contract.ds.company.tasker;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.service.tasker.WebSocketServerTasker;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
import com.ecep.contract.vo.CompanyVo;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 公司合并任务
|
||||
* 用于通过WebSocket执行公司合并操作
|
||||
*/
|
||||
|
||||
public class CompanyMergeServerTasker extends Tasker<Object> implements WebSocketServerTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CompanyMergeServerTasker.class);
|
||||
private CompanyVo company;
|
||||
private List<String> nameList;
|
||||
|
||||
private CompanyService companyService;
|
||||
|
||||
@Override
|
||||
public void init(JsonNode argsNode) {
|
||||
companyService = getBean(CompanyService.class);
|
||||
// 从第一个参数获取公司ID并查找公司
|
||||
company = companyService.findById(argsNode.get(0).asInt());
|
||||
|
||||
// 从第二个参数获取名称列表
|
||||
JsonNode nameListNode = argsNode.get(1);
|
||||
nameList = new ArrayList<>();
|
||||
|
||||
// 遍历JSON数组,将每个元素添加到nameList中
|
||||
if (nameListNode != null && nameListNode.isArray()) {
|
||||
for (JsonNode nameNode : nameListNode) {
|
||||
nameList.add(nameNode.asText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
HashSet<String> nameSet = new HashSet<>(nameList);
|
||||
nameSet.add(company.getName());
|
||||
|
||||
int size = nameSet.size();
|
||||
int count = 1;
|
||||
int merge = 0;
|
||||
|
||||
|
||||
HashMap<Integer, Company> targetCompanyMap = new HashMap<>();
|
||||
for (String name : nameSet) {
|
||||
MessageHolder sub = holder.sub(count + "/" + size + ":" + name + ">");
|
||||
if (name == null || name.isEmpty()) {
|
||||
sub.warn("名称为空");
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Company> list = companyService.findAllByName(name);
|
||||
for (Company company : list) {
|
||||
sub.debug("找到 " + company.getName());
|
||||
targetCompanyMap.put(company.getId(), company);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
targetCompanyMap.remove(this.company.getId());
|
||||
|
||||
if (targetCompanyMap.isEmpty()) {
|
||||
holder.warn("没有需要并户的公司");
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
Company targetCompany = companyService.getById(this.company.getId());
|
||||
for (Company company : targetCompanyMap.values()) {
|
||||
try {
|
||||
companyService.merge(company, targetCompany, holder);
|
||||
holder.info("并户 " + company.getName() + "[" + company.getId() + "] 到当前公司");
|
||||
merge++;
|
||||
} catch (Exception e) {
|
||||
holder.warn("合并 " + company.getName() + " -> " + targetCompany.getName() + " 失败: " + e.getMessage());
|
||||
logger.warn("合并 {} -> {} 失败: {}", company.getName(), targetCompany.getName(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (merge == 0) {
|
||||
holder.info("没有需要并户的公司");
|
||||
} else {
|
||||
holder.info("完成合并操作,共合并 " + merge + " 个公司");
|
||||
}
|
||||
|
||||
updateTitle("公司合并任务完成");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.ecep.contract.*;
|
||||
import com.ecep.contract.ds.contract.model.ContractItem;
|
||||
import com.ecep.contract.vo.ContractCatalogVo;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
@@ -25,11 +26,6 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.ContractPayWay;
|
||||
import com.ecep.contract.EntityService;
|
||||
import com.ecep.contract.IEntityService;
|
||||
import com.ecep.contract.QueryService;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.constant.ContractConstant;
|
||||
import com.ecep.contract.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.ds.contract.repository.ContractRepository;
|
||||
@@ -420,14 +416,16 @@ public class ContractService extends EntityService<Contract, ContractVo, Integer
|
||||
/**
|
||||
* 重置合同关联企业
|
||||
*/
|
||||
public void resetTo(Company from, Company to) {
|
||||
public void mergeTo(Company from, Company to, MessageHolder holder) {
|
||||
List<Contract> list = contractRepository.findAllByCompanyId(from.getId());
|
||||
if (list.isEmpty()) {
|
||||
holder.info("没有合同需要处理");
|
||||
return;
|
||||
}
|
||||
for (Contract contract : list) {
|
||||
contract.setDescription(MyStringUtils.appendIfAbsent(contract.getDescription(), "转自 " + from.getId()));
|
||||
contract.setCompany(to);
|
||||
holder.info("Reset #" + contract.getId());
|
||||
}
|
||||
contractRepository.saveAll(list);
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ public class CustomerService extends CompanyBasicService
|
||||
* @param from 要转移的客户信息所属的公司
|
||||
* @param to 要转移到的公司
|
||||
*/
|
||||
public void resetTo(Company from, Company to) {
|
||||
public void mergeTo(Company from, Company to, MessageHolder holder) {
|
||||
// 这里使用Optional对象来处理可能为空的情况
|
||||
Optional<CompanyCustomer> fromCustomer = repository.findByCompany(from);
|
||||
if (fromCustomer.isEmpty()) {
|
||||
@@ -373,7 +373,7 @@ public class CustomerService extends CompanyBasicService
|
||||
}
|
||||
|
||||
// 把 fromCustomer 信息合并到 toCustomer
|
||||
resetTo(fromCustomer.get(), toCustomer.get());
|
||||
mergeTo(fromCustomer.get(), toCustomer.get(), holder);
|
||||
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ public class CustomerService extends CompanyBasicService
|
||||
* @param from 源客户对象
|
||||
* @param to 目标客户对象
|
||||
*/
|
||||
public void resetTo(CompanyCustomer from, CompanyCustomer to) {
|
||||
public void mergeTo(CompanyCustomer from, CompanyCustomer to, MessageHolder holder) {
|
||||
// file
|
||||
companyCustomerFileService.resetTo(from, to);
|
||||
// entity
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ecep.contract.ds.other.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.ecep.contract.vo.FunctionVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -73,7 +74,7 @@ public class EmployeeRoleController {
|
||||
}
|
||||
|
||||
@RequestMapping("/getFunctionsByRoleId")
|
||||
public java.util.List<com.ecep.contract.model.Function> getFunctionsByRoleId(Integer roleId) {
|
||||
public java.util.List<FunctionVo> getFunctionsByRoleId(Integer roleId) {
|
||||
return employeeRoleService.getFunctionsByRoleId(roleId);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.ecep.contract.ds.other.service;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.ecep.contract.vo.FunctionVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
@@ -36,6 +37,9 @@ public class EmployeeRoleService implements IEntityService<EmployeeRole>, QueryS
|
||||
@Lazy
|
||||
@Autowired
|
||||
private EmployeeRoleRepository roleRepository;
|
||||
@Lazy
|
||||
@Autowired
|
||||
private FunctionService functionService;
|
||||
|
||||
@Cacheable(key = "#p0")
|
||||
public EmployeeRoleVo findById(Integer id) {
|
||||
@@ -95,15 +99,31 @@ public class EmployeeRoleService implements IEntityService<EmployeeRole>, QueryS
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<Function> getFunctionsByRoleId(int roleId) {
|
||||
public List<FunctionVo> getFunctionsByRoleId(Integer roleId) {
|
||||
Optional<EmployeeRole> optional = roleRepository.findById(roleId);
|
||||
if (optional.isPresent()) {
|
||||
EmployeeRole role = optional.get();
|
||||
return role.getFunctions().stream().toList();
|
||||
return role.getFunctions().stream().map(Function::toVo).toList();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveRoleFunctions(Integer roleId, FunctionVo[] functions) {
|
||||
Optional<EmployeeRole> optional = roleRepository.findById(roleId);
|
||||
if (optional.isEmpty()) {
|
||||
throw new RuntimeException("角色不存在");
|
||||
}
|
||||
EmployeeRole role = optional.get();
|
||||
java.util.List<Function> list = new java.util.ArrayList<>();
|
||||
for (FunctionVo functionVo : functions) {
|
||||
Function func = functionService.getById(functionVo.getId());
|
||||
list.add(func);
|
||||
}
|
||||
role.setFunctions(list);
|
||||
save(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateByVo(EmployeeRole role, EmployeeRoleVo vo) {
|
||||
role.setCode(vo.getCode());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ecep.contract.ds.project.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -30,4 +31,6 @@ public interface ProjectRepository extends
|
||||
Optional<Project> findByName(String name);
|
||||
|
||||
Optional<Project> findByCode(String code);
|
||||
|
||||
List<Project> findAllByCustomerId(Integer id);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.vo.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -415,4 +417,16 @@ public class ProjectService
|
||||
|
||||
}
|
||||
|
||||
public void mergeTo(Company from, Company to, MessageHolder holder) {
|
||||
List<Project> list = projectRepository.findAllByCustomerId(from.getId());
|
||||
if (list.isEmpty()) {
|
||||
holder.info("没有项目需要处理");
|
||||
return;
|
||||
}
|
||||
for (Project project : list) {
|
||||
project.setCustomer(to);
|
||||
holder.info("Reset #" + project.getId());
|
||||
}
|
||||
projectRepository.saveAll(list);
|
||||
}
|
||||
}
|
||||
|
||||
24
server/src/main/java/com/ecep/contract/ds/vendor/converter/StringToVendorConverter.java
vendored
Normal file
24
server/src/main/java/com/ecep/contract/ds/vendor/converter/StringToVendorConverter.java
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.ecep.contract.ds.vendor.converter;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.ecep.contract.ds.vendor.service.VendorService;
|
||||
import com.ecep.contract.vo.VendorVo;
|
||||
|
||||
public class StringToVendorConverter implements org.springframework.core.convert.converter.Converter<String, VendorVo> {
|
||||
|
||||
private VendorService service;
|
||||
|
||||
public StringToVendorConverter(VendorService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public VendorVo convert(String string) {
|
||||
if (string == null || string.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return service.findById(Integer.parseInt(string));
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import org.springframework.util.StringUtils;
|
||||
import com.ecep.contract.IEntityService;
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.QueryService;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.VendorFileType;
|
||||
import com.ecep.contract.VendorType;
|
||||
import com.ecep.contract.constant.CompanyVendorConstant;
|
||||
@@ -44,6 +45,7 @@ import com.ecep.contract.ds.vendor.repository.VendorTypeLocalRepository;
|
||||
import com.ecep.contract.ds.company.model.Company;
|
||||
import com.ecep.contract.model.CompanyBasicFile;
|
||||
import com.ecep.contract.ds.contract.model.Contract;
|
||||
import com.ecep.contract.ds.vendor.converter.StringToVendorConverter;
|
||||
import com.ecep.contract.ds.vendor.model.Vendor;
|
||||
import com.ecep.contract.model.VendorCatalog;
|
||||
import com.ecep.contract.ds.vendor.model.VendorEntity;
|
||||
@@ -57,6 +59,7 @@ import com.ecep.contract.util.SpecificationUtils;
|
||||
import com.ecep.contract.vo.VendorVo;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.persistence.criteria.Path;
|
||||
|
||||
@Lazy
|
||||
@@ -89,6 +92,12 @@ public class VendorService extends CompanyBasicService
|
||||
@Autowired
|
||||
private VendorClassRepository vendorClassRepository;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
SpringApp.getBean(org.springframework.core.convert.converter.ConverterRegistry.class)
|
||||
.addConverter(new StringToVendorConverter(this));
|
||||
}
|
||||
|
||||
@Cacheable(key = "#p0")
|
||||
public VendorVo findById(Integer id) {
|
||||
return repository.findById(id).map(Vendor::toVo).orElse(null);
|
||||
@@ -226,7 +235,7 @@ public class VendorService extends CompanyBasicService
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file,
|
||||
Consumer<String> status) {
|
||||
Consumer<String> status) {
|
||||
dbFile.setType((T) VendorFileType.General);
|
||||
fillFile(dbFile, file, null, status);
|
||||
vendorFileService.save((VendorFile) dbFile);
|
||||
@@ -236,7 +245,7 @@ public class VendorService extends CompanyBasicService
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList,
|
||||
Consumer<String> status) {
|
||||
Consumer<String> status) {
|
||||
VendorFile vendorFile = new VendorFile();
|
||||
vendorFile.setType(VendorFileType.General);
|
||||
vendorFile.setFilePath(file.getAbsolutePath());
|
||||
@@ -257,7 +266,7 @@ public class VendorService extends CompanyBasicService
|
||||
|
||||
@Override
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsEvaluationFile(F customerFile, File file,
|
||||
List<File> fileList, Consumer<String> status) {
|
||||
List<File> fileList, Consumer<String> status) {
|
||||
boolean modified = super.fillFileAsEvaluationFile(customerFile, file, fileList, status);
|
||||
// 当评价表有日期,并且未设审核时
|
||||
boolean valid = FileUtils.isArchiveFile(customerFile.getFilePath()) && customerFile.getSignDate() != null;
|
||||
@@ -428,7 +437,7 @@ public class VendorService extends CompanyBasicService
|
||||
return dir;
|
||||
}
|
||||
|
||||
public void resetTo(Company from, Company to) {
|
||||
public void resetTo(Company from, Company to, MessageHolder holder) {
|
||||
Optional<Vendor> optional = repository.findByCompany(from);
|
||||
optional.ifPresent(companyVendor -> {
|
||||
companyVendor
|
||||
|
||||
@@ -121,6 +121,7 @@ public class WebSocketServerCallbackManager {
|
||||
return method.invoke(service);
|
||||
}
|
||||
|
||||
// 第一个参数不是数组时
|
||||
if (!argumentsNode.get(0).isArray()) {
|
||||
Class<?> parameterType = Class.forName(argumentsNode.get(1).asText());
|
||||
Object arg = objectMapper.treeToValue(argumentsNode.get(0), parameterType);
|
||||
|
||||
@@ -13,12 +13,23 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||
* 定义了所有通过WebSocket与客户端通信的任务的通用方法
|
||||
* 包括任务名称、初始化参数、设置会话、更新消息、更新标题、更新进度等操作
|
||||
* <p>
|
||||
* 所有通过WebSocket与客户端通信的任务类都应实现此接口, 文档参考 .trace/rules/server_task_rules.md
|
||||
* tips:检查是否在 tasker_mapper.json 中注册
|
||||
* 所有通过WebSocket与客户端通信的任务类都应实现此接口, 通常应继承Tasker类并实现此接口
|
||||
* <p>
|
||||
* <b>实现注意事项:</b>
|
||||
* 1. 服务器端任务实现应继承Tasker基类,该基类已提供大部分通信功能的实现
|
||||
* 2. 不要在子类中重复实现setMessageHandler、setTitleHandler、setPropertyHandler和setProgressHandler方法,这些由Tasker基类提供
|
||||
* 3. 任务类应覆盖init方法以初始化参数和设置任务标题
|
||||
* 4. 任务类应覆盖execute方法实现具体业务逻辑,使用MessageHolder进行消息消息反馈
|
||||
* 5. 任务执行时使用updateProgress方法进行进度反馈
|
||||
* 6. 任务名称应与客户端对应的Tasker类名保持一致,以确保正确的通信映射
|
||||
* <p>
|
||||
* <b>注册要求:</b>
|
||||
* 任务类必须在tasker_mapper.json中注册,以确保WebSocketServerTaskManager能够正确识别和实例化
|
||||
*/
|
||||
public interface WebSocketServerTasker extends Callable<Object> {
|
||||
/**
|
||||
* 初始化任务参数
|
||||
* 任务类应在init方法中解析argsNode, 初始化任务参数
|
||||
*
|
||||
* @param argsNode 任务参数的JSON节点
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.ecep.contract.ui;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.logging.Level;
|
||||
@@ -11,7 +10,6 @@ import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.Message;
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.ds.other.service.EmployeeService;
|
||||
import com.ecep.contract.ds.other.service.SysConfService;
|
||||
@@ -22,6 +20,27 @@ import com.ecep.contract.util.DefaultBeanContext;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Tasker基类,提供任务执行和通信的核心功能
|
||||
* <p>
|
||||
* 该基类实现了任务执行框架,提供了以下核心功能:
|
||||
* 1. 任务执行环境(call方法)
|
||||
* 2. 消息处理和进度更新机制
|
||||
* 3. Spring Bean获取和缓存功能
|
||||
* 4. 当前用户和本地化支持
|
||||
* <p>
|
||||
* <b>主要组件:</b>
|
||||
* - messageHandler: 处理消息通知
|
||||
* - titleHandler: 处理标题更新
|
||||
* - progressHandler: 处理进度更新
|
||||
* - propertyHandler: 处理属性更新
|
||||
* <p>
|
||||
* <b>使用说明:</b>
|
||||
* 1. 子类应继承此类并实现execute方法,实现具体业务逻辑
|
||||
* 2. 使用updateMessage、updateProgress等方法进行状态反馈
|
||||
* 3. 对于WebSocket任务,还应实现WebSocketServerTasker接口
|
||||
* 4. 子类通常不需要覆盖setter方法,这些由框架自动设置
|
||||
*/
|
||||
public abstract class Tasker<T> implements java.util.concurrent.Callable<T>, BeanContext {
|
||||
private static final Logger logger = LoggerFactory.getLogger(Tasker.class);
|
||||
@Setter
|
||||
|
||||
@@ -20,7 +20,15 @@
|
||||
"ContractRepairAllTask": "com.ecep.contract.ds.contract.tasker.ContractRepairAllTasker",
|
||||
"ContractFilesRebuildAllTasker": "com.ecep.contract.ds.contract.tasker.ContractFilesRebuildAllTasker",
|
||||
"ContractFilesRebuildTasker": "com.ecep.contract.ds.contract.tasker.ContractFilesRebuildTasker",
|
||||
"EmployeesSyncTask": "com.ecep.contract.cloud.u8.EmployeesSyncTask"
|
||||
"EmployeesSyncTask": "com.ecep.contract.cloud.u8.EmployeesSyncTask",
|
||||
"CompanyMergeTask": "com.ecep.contract.ds.company.tasker.CompanyMergeServerTasker",
|
||||
"VendorSyncTask": "com.ecep.contract.cloud.u8.VendorSyncTask",
|
||||
"CustomerSyncTask": "com.ecep.contract.cloud.u8.CustomerSyncTask",
|
||||
"CustomerClassSyncTask": "com.ecep.contract.cloud.u8.CustomerClassSyncTask",
|
||||
"VendorClassSyncTask": "com.ecep.contract.cloud.u8.VendorClassSyncTask",
|
||||
"ContractKindSyncTask": "com.ecep.contract.cloud.u8.ContractKindSyncTask",
|
||||
"ContractTypeSyncTask": "com.ecep.contract.cloud.u8.ContractTypeSyncTask",
|
||||
"ContractGroupSyncTask": "com.ecep.contract.cloud.u8.ContractGroupSyncTask"
|
||||
},
|
||||
"descriptions": "任务注册信息, 客户端的任务可以通过 WebSocket 调用"
|
||||
}
|
||||
Reference in New Issue
Block a user