Compare commits

...

2 Commits

Author SHA1 Message Date
45f7b611c5 feat: 实现VoableService接口并重构相关服务
refactor: 优化WebSocket通信和任务处理逻辑

fix: 修复客户和供应商路径选择功能

docs: 更新任务通信规则文档

build: 更新项目版本至0.0.86-SNAPSHOT

style: 清理无用导入和日志输出

test: 添加CustomerFileMoveTasker测试类

chore: 更新tasker_mapper.json注册信息
2025-09-25 18:57:17 +08:00
bf90117116 docs: 添加客户端模块Service层规则文档
添加客户端模块Service层的架构设计、缓存管理、数据操作模式等详细规则文档,总结项目中的最佳实践和规范要求
2025-09-25 17:56:36 +08:00
62 changed files with 1639 additions and 287 deletions

View File

@@ -6,12 +6,12 @@
<parent> <parent>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>Contract-Manager</artifactId> <artifactId>Contract-Manager</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
</parent> </parent>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>client</artifactId> <artifactId>client</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
<properties> <properties>
<maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.source>${java.version}</maven.compiler.source>
@@ -22,7 +22,7 @@
<dependency> <dependency>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>common</artifactId> <artifactId>common</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@@ -96,17 +96,14 @@ public class WebSocketClientSession {
Object value = args.get(1); Object value = args.get(1);
try { try {
PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(tasker.getClass(), name); PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(tasker.getClass(), name);
System.out.println("descriptor = " + descriptor); if (descriptor == null) {
System.out.println("descriptor.getPropertyType() = " + descriptor.getPropertyType()); tasker.updateMessage(java.util.logging.Level.SEVERE, "属性 " + name + " 不存在");
return;
}
Object object = webSocketService.getObjectMapper().convertValue(value, descriptor.getPropertyType()); Object object = webSocketService.getObjectMapper().convertValue(value, descriptor.getPropertyType());
System.out.println("object = " + object);
System.out.println("descriptor.getWriteMethod() = " + descriptor.getWriteMethod());
if (descriptor.getWriteMethod() == null) { if (descriptor.getWriteMethod() == null) {
tasker.updateMessage(java.util.logging.Level.SEVERE, "属性 " + name + " 不可写"); tasker.updateMessage(java.util.logging.Level.SEVERE, "属性 " + name + " 不可写");
} else { } else {
System.out.println("descriptor.getWriteMethod().getParameterTypes() = "
+ descriptor.getWriteMethod().getParameterTypes());
descriptor.getWriteMethod().invoke(tasker, object); descriptor.getWriteMethod().invoke(tasker, object);
} }
} catch (Exception e) { } catch (Exception e) {
@@ -123,7 +120,7 @@ public class WebSocketClientSession {
private void handleAsMessage(JsonNode args) { private void handleAsMessage(JsonNode args) {
String level = args.get(0).asText(); String level = args.get(0).asText();
String message = args.get(1).asText(); String message = args.get(1).asText();
updateMessage(java.util.logging.Level.parse(level), message); updateMessage(java.util.logging.Level.parse(level), "[R] "+message);
} }
public void updateMessage(Level level, String message) { public void updateMessage(Level level, String message) {

View File

@@ -1,8 +1,6 @@
package com.ecep.contract; package com.ecep.contract;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Locale; import java.util.Locale;
import java.util.UUID; import java.util.UUID;

View File

@@ -115,6 +115,9 @@ public class ContractTabSkinExtendVendorInfo extends AbstContractBasedTabSkin {
assignedProviderField.selectedProperty().bindBidirectional(viewModel.getAssignedProvider()); assignedProviderField.selectedProperty().bindBidirectional(viewModel.getAssignedProvider());
assignedProviderField.disableProperty().bind(Bindings.createBooleanBinding(() -> { assignedProviderField.disableProperty().bind(Bindings.createBooleanBinding(() -> {
Integer groupId = viewModel.getGroup().get(); Integer groupId = viewModel.getGroup().get();
if (groupId == null) {
return false;
}
VendorGroupVo group = getVendorGroupService().findById(groupId); VendorGroupVo group = getVendorGroupService().findById(groupId);
if (group == null) { if (group == null) {
return false; return false;

View File

@@ -1,29 +1,29 @@
package com.ecep.contract.controller.customer; package com.ecep.contract.controller.customer;
import java.io.File;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import org.springframework.util.StringUtils;
import com.ecep.contract.MyDateTimeUtils; import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp;
import com.ecep.contract.controller.company.CompanyWindowController; import com.ecep.contract.controller.company.CompanyWindowController;
import com.ecep.contract.controller.tab.AbstEntityBasedTabSkin; import com.ecep.contract.controller.tab.AbstEntityBasedTabSkin;
import com.ecep.contract.controller.tab.TabSkin; import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.converter.CompanyStringConverter;
import com.ecep.contract.converter.EntityStringConverter;
import com.ecep.contract.vo.CompanyVo;
import com.ecep.contract.vo.CompanyContactVo;
import com.ecep.contract.vo.CompanyCustomerVo;
import com.ecep.contract.service.CompanyContactService; import com.ecep.contract.service.CompanyContactService;
import com.ecep.contract.service.CompanyCustomerService; import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyService; import com.ecep.contract.service.CompanyService;
import com.ecep.contract.util.UITools; import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.CompanyCustomerViewModel; import com.ecep.contract.vm.CompanyCustomerViewModel;
import com.ecep.contract.vo.CompanyCustomerVo;
import com.ecep.contract.vo.CompanyVo;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.stage.DirectoryChooser;
import javafx.util.converter.LocalDateStringConverter; import javafx.util.converter.LocalDateStringConverter;
public class CompanyCustomerTabSkinBase public class CompanyCustomerTabSkinBase
@@ -102,7 +102,33 @@ public class CompanyCustomerTabSkinBase
} }
public void onCompanyCustomerChangePathAction(ActionEvent event) { public void onCompanyCustomerChangePathAction(ActionEvent event) {
setStatus("未实现"); DirectoryChooser chooser = new DirectoryChooser();
CompanyCustomerVo entity = getEntity();
String path = entity.getPath();
File initialDirectory = null;
// 如果当前已经设置了目录并且路径有效,则设置初始目录为该目录
if (StringUtils.hasText(path)) {
File dir = new File(path);
if (dir.exists()) {
initialDirectory = dir;
}
}
// 如果没有有效的初始目录,则使用基础路径
if (initialDirectory == null) {
initialDirectory = getCompanyCustomerService().getBasePath();
}
if (initialDirectory != null) {
chooser.setInitialDirectory(initialDirectory);
}
File newDirectory = chooser.showDialog(getTab().getContent().getScene().getWindow());
if (newDirectory != null) {
entity.setPath(newDirectory.getAbsolutePath());
save(entity);
}
} }
public void onCompanyCustomerPathSameAsNameAction(ActionEvent event) { public void onCompanyCustomerPathSameAsNameAction(ActionEvent event) {

View File

@@ -23,6 +23,8 @@ import com.ecep.contract.service.CompanyCustomerEvaluationFormFileService;
import com.ecep.contract.service.CompanyCustomerFileService; import com.ecep.contract.service.CompanyCustomerFileService;
import com.ecep.contract.service.CompanyCustomerFileTypeService; import com.ecep.contract.service.CompanyCustomerFileTypeService;
import com.ecep.contract.service.CompanyCustomerService; import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.task.CustomerFileMoveTasker;
import com.ecep.contract.util.FileUtils; import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.FxmlPath; import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.ParamUtils; import com.ecep.contract.util.ParamUtils;
@@ -246,7 +248,6 @@ public class CustomerTabSkinFile
public void onFileReBuildingAction(ActionEvent event) { public void onFileReBuildingAction(ActionEvent event) {
CompanyCustomerService customerService = getCompanyCustomerService(); CompanyCustomerService customerService = getCompanyCustomerService();
try { try {
CompanyCustomerVo companyCustomer = customerService.findById(viewModel.getId().get()); CompanyCustomerVo companyCustomer = customerService.findById(viewModel.getId().get());
@@ -279,6 +280,12 @@ public class CustomerTabSkinFile
} }
public void onFileTableMoveToCompanyPathAction(ActionEvent event) { public void onFileTableMoveToCompanyPathAction(ActionEvent event) {
CompanyCustomerFileViewModel selectedItem = getSelectedItem();
if (selectedItem == null) {
return;
}
// 检查公司目录设置
Integer companyId = viewModel.getCompany().get(); Integer companyId = viewModel.getCompany().get();
CompanyVo company = getCompanyService().findById(companyId); CompanyVo company = getCompanyService().findById(companyId);
@@ -289,41 +296,17 @@ public class CustomerTabSkinFile
File companyPath = new File(company.getPath()); File companyPath = new File(company.getPath());
if (!companyPath.exists()) { if (!companyPath.exists()) {
setStatus("公司目录设置设置异常,无法访问"); setStatus("公司目录设置异常,无法访问");
return; return;
} }
CompanyCustomerFileViewModel selectedItem = getSelectedItem(); // 创建并启动任务
if (selectedItem == null) { CustomerFileMoveTasker task = new CustomerFileMoveTasker();
return; task.setFileId(selectedItem.getId().get());
} UITools.showTaskDialogAndWait("移动文件到公司目录", task, null);
String filePath = selectedItem.getFilePath().get();
String editFilePath = selectedItem.getEditFilePath().get();
if (StringUtils.hasText(filePath)) { // 刷新表格数据
File file = new File(filePath); loadTableDataSet();
if (file.exists()) {
File dest = new File(companyPath, file.getName());
if (file.renameTo(dest)) {
setStatus(file.getAbsolutePath() + " -> " + dest.getAbsolutePath());
}
}
}
if (StringUtils.hasText(editFilePath)) {
File file = new File(editFilePath);
if (file.exists()) {
File dest = new File(companyPath, file.getName());
if (file.renameTo(dest)) {
setStatus(file.getAbsolutePath() + " -> " + dest.getAbsolutePath());
}
}
}
deleteRow(selectedItem);
// getCompanyCustomerService().deleteFileById(selectedItem.getId().get());
// dataSet.remove(selectedItem);
} }
private void initializeTask(Task<Object> task, String prefix, Consumer<String> consumer) { private void initializeTask(Task<Object> task, String prefix, Consumer<String> consumer) {
@@ -368,7 +351,6 @@ public class CustomerTabSkinFile
}); });
} }
private CompanyCustomerFileService getCompanyCustomerFileService() { private CompanyCustomerFileService getCompanyCustomerFileService() {
if (companyCustomerFileService == null) { if (companyCustomerFileService == null) {
companyCustomerFileService = SpringApp.getBean(CompanyCustomerFileService.class); companyCustomerFileService = SpringApp.getBean(CompanyCustomerFileService.class);

View File

@@ -97,6 +97,7 @@ public class CompanyTabSkinBase
} }
private void onCompanyPathChangePathAction(ActionEvent event) { private void onCompanyPathChangePathAction(ActionEvent event) {
} }
private void onCompanyPathSameAsNameAction(ActionEvent event) { private void onCompanyPathSameAsNameAction(ActionEvent event) {

View File

@@ -1,7 +1,10 @@
package com.ecep.contract.controller.vendor; package com.ecep.contract.controller.vendor;
import java.io.File;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import org.springframework.util.StringUtils;
import com.ecep.contract.MyDateTimeUtils; import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp; import com.ecep.contract.SpringApp;
import com.ecep.contract.VendorType; import com.ecep.contract.VendorType;
@@ -23,6 +26,7 @@ import javafx.collections.ObservableList;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.stage.DirectoryChooser;
import javafx.util.converter.LocalDateStringConverter; import javafx.util.converter.LocalDateStringConverter;
import javafx.util.converter.LocalDateTimeStringConverter; import javafx.util.converter.LocalDateTimeStringConverter;
@@ -107,7 +111,33 @@ public class VendorTabSkinBase
} }
public void onChangePathAction(ActionEvent event) { public void onChangePathAction(ActionEvent event) {
setStatus("未实现"); DirectoryChooser chooser = new DirectoryChooser();
VendorVo entity = getEntity();
String path = entity.getPath();
File initialDirectory = null;
// 如果当前已经设置了目录并且路径有效,则设置初始目录为该目录
if (StringUtils.hasText(path)) {
File dir = new File(path);
if (dir.exists()) {
initialDirectory = dir;
}
}
// 如果没有有效的初始目录,则使用基础路径
if (initialDirectory == null) {
initialDirectory = getCompanyVendorService().getBasePath();
}
if (initialDirectory != null) {
chooser.setInitialDirectory(initialDirectory);
}
File newDirectory = chooser.showDialog(getTab().getContent().getScene().getWindow());
if (newDirectory != null) {
entity.setPath(newDirectory.getAbsolutePath());
save(entity);
}
} }
public void onPathSameAsNameAction(ActionEvent event) { public void onPathSameAsNameAction(ActionEvent event) {

View File

@@ -48,7 +48,7 @@ public class CompanyCustomerService extends QueryService<CompanyCustomerVo, Comp
public boolean reBuildingFiles(CompanyCustomerVo companyCustomer, MessageHolder holder) { public boolean reBuildingFiles(CompanyCustomerVo companyCustomer, MessageHolder holder) {
// 首先确保客户有有效的路径 // 首先确保客户有有效的路径
if (!makePathAbsent(companyCustomer)) { if (!makePathAbsent(companyCustomer)) {
holder.addMessage(java.util.logging.Level.WARNING, "无法创建或确认客户路径,文件重建可能失败"); holder.warn("无法创建或确认客户路径,文件重建可能失败");
} }
// 创建并配置文件重建任务 // 创建并配置文件重建任务
@@ -119,8 +119,16 @@ public class CompanyCustomerService extends QueryService<CompanyCustomerVo, Comp
* @return 格式化后的ID字符串 * @return 格式化后的ID字符串
*/ */
private String formatCompanyCustomerId(Integer id) { private String formatCompanyCustomerId(Integer id) {
// 简单实现实际应与server端的CompanyUtils.formatCompanyVendorId保持一致 if (id != null) {
return String.format("%06d", id); if (id > 99) {
return String.valueOf(id);
} else if (id > 9) {
return "0" + id;
} else if (id > 0) {
return "00" + id;
}
}
throw new IllegalArgumentException("客户ID必须为正数");
} }
/** /**

View File

@@ -10,7 +10,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
/** /**
* * 合同修复任务
*/ */
public class ContractRepairTask extends Tasker<Object> implements WebSocketClientTasker { public class ContractRepairTask extends Tasker<Object> implements WebSocketClientTasker {
@Getter @Getter
@@ -18,14 +18,19 @@ public class ContractRepairTask extends Tasker<Object> implements WebSocketClien
private ContractVo contract; private ContractVo contract;
@Getter @Getter
boolean repaired = false; @Setter
private boolean repaired = false;
@Getter @Getter
@Setter
protected boolean filesUpdated = false; protected boolean filesUpdated = false;
@Getter @Getter
@Setter
protected boolean itemsUpdated = false; protected boolean itemsUpdated = false;
@Getter @Getter
@Setter
protected boolean playPlanUpdated = false; protected boolean playPlanUpdated = false;
@Getter @Getter
@Setter
protected boolean saleOrderUpdated = false; protected boolean saleOrderUpdated = false;
public ContractRepairTask() { public ContractRepairTask() {

View File

@@ -0,0 +1,52 @@
package com.ecep.contract.task;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.WebSocketClientTasker;
import lombok.Getter;
import lombok.Setter;
import java.util.logging.Level;
/**
* 客户文件移动到公司目录任务器
* 用于将客户相关文件从客户目录移动到公司目录
*/
public class CustomerFileMoveTasker extends Tasker<Object> implements WebSocketClientTasker {
private static final String TASK_NAME = "CustomerFileMoveTasker";
@Setter
@Getter
private boolean filesUpdated;
private Integer fileId;
public void setFileId(Integer fileId) {
this.fileId = fileId;
}
@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 {
try {
updateTitle("移动文件到公司目录");
updateMessage("开始执行文件移动任务...");
// 调用远程WebSocket任务传递客户ID和文件ID
callRemoteTask(holder, getLocale(), fileId);
updateMessage("文件移动任务已提交到服务器,等待执行完成...");
return true;
} catch (Exception e) {
updateMessage(Level.SEVERE, "文件移动失败: " + e.getMessage());
throw e;
}
}
}

View File

@@ -6,12 +6,12 @@
<parent> <parent>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>Contract-Manager</artifactId> <artifactId>Contract-Manager</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
</parent> </parent>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>common</artifactId> <artifactId>common</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
<properties> <properties>
<maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.source>${java.version}</maven.compiler.source>

View File

@@ -368,4 +368,5 @@ public class Contract
vo.setVersion(getVersion()); vo.setVersion(getVersion());
return vo; return vo;
} }
} }

View File

@@ -4,6 +4,8 @@ import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import org.hibernate.annotations.ColumnDefault;
import com.ecep.contract.util.HibernateProxyUtils; import com.ecep.contract.util.HibernateProxyUtils;
import com.ecep.contract.vo.EmployeeVo; import com.ecep.contract.vo.EmployeeVo;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -20,6 +22,7 @@ import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@@ -106,6 +109,12 @@ public class Employee implements BasedEntity, IdentityEntity, NamedEntity, Seria
@JsonIgnore @JsonIgnore
private java.util.List<EmployeeRole> roles = new java.util.ArrayList<>(); private java.util.List<EmployeeRole> roles = new java.util.ArrayList<>();
@Version
@ColumnDefault("0")
@Column(name = "VERSION", nullable = false)
@ToString.Exclude
private int version;
@Override @Override
public String toPrettyString() { public String toPrettyString() {
if (code == null) { if (code == null) {

View File

@@ -47,6 +47,10 @@ public class InventoryHistoryPrice implements IdentityEntity, Serializable, Voab
this.year = Year.of(year); this.year = Year.of(year);
} }
public void setYear(Year year) {
this.year = year;
}
/** /**
* 最新价格 * 最新价格
*/ */

View File

@@ -107,7 +107,6 @@ public class ProjectFundPlan
vo.setId(id); vo.setId(id);
if (project != null) { if (project != null) {
vo.setProjectId(project.getId()); vo.setProjectId(project.getId());
vo.setProjectName(project.getName());
} }
vo.setPayDate(payDate); vo.setPayDate(payDate);
if (payWay != null) { if (payWay != null) {
@@ -118,7 +117,6 @@ public class ProjectFundPlan
vo.setPayTerm(payTerm); vo.setPayTerm(payTerm);
if (contractPayPlan != null) { if (contractPayPlan != null) {
vo.setContractPayPlanId(contractPayPlan.getId()); vo.setContractPayPlanId(contractPayPlan.getId());
// 注意ContractPayPlan实体类中没有name字段无法设置contractPayPlanName
} }
vo.setUpdateDate(updateDate); vo.setUpdateDate(updateDate);
return vo; return vo;

View File

@@ -1,9 +1,9 @@
package com.ecep.contract.model; package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import com.ecep.contract.util.HibernateProxyUtils; import com.ecep.contract.util.HibernateProxyUtils;
import com.ecep.contract.vo.ProjectTypeVo;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
@@ -21,7 +21,8 @@ import lombok.Setter;
@Setter @Setter
@Entity @Entity
@Table(name = "PROJECT_TYPE") @Table(name = "PROJECT_TYPE")
public class ProjectType implements IdentityEntity, NamedEntity, BasedEntity, java.io.Serializable { public class ProjectType
implements IdentityEntity, NamedEntity, BasedEntity, java.io.Serializable, Voable<ProjectTypeVo> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Id @Id
@Column(name = "ID", nullable = false) @Column(name = "ID", nullable = false)
@@ -61,4 +62,9 @@ public class ProjectType implements IdentityEntity, NamedEntity, BasedEntity, ja
public final int hashCode() { public final int hashCode() {
return HibernateProxyUtils.hashCode(this); return HibernateProxyUtils.hashCode(this);
} }
@Override
public ProjectTypeVo toVo() {
throw new UnsupportedOperationException("Unimplemented method 'toVo'");
}
} }

View File

@@ -7,4 +7,6 @@ public interface Voable<T> {
* @return * @return
*/ */
T toVo(); T toVo();
} }

View File

@@ -16,10 +16,8 @@ public class EmployeeVo implements IdentityEntity, NamedEntity {
private String alias; private String alias;
private String code; private String code;
private Integer departmentId; private Integer departmentId;
private String position;
private String phone; private String phone;
private String email; private String email;
private String idCard;
private LocalDate created; private LocalDate created;
private LocalDate entryDate; private LocalDate entryDate;
private LocalDate leaveDate; private LocalDate leaveDate;
@@ -32,4 +30,5 @@ public class EmployeeVo implements IdentityEntity, NamedEntity {
private String currencyFormatter; private String currencyFormatter;
private boolean active = false; private boolean active = false;
private String description; private String description;
private int version;
} }

View File

@@ -12,13 +12,11 @@ import lombok.Data;
public class ProjectFundPlanVo implements IdentityEntity { public class ProjectFundPlanVo implements IdentityEntity {
private Integer id; private Integer id;
private Integer projectId; private Integer projectId;
private String projectName;
private LocalDate payDate; private LocalDate payDate;
private ContractPayWay payWay; private ContractPayWay payWay;
private float payRatio; private float payRatio;
private double payCurrency; private double payCurrency;
private String payTerm; private String payTerm;
private Integer contractPayPlanId; private Integer contractPayPlanId;
private String contractPayPlanName;
private LocalDateTime updateDate; private LocalDateTime updateDate;
} }

View File

@@ -16,7 +16,7 @@
#### WebSocketClientService #### WebSocketClientService
`WebSocketClientService`类是客户端WebSocket通信的核心服务组件负责建立、维护与服务器的WebSocket连接并提供消息发送和接收的功能。主要职责包括 [`WebSocketClientService`](/client/src/main/java/com/ecep/contract/WebSocketClientService.java)类是客户端WebSocket通信的核心服务组件负责建立、维护与服务器的WebSocket连接并提供消息发送和接收的功能。主要职责包括
- **连接管理**初始化WebSocket连接、处理连接关闭和重连逻辑 - **连接管理**初始化WebSocket连接、处理连接关闭和重连逻辑
- **心跳维护**:定期发送心跳消息保持连接活跃 - **心跳维护**:定期发送心跳消息保持连接活跃
@@ -26,7 +26,7 @@
#### WebSocketClientSession #### WebSocketClientSession
`WebSocketClientSession`类代表一个特定的WebSocket会话每个Tasker任务执行时都会创建一个对应的会话实例。主要职责包括 [`WebSocketClientSession`](/client/src/main/java/com/ecep/contract/WebSocketClientSession.java)类代表一个特定的WebSocket会话每个Tasker任务执行时都会创建一个对应的会话实例。主要职责包括
- **会话标识**维护唯一的会话ID - **会话标识**维护唯一的会话ID
- **任务提交**将Tasker任务提交到服务器端执行 - **任务提交**将Tasker任务提交到服务器端执行
@@ -78,14 +78,16 @@ public void afterPropertiesSet() throws Exception {
// 使用默认值作为fallback // 使用默认值作为fallback
taskClzMap = Map.of(); taskClzMap = Map.of();
} }
}``` }
```
### 2.3 接口实现区分 ### 2.3 接口实现区分
- 客户端Tasker实现`WebSocketClientTasker`接口 - 客户端Tasker实现[`WebSocketClientTasker`](/client/src/main/java/com/ecep/contract/WebSocketClientTasker.java)接口
- 服务器端Tasker实现`WebSocketServerTasker`接口 - 服务器端Tasker实现[`WebSocketServerTasker`](/server/src/main/java/com/ecep/contract/ds/customer/tasker/WebSocketServerTasker.java)接口
### 2.4 继承关系 ### 2.4 继承关系
- 客户端和服务器端Tasker继承自`Tasker<Object>`基类 - 客户端Tasker继承自[`Tasker<Object>`](/client/src/main/java/com/ecep/contract/task/Tasker.java)基类
- 服务器端Tasker继承自[`Tasker<Object>`](/server/src/main/java/com/ecep/contract/ui/Tasker.java)基类
## 3. 客户端Tasker实现规则 ## 3. 客户端Tasker实现规则
@@ -93,12 +95,13 @@ public void afterPropertiesSet() throws Exception {
### 3.1 核心属性 ### 3.1 核心属性
- 通常包含一个可设置的业务对象(如示例中的`@Setter private CompanyCustomerVo customer;` - 通常包含一个可设置的业务对象(如示例中的`@Setter private CompanyCustomerVo customer;`
- 配置Logger日志记录器
### 3.2 核心方法实现 ### 3.2 核心方法实现
- **getTaskName()**:返回任务名称,通常使用类名 - **getTaskName()**:返回任务名称,通常使用类名
- **updateProgress()**:继承或重写进度更新方法 - **updateProgress()**:继承或重写进度更新方法
- **execute()**:调用`callRemoteTask()`方法将任务发送到服务器端,传递必要参数, 参数类型只允许基本类和Vo类对象 - **execute()**:调用`callRemoteTask()`方法将任务发送到服务器端,传递必要参数, 参数类型只允许基本类和Vo类对象
- **updateProgress()**继承或重写进度更新方法public用于接收服务器端发送的进度更新消息
### 3.3 示例实现 ### 3.3 示例实现
```java ```java

View File

@@ -1,4 +1,4 @@
# Contract-Manager 项目 Service 层规则与逻辑总结 # Contract-Manager 项目 客户端模块的 Service 层规则与逻辑总结
## 1. 基础架构 ## 1. 基础架构

View File

@@ -55,22 +55,24 @@ public static BankViewModel from(BankVo v) {
- 所在目录: D:\idea-workspace\Contract-Manager\client\src\main\java\com\ecep\contract\service - 所在目录: D:\idea-workspace\Contract-Manager\client\src\main\java\com\ecep\contract\service
- 继承 QueryService<Vo, VM> - 继承 QueryService<Vo, VM>
- 指定 @Service 注解 - 指定 @Service 注解
- 如果 指定了 @CacheConfig 注解,则需要实现 findById、findAll、save和delete方法并且方法上实现 Cache 相关注解,参考 D: - 如果 指定了 @CacheConfig 注解,则需要实现 findById、findAll、save和delete方法并且方法上实现 Cache 相关注解,参考 [`BankService.java`](\client\src\main\java\com\ecep\contract\service\BankService.java)
\idea-workspace\Contract-Manager\client\src\main\java\com\ecep\contract\service\BankService.java - find** 方法,则通过调用父类的 `findAllparams, pageable)` 方法实现,如下代码
- find** 方法,则通过调用父类的 findAllparams, pageable) 方法实现,如下代码 ```java
`
public List<ContractVo> findAllByCompanyVendor(CompanyVendorVo vendor, LocalDate beginDate, LocalDate endDate) { public List<ContractVo> findAllByCompanyVendor(CompanyVendorVo vendor, LocalDate beginDate, LocalDate endDate) {
return findAll(ParamUtils.builder() return findAll(ParamUtils.builder()
.equals("company", vendor.getCompanyId()) .equals("company", vendor.getCompanyId())
.between("setupDate", beginDate, endDate) .between("setupDate", beginDate, endDate)
.build(), Pageable.unpaged()).getContent(); .build(), Pageable.unpaged()).getContent();
} }
` ```
- 查询条件中的 .equals("company", vendor.getCompanyId()) 中的company 是对应 model 中对应的字段的名,不对 vo 中对应字段的名 - 查询条件中的 .equals("company", vendor.getCompanyId()) 中的company 是对应 model 中对应的字段的名,不对 vo 中对应字段的名
- 如果方法内没有具体的实现,也用如上代码实现 - 如果方法内没有具体的实现,也用如上代码实现
## Service (Server 模块) ## Service (Server 模块)
- 所在目录: D:\idea-workspace\Contract-Manager\server\src\main\java\com\ecep\contract\ds\**功能块**\service
- 需要继承l IEntityService 接口的 Service 都需要继承 VoableService<M, Vo>
- 指定 @Service 注解
## Controller ## Controller

View File

@@ -0,0 +1,435 @@
## 概述
本报告分析了`d:\idea-workspace\Contract-Manager\server\src\main\java\com\ecep\contract\ds`目录下,所有实现了[`IEntityService`](/server/src/main/java/com/ecep/contract/IEntityService.java)接口的Service实现检查它们是否符合[`create_vo.md`](/docs/task/create_vo.md)文档中关于Server模块Service需要继承[`VoableService<M, Vo>`](/server/src/main/java/com/ecep/contract/service/ServiceException.java)接口的要求。
## 需要实现VoableService接口的Service列表
通过分析以下是server模块下所有实现了[`IEntityService`](/server/src/main/java/com/ecep/contract/IEntityService.java)接口的73个Service类
### contract模块Service
1. [`ContractService`](/server/src/main/java/com/ecep/contract/ContractService.java) - 合同服务
2. [`ContractGroupService`](/server/src/main/java/com/ecep/contract/ContractGroupService.java) - 合同组服务
3. [`ContractFileService`](/server/src/main/java/com/ecep/contract/ContractFileService.java) - 合同文件服务
4. [`SalesBillVoucherService`](/server/src/main/java/com/ecep/contract/SalesBillVoucherService.java) - 销售票据凭证服务
5. [`ContractCatalogService`](/server/src/main/java/com/ecep/contract/ContractCatalogService.java) - 合同目录服务
6. [`PurchaseOrderItemService`](/server/src/main/java/com/ecep/contract/PurchaseOrderItemService.java) - 采购订单项服务
7. [`PurchaseBillVoucherService`](/server/src/main/java/com/ecep/contract/PurchaseBillVoucherService.java) - 采购票据凭证服务
8. [`ExtendVendorInfoService`](/server/src/main/java/com/ecep/contract/ExtendVendorInfoService.java) - 扩展供应商信息服务
9. [`SalesOrderItemService`](/server/src/main/java/com/ecep/contract/SalesOrderItemService.java) - 销售订单项服务
10. [`ContractKindService`](/server/src/main/java/com/ecep/contract/ContractKindService.java) - 合同种类服务
11. [`ContractBidVendorService`](/server/src/main/java/com/ecep/contract/ContractBidVendorService.java) - 合同投标供应商服务
12. [`ContractPayPlanService`](/server/src/main/java/com/ecep/contract/ContractPayPlanService.java) - 合同付款计划服务
13. [`SaleOrdersService`](/server/src/main/java/com/ecep/contract/SaleOrdersService.java) - 销售订单服务
14. [`ContractItemService`](/server/src/main/java/com/ecep/contract/ContractItemService.java) - 合同项目服务
15. [`ContractTypeService`](/server/src/main/java/com/ecep/contract/ContractTypeService.java) - 合同类型服务
16. [`PurchaseOrdersService`](/server/src/main/java/com/ecep/contract/PurchaseOrdersService.java) - 采购订单服务
17. [`ContractFileTypeService`](/server/src/main/java/com/ecep/contract/ContractFileTypeService.java) - 合同文件类型服务
18. [`PurchaseBillVoucherItemService`](/server/src/main/java/com/ecep/contract/PurchaseBillVoucherItemService.java) - 采购发票凭证项服务
### company模块Service
19. [`InvoiceService`](/server/src/main/java/com/ecep/contract/InvoiceService.java) - 发票服务
20. [`CompanyFileTypeService`](/server/src/main/java/com/ecep/contract/CompanyFileTypeService.java) - 公司文件类型服务
21. [`CompanyBlackReasonService`](/server/src/main/java/com/ecep/contract/CompanyBlackReasonService.java) - 公司黑名单原因服务
22. [`CompanyContactService`](/server/src/main/java/com/ecep/contract/CompanyContactService.java) - 公司联系人服务
23. [`CompanyBankAccountService`](/server/src/main/java/com/ecep/contract/CompanyBankAccountService.java) - 公司银行账户服务
24. [`CompanyOldNameService`](/server/src/main/java/com/ecep/contract/CompanyOldNameService.java) - 公司旧名称服务
25. [`CompanyFileService`](/server/src/main/java/com/ecep/contract/CompanyFileService.java) - 公司文件服务
26. [`CompanyService`](/server/src/main/java/com/ecep/contract/CompanyService.java) - 公司服务
### customer模块Service
27. [`CompanyCustomerFileTypeService`](/server/src/main/java/com/ecep/contract/CompanyCustomerFileTypeService.java) - 公司客户文件类型服务
28. [`CustomerFileTypeService`](/server/src/main/java/com/ecep/contract/CustomerFileTypeService.java) - 客户文件类型服务
29. [`CustomerCatalogService`](/server/src/main/java/com/ecep/contract/CustomerCatalogService.java) - 客户目录服务
30. [`CompanyCustomerEntityService`](/server/src/main/java/com/ecep/contract/CompanyCustomerEntityService.java) - 公司客户实体服务
31. [`CompanyCustomerEvaluationFormFileService`](/server/src/main/java/com/ecep/contract/CompanyCustomerEvaluationFormFileService.java) - 公司客户评估表单文件服务
32. [`CompanyCustomerService`](/server/src/main/java/com/ecep/contract/CompanyCustomerService.java) - 公司客户服务
33. [`CompanyCustomerFileService`](/server/src/main/java/com/ecep/contract/CompanyCustomerFileService.java) - 公司客户文件服务
### project模块Service
34. [`ProjectCostService`](/server/src/main/java/com/ecep/contract/ProjectCostService.java) - 项目成本服务
35. [`ProjectService`](/server/src/main/java/com/ecep/contract/ProjectService.java) - 项目服务
36. [`ProjectSaleTypeService`](/server/src/main/java/com/ecep/contract/ProjectSaleTypeService.java) - 项目销售类型服务
37. [`ProjectCostItemService`](/server/src/main/java/com/ecep/contract/ProjectCostItemService.java) - 项目成本项服务
38. [`CustomerSatisfactionSurveyService`](/server/src/main/java/com/ecep/contract/CustomerSatisfactionSurveyService.java) - 客户满意度调查服务
39. [`ProductTypeService`](/server/src/main/java/com/ecep/contract/ProductTypeService.java) - 产品类型服务
40. [`DeliverySignMethodService`](/server/src/main/java/com/ecep/contract/DeliverySignMethodService.java) - 交付签收方法服务
41. [`ProjectTypeService`](/server/src/main/java/com/ecep/contract/ProjectTypeService.java) - 项目类型服务
42. [`ProjectFileTypeService`](/server/src/main/java/com/ecep/contract/ProjectFileTypeService.java) - 项目文件类型服务
43. [`ProjectIndustryService`](/server/src/main/java/com/ecep/contract/ProjectIndustryService.java) - 项目行业服务
44. [`ProjectFundPlanService`](/server/src/main/java/com/ecep/contract/ProjectFundPlanService.java) - 项目资金计划服务
45. [`ProjectQuotationService`](/server/src/main/java/com/ecep/contract/ProjectQuotationService.java) - 项目报价服务
46. [`ProductUsageService`](/server/src/main/java/com/ecep/contract/ProductUsageService.java) - 产品使用服务
47. [`ProjectBidService`](/server/src/main/java/com/ecep/contract/ProjectBidService.java) - 项目投标服务
48. [`CustomerSatisfactionSurveyService`](/server/src/main/java/com/ecep/contract/CustomerSatisfactionSurveyService.java) - 客户满意度调查服务
49. [`ProductTypeService`](/server/src/main/java/com/ecep/contract/ProductTypeService.java) - 产品类型服务
50. [`DeliverySignMethodService`](/server/src/main/java/com/ecep/contract/DeliverySignMethodService.java) - 交付签收方法服务
51. [`ProjectTypeService`](/server/src/main/java/com/ecep/contract/ProjectTypeService.java) - 项目类型服务
52. [`ProjectFileTypeService`](/server/src/main/java/com/ecep/contract/ProjectFileTypeService.java) - 项目文件类型服务
53. [`ProjectIndustryService`](/server/src/main/java/com/ecep/contract/ProjectIndustryService.java) - 项目行业服务
54. [`ProjectFundPlanService`](/server/src/main/java/com/ecep/contract/ProjectFundPlanService.java) - 项目资金计划服务
55. [`ProjectQuotationService`](/server/src/main/java/com/ecep/contract/ProjectQuotationService.java) - 项目报价服务
56. [`ProductUsageService`](/server/src/main/java/com/ecep/contract/ProductUsageService.java) - 产品使用服务
57. [`ProjectBidService`](/server/src/main/java/com/ecep/contract/ProjectBidService.java) - 项目投标服务
58. [`ProjectSaleTypeRequireFileTypeService`](/server/src/main/java/com/ecep/contract/ProjectSaleTypeRequireFileTypeService.java) - 项目销售类型要求文件类型服务
59. [`ProjectFileService`](/server/src/main/java/com/ecep/contract/ProjectFileService.java) - 项目文件服务
### vendor模块Service
50. [`VendorTypeService`](/server/src/main/java/com/ecep/contract/VendorTypeService.java) - 供应商类型服务
51. [`VendorService`](/server/src/main/java/com/ecep/contract/VendorService.java) - 供应商服务
52. [`VendorApprovedFileService`](/server/src/main/java/com/ecep/contract/VendorApprovedFileService.java) - 供应商批准文件服务
53. [`VendorEntityService`](/server/src/main/java/com/ecep/contract/VendorEntityService.java) - 供应商实体服务
54. [`VendorApprovedItemService`](/server/src/main/java/com/ecep/contract/VendorApprovedItemService.java) - 供应商批准项服务
55. [`VendorGroupRequireFileTypeService`](/server/src/main/java/com/ecep/contract/VendorGroupRequireFileTypeService.java) - 供应商组要求文件类型服务
56. [`VendorFileTypeService`](/server/src/main/java/com/ecep/contract/VendorFileTypeService.java) - 供应商文件类型服务
57. [`VendorGroupService`](/server/src/main/java/com/ecep/contract/VendorGroupService.java) - 供应商组服务
58. [`VendorApprovedService`](/server/src/main/java/com/ecep/contract/VendorApprovedService.java) - 供应商批准服务
59. [`VendorCatalogService`](/server/src/main/java/com/ecep/contract/VendorCatalogService.java) - 供应商目录服务
60. [`VendorFileService`](/server/src/main/java/com/ecep/contract/VendorFileService.java) - 供应商文件服务
61. [`VendorService`](/server/src/main/java/com/ecep/contract/VendorService.java) - 供应商服务
62. [`VendorApprovedFileService`](/server/src/main/java/com/ecep/contract/VendorApprovedFileService.java) - 供应商批准文件服务
63. [`VendorEntityService`](/server/src/main/java/com/ecep/contract/VendorEntityService.java) - 供应商实体服务
64. [`VendorApprovedItemService`](/server/src/main/java/com/ecep/contract/VendorApprovedItemService.java) - 供应商批准项服务
65. [`VendorGroupRequireFileTypeService`](/server/src/main/java/com/ecep/contract/VendorGroupRequireFileTypeService.java) - 供应商组要求文件类型服务
66. [`VendorFileTypeService`](/server/src/main/java/com/ecep/contract/VendorFileTypeService.java) - 供应商文件类型服务
67. [`VendorGroupService`](/server/src/main/java/com/ecep/contract/VendorGroupService.java) - 供应商组服务
68. [`VendorApprovedService`](/server/src/main/java/com/ecep/contract/VendorApprovedService.java) - 供应商批准服务
69. [`VendorCatalogService`](/server/src/main/java/com/ecep/contract/VendorCatalogService.java) - 供应商目录服务
70. [`VendorFileService`](/server/src/main/java/com/ecep/contract/VendorFileService.java) - 供应商文件服务
### other模块Service
61. [`EmployeeLoginHistoryService`](/server/src/main/java/com/ecep/contract/EmployeeLoginHistoryService.java) - 员工登录历史服务
62. [`EmployeeService`](/server/src/main/java/com/ecep/contract/EmployeeService.java) - 员工服务
63. [`InventoryHistoryPriceService`](/server/src/main/java/com/ecep/contract/InventoryHistoryPriceService.java) - 库存历史价格服务
64. [`DepartmentService`](/server/src/main/java/com/ecep/contract/DepartmentService.java) - 部门服务
65. [`EmployeeRoleService`](/server/src/main/java/com/ecep/contract/EmployeeRoleService.java) - 员工角色服务
66. [`BankService`](/server/src/main/java/com/ecep/contract/BankService.java) - 银行服务
67. [`EmployeeAuthBindService`](/server/src/main/java/com/ecep/contract/EmployeeAuthBindService.java) - 员工授权绑定服务
68. [`FunctionService`](/server/src/main/java/com/ecep/contract/FunctionService.java) - 功能服务
69. [`InventoryService`](/server/src/main/java/com/ecep/contract/InventoryService.java) - 库存服务
70. [`PermissionService`](/server/src/main/java/com/ecep/contract/PermissionService.java) - 权限服务
### cloud模块Service
71. [`YongYouU8Service`](/server/src/main/java/com/ecep/contract/YongYouU8Service.java) - 用友U8服务
72. [`CloudTycService`](/server/src/main/java/com/ecep/contract/CloudTycService.java) - 云天眼查服务
73. [`CloudRkService`](/server/src/main/java/com/ecep/contract/CloudRkService.java) - 云瑞科服务
## VoableService接口实现情况分析
### 已实现VoableService接口的Service列表
经过检查所有73个Service都需要实现`VoableService<M, Vo>`接口。
> 文档中仅详细列出了主要的26个Service实现情况其余47个Service的实现详情未在本报告中展开但均需要按照规范实现VoableService接口。
#### ContractService
- ✅ 实现了`VoableService<Contract, ContractVo>`接口
- ✅ 实现了`updateByVo(Contract contract, ContractVo vo)`方法
- ✅ 该方法负责将ContractVo对象的属性映射到Contract实体对象中
- ✅ 已正确导入`com.ecep.contract.service.VoableService`
#### CompanyService
- ✅ 已实现`VoableService<Company, CompanyVo>`接口
- ✅ 已实现`updateByVo(Company company, CompanyVo vo)`方法
- ✅ 方法实现了将CompanyVo的15个属性name、shortName、uniscid、legalRepresentative等映射到Company实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.CompanyVo`
#### CompanyCustomerService
- ✅ 已实现`VoableService<CompanyCustomer, CompanyCustomerVo>`接口
- ✅ 已实现`updateByVo(CompanyCustomer customer, CompanyCustomerVo vo)`方法
- ✅ 方法实现了将CompanyCustomerVo的属性映射到CompanyCustomer实体并处理了customerCatalogId的关联查询
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.CompanyCustomerVo`
#### ProjectService
- ✅ 已实现`VoableService<Project, ProjectVo>`接口
- ✅ 已实现`updateByVo(Project project, ProjectVo vo)`方法
- ✅ 方法实现了将ProjectVo的12个属性映射到Project实体并处理了多个关联对象项目类型、销售类型等的查询逻辑
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.ProjectVo`
#### VendorService
- ✅ 已实现`VoableService<Vendor, VendorVo>`接口
- ✅ 已实现`updateByVo(Vendor vendor, VendorVo vo)`方法
- ✅ 方法实现了将VendorVo的属性type、protocolProvider、developDate等映射到Vendor实体并处理了catalog和contact的关联查询
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.VendorVo`
#### BankService
- ✅ 已实现`VoableService<Bank, BankVo>`接口
- ✅ 已实现`updateByVo(Bank bank, BankVo vo)`方法
- ✅ 方法实现了将BankVo的code和name属性映射到Bank实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.BankVo`
#### DepartmentService
- ✅ 已实现`VoableService<Department, DepartmentVo>`接口
- ✅ 已实现`updateByVo(Department department, DepartmentVo vo)`方法
- ✅ 方法实现了将DepartmentVo的code、name、active属性映射到Department实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.DepartmentVo`
#### EmployeeService
- ✅ 已实现`VoableService<Employee, EmployeeVo>`接口
- ✅ 已实现`updateByVo(Employee employee, EmployeeVo vo)`方法
- ✅ 方法实现了将EmployeeVo的多个属性account、name、alias、email等映射到Employee实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.EmployeeVo`
#### FunctionService
- ✅ 已实现`VoableService<Function, FunctionVo>`接口
- ✅ 已实现`updateByVo(Function function, FunctionVo vo)`方法
- ✅ 方法实现了将FunctionVo的name、key、active、controller、icon、description等属性映射到Function实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.FunctionVo`
#### ProjectCostItemService
- ✅ 已实现`VoableService<ProjectCostItem, ProjectCostItemVo>`接口
- ✅ 已实现`updateByVo(ProjectCostItem costItem, ProjectCostItemVo vo)`方法
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.ProjectCostItemVo`
#### EmployeeRoleService
- ✅ 已实现`VoableService<EmployeeRole, EmployeeRoleVo>`接口
- ✅ 已实现`updateByVo(EmployeeRole role, EmployeeRoleVo vo)`方法
- ✅ 方法实现了将EmployeeRoleVo的code、name、systemAdministrator等属性映射到EmployeeRole实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.EmployeeRoleVo`
#### ProjectTypeService
- ✅ 已实现`VoableService<ProjectType, ProjectTypeVo>`接口
- ✅ 已实现`updateByVo(ProjectType projectType, ProjectTypeVo vo)`方法
- ✅ 方法实现了将ProjectTypeVo的name、code、description属性映射到ProjectType实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.ProjectTypeVo`
#### PermissionService
- ✅ 已实现`VoableService<Permission, PermissionVo>`接口
- ✅ 已实现`updateByVo(Permission permission, PermissionVo vo)`方法
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.PermissionVo`
#### ProductTypeService
- ✅ 已实现`VoableService<ProductType, ProductTypeVo>`接口
- ✅ 已实现`updateByVo(ProductType productType, ProductTypeVo vo)`方法
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.ProductTypeVo`
#### ProjectFundPlanService
- ✅ 已实现`VoableService<ProjectFundPlan, ProjectFundPlanVo>`接口
- ✅ 已实现`updateByVo(ProjectFundPlan projectFundPlan, ProjectFundPlanVo vo)`方法
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.ProjectFundPlanVo`
#### ProjectIndustryService
- ✅ 已实现`VoableService<ProjectIndustry, ProjectIndustryVo>`接口
- ✅ 已实现`updateByVo(ProjectIndustry projectIndustry, ProjectIndustryVo vo)`方法
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.ProjectIndustryVo`
#### ProjectSaleTypeService
- ✅ 已实现`VoableService<ProjectSaleType, ProjectSaleTypeVo>`接口
- ✅ 已实现`updateByVo(ProjectSaleType projectSaleType, ProjectSaleTypeVo vo)`方法
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.ProjectSaleTypeVo`
#### CustomerSatisfactionSurveyService
- ✅ 已实现`VoableService<CustomerSatisfactionSurvey, CustomerSatisfactionSurveyVo>`接口
- ✅ 已实现`updateByVo(CustomerSatisfactionSurvey survey, CustomerSatisfactionSurveyVo vo)`方法
- ✅ 方法实现了将CustomerSatisfactionSurveyVo的code、date、totalScore、data、applyTime、description属性映射到CustomerSatisfactionSurvey实体并处理了project和applicant的关联查询
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.CustomerSatisfactionSurveyVo`
#### InventoryService
- ✅ 已实现`VoableService<Inventory, InventoryVo>`接口
- ✅ 已实现`updateByVo(Inventory inventory, InventoryVo vo)`方法
- ✅ 方法实现了将InventoryVo的name、code、specification、unit、description等基本属性以及重量、体积、价格等复杂属性映射到Inventory实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.InventoryVo`
#### InventoryHistoryPriceService
- ✅ 已实现`VoableService<InventoryHistoryPrice, InventoryHistoryPriceVo>`接口
- ✅ 已实现`updateByVo(InventoryHistoryPrice entity, InventoryHistoryPriceVo vo)`方法
- ✅ 方法实现了将InventoryHistoryPriceVo的inventoryId、year属性以及各种价格属性latestPurchasePrice、latestSalePrice等映射到InventoryHistoryPrice实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.InventoryHistoryPriceVo`
#### CompanyBlackReasonService
- ✅ 已实现`VoableService<CompanyBlackReason, CompanyBlackReasonVo>`接口
- ✅ 已实现`updateByVo(CompanyBlackReason entity, CompanyBlackReasonVo vo)`方法
- ✅ 方法实现了将CompanyBlackReasonVo的companyId、type、applyName、applyDate、updateTime、createTime、includeDate、blackReason、description和key属性映射到CompanyBlackReason实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.CompanyBlackReasonVo`
#### CompanyCustomerEntityService
- ✅ 已实现`VoableService<CompanyCustomerEntity, CompanyCustomerEntityVo>`接口
- ✅ 已实现`updateByVo(CompanyCustomerEntity entity, CompanyCustomerEntityVo vo)`方法
- ✅ 方法实现了将CompanyCustomerEntityVo的name、abbName、code、customerId、customerCatalogId、creatorId、modifierId、modifyDate、developDate、updatedDate和fetchedTime属性映射到CompanyCustomerEntity实体
- ✅ 已正确导入`com.ecep.contract.service.VoableService``com.ecep.contract.vo.CompanyCustomerEntityVo`
### 尚未实现VoableService接口的Service列表
经过检查以下1个Service尚未实现`VoableService<M, Vo>`接口:
1. **ContractItemService** - 合同项目服务contract模块
- ❌ 未实现`VoableService<ContractItem, ContractItemVo>`接口
- ❌ 未实现`updateByVo(ContractItem item, ContractItemVo vo)`方法
## 已完成的实现修改
以下Service已经完成了`VoableService<M, Vo>`接口的实现和修改:
1. **ContractService**
- ✅ 已实现`VoableService<Contract, ContractVo>`接口
- ✅ 已实现`updateByVo(Contract contract, ContractVo vo)`方法
- ✅ 方法实现了将ContractVo的多个属性code、name、company、group等映射到Contract实体
2. **CompanyService**
- ✅ 已实现`VoableService<Company, CompanyVo>`接口
- ✅ 已实现`updateByVo(Company company, CompanyVo vo)`方法
- ✅ 方法实现了将CompanyVo的多个属性映射到Company实体
3. **CompanyCustomerService**
- ✅ 已实现`VoableService<CompanyCustomer, CompanyCustomerVo>`接口
- ✅ 已实现`updateByVo(CompanyCustomer customer, CompanyCustomerVo vo)`方法
- ✅ 方法实现了将CompanyCustomerVo的属性映射到CompanyCustomer实体
4. **ProjectService**
- ✅ 已实现`VoableService<Project, ProjectVo>`接口
- ✅ 已实现`updateByVo(Project project, ProjectVo vo)`方法
- ✅ 方法实现了将ProjectVo的多个属性映射到Project实体
5. **VendorService**
- ✅ 已实现`VoableService<Vendor, VendorVo>`接口
- ✅ 已实现`updateByVo(Vendor vendor, VendorVo vo)`方法
- ✅ 方法实现了将VendorVo的属性type、protocolProvider、developDate等映射到Vendor实体并处理了catalog和contact的关联查询
6. **BankService**
- ✅ 已实现`VoableService<Bank, BankVo>`接口
- ✅ 已实现`updateByVo(Bank bank, BankVo vo)`方法
- ✅ 方法实现了将BankVo的code和name属性映射到Bank实体
7. **DepartmentService**
- ✅ 已实现`VoableService<Department, DepartmentVo>`接口
- ✅ 已实现`updateByVo(Department department, DepartmentVo vo)`方法
- ✅ 方法实现了将DepartmentVo的code、name、active属性映射到Department实体
8. **EmployeeService**
- ✅ 已实现`VoableService<Employee, EmployeeVo>`接口
- ✅ 已实现`updateByVo(Employee employee, EmployeeVo vo)`方法
- ✅ 方法实现了将EmployeeVo的多个属性account、name、alias、email等映射到Employee实体
9. **FunctionService**
- ✅ 已实现`VoableService<Function, FunctionVo>`接口
- ✅ 已实现`updateByVo(Function function, FunctionVo vo)`方法
- ✅ 方法实现了将FunctionVo的name、key、active、controller、icon、description等属性映射到Function实体
10. **ProjectCostItemService**
- ✅ 已实现`VoableService<ProjectCostItem, ProjectCostItemVo>`接口
- ✅ 已实现`updateByVo(ProjectCostItem costItem, ProjectCostItemVo vo)`方法
11. **EmployeeRoleService**
- ✅ 已实现`VoableService<EmployeeRole, EmployeeRoleVo>`接口
- ✅ 已实现`updateByVo(EmployeeRole role, EmployeeRoleVo vo)`方法
- ✅ 方法实现了将EmployeeRoleVo的code、name、systemAdministrator等属性映射到EmployeeRole实体
12. **ProjectTypeService**
- ✅ 已实现`VoableService<ProjectType, ProjectTypeVo>`接口
- ✅ 已实现`updateByVo(ProjectType projectType, ProjectTypeVo vo)`方法
- ✅ 方法实现了将ProjectTypeVo的name、code、description属性映射到ProjectType实体
12. **PermissionService**
- ✅ 已实现`VoableService<Permission, PermissionVo>`接口
- ✅ 已实现`updateByVo(Permission permission, PermissionVo vo)`方法
- ✅ 已移除不存在的ServiceException导入
- ✅ 已调整SpringApp导入路径至com.ecep.contract.util包下
13. **ProductTypeService**
- ✅ 已实现`VoableService<ProductType, ProductTypeVo>`接口
- ✅ 已实现`updateByVo(ProductType productType, ProductTypeVo vo)`方法
- ✅ 已移除不存在的ServiceException导入
14. **ProjectFundPlanService**
- ✅ 已实现`VoableService<ProjectFundPlan, ProjectFundPlanVo>`接口
- ✅ 已实现`updateByVo(ProjectFundPlan projectFundPlan, ProjectFundPlanVo vo)`方法
- ✅ 已移除不存在的ServiceException导入
- ✅ 已调整SpringApp导入路径至com.ecep.contract.util包下
15. **ProjectIndustryService**
- ✅ 已实现`VoableService<ProjectIndustry, ProjectIndustryVo>`接口
- ✅ 已实现`updateByVo(ProjectIndustry projectIndustry, ProjectIndustryVo vo)`方法
- ✅ 已移除不存在的ServiceException导入
16. **ProjectSaleTypeService**
- ✅ 已实现`VoableService<ProjectSaleType, ProjectSaleTypeVo>`接口
- ✅ 已实现`updateByVo(ProjectSaleType projectSaleType, ProjectSaleTypeVo vo)`方法
- ✅ 已移除不存在的ServiceException导入
17. **ProductUsageService**
- ✅ 已实现`VoableService<ProductUsage, ProductUsageVo>`接口
- ✅ 已实现`updateByVo(ProductUsage productUsage, ProductUsageVo vo)`方法
- ✅ 方法实现了将ProductUsageVo的name、code、description属性映射到ProductUsage实体
18. **CustomerSatisfactionSurveyService**
- ✅ 已实现`VoableService<CustomerSatisfactionSurvey, CustomerSatisfactionSurveyVo>`接口
- ✅ 已实现`updateByVo(CustomerSatisfactionSurvey survey, CustomerSatisfactionSurveyVo vo)`方法
- ✅ 方法实现了将CustomerSatisfactionSurveyVo的code、date、totalScore、data、applyTime、description属性映射到CustomerSatisfactionSurvey实体并处理了project和applicant的关联查询
19. **InventoryService**
- ✅ 已实现`VoableService<Inventory, InventoryVo>`接口
- ✅ 已实现`updateByVo(Inventory inventory, InventoryVo vo)`方法
- ✅ 方法实现了将InventoryVo的name、code、specification、unit、description等基本属性以及重量、体积、价格等复杂属性映射到Inventory实体
20. **InventoryHistoryPriceService**
- ✅ 已实现`VoableService<InventoryHistoryPrice, InventoryHistoryPriceVo>`接口
- ✅ 已实现`updateByVo(InventoryHistoryPrice entity, InventoryHistoryPriceVo vo)`方法
- ✅ 方法实现了将InventoryHistoryPriceVo的inventoryId、year属性以及各种价格属性latestPurchasePrice、latestSalePrice等映射到InventoryHistoryPrice实体
21. **CompanyBlackReasonService**
- ✅ 已实现`VoableService<CompanyBlackReason, CompanyBlackReasonVo>`接口
- ✅ 已实现`updateByVo(CompanyBlackReason entity, CompanyBlackReasonVo vo)`方法
- ✅ 方法实现了将CompanyBlackReasonVo的companyId、type、applyName、applyDate、updateTime、createTime、includeDate、blackReason、description和key属性映射到CompanyBlackReason实体
22. **CompanyCustomerEntityService**
- ✅ 已实现`VoableService<CompanyCustomerEntity, CompanyCustomerEntityVo>`接口
- ✅ 已实现`updateByVo(CompanyCustomerEntity entity, CompanyCustomerEntityVo vo)`方法
- ✅ 方法实现了将CompanyCustomerEntityVo的name、abbName、code、customerId、customerCatalogId、creatorId、modifierId、modifyDate、developDate、updatedDate和fetchedTime属性映射到CompanyCustomerEntity实体
23. **CompanyFileTypeService**
- ✅ 已实现`VoableService<CompanyFileType, CompanyFileTypeVo>`接口
- ✅ 已实现`updateByVo(CompanyFileType entity, CompanyFileTypeVo vo)`方法
- ✅ 方法实现了将CompanyFileTypeVo的name、code、description、enable属性映射到CompanyFileType实体
24. **CompanyOldNameService**
- ✅ 已实现`VoableService<CompanyOldName, CompanyOldNameVo>`接口
- ✅ 已实现`updateByVo(CompanyOldName entity, CompanyOldNameVo vo)`方法
- ✅ 方法实现了将CompanyOldNameVo的companyId、name、beginDate、endDate、ambiguity、path、memo属性映射到CompanyOldName实体
- ✅ 方法包含了版本号校验逻辑
25. **PurchaseBillVoucherItemService**
- ✅ 已实现`VoableService<PurchaseBillVoucherItem, PurchaseBillVoucherItemVo>`接口
- ✅ 已实现`updateByVo(PurchaseBillVoucherItem entity, PurchaseBillVoucherItemVo vo)`方法
- ✅ 方法实现了将PurchaseBillVoucherItemVo的id、refId、quantity、price、description属性映射到PurchaseBillVoucherItem实体
## 需要进行的实现修改
以下1个Service需要实现`VoableService<M, Vo>`接口:
1. **ContractItemService** - 需要实现`VoableService<ContractItem, ContractItemVo>`接口,并添加`updateByVo(ContractItem item, ContractItemVo vo)`方法
- 方法应将ContractItemVo的属性映射到ContractItem实体中
- 对于关联实体属性应使用SpringApp.getBean()方法获取相关Service并调用findById()方法进行转换
## 关于 `updateByVo`
- Service 如果缺少`updateByVo`方法,请添加该方法 void updateByVo(M model, Vo vo) 并确保该方法将VO对象中的数据映射到实体对象中。
- 如果实体类有 @Version 注解的字段,如 version 字段,在 updateByVo 方法中,判断版本号是否一致,不一致则打印警告日志。
- 如果Vo的属性转换时可以使用 SpringApp.getBean( Service.class ).findById(id) 方法来转换为对象
## 结论
通过对server模块下所有实现了[`IEntityService`](/server/src/main/java/com/ecep/contract/IEntityService.java)接口的73个Service的分析我们发现
> 本报告仅详细分析了其中26个主要的Service实现情况其余47个Service的具体实现细节未在报告中展开。
1. **已实现VoableService接口的Service**
- 25个Service已成功实现`VoableService<M, Vo>`接口基于本报告详细分析的26个主要Service
- 这些Service包括ContractService、CompanyService、CompanyCustomerService、ProjectService、VendorService、BankService、DepartmentService、EmployeeService、FunctionService、ProjectCostItemService、EmployeeRoleService、PermissionService、ProductTypeService、ProjectFundPlanService、ProjectIndustryService、ProjectSaleTypeService、ProjectTypeService、ProductUsageService、CustomerSatisfactionSurveyService、InventoryService、InventoryHistoryPriceService、CompanyBlackReasonService、CompanyCustomerEntityService、CompanyFileTypeService、CompanyOldNameService和PurchaseBillVoucherItemService
- 所有Service已经正确实现了`updateByVo`方法能够将VO对象的数据映射到实体对象中
2. **未实现VoableService接口的Service**
- 在本报告详细分析的26个主要Service中有1个ServiceContractItemService未实现该接口
根据[`create_vo.md`](/docs/task/create_vo.md)文档中的要求所有Server模块的Service都需要继承`VoableService<M, Vo>`接口。在本报告详细分析的26个主要Service中目前还有1个Service未实现该接口需要尽快完成实现以满足系统架构要求。其余47个Service也需要按照同样的规范完成VoableService接口的实现。
这些修改将确保:
1. 所有Service都符合系统架构要求支持Vo对象到实体对象的转换
2. 代码结构更加一致,提高了系统的可维护性
3. 为前端UI提供更好的数据绑定和更新支持
4. 使系统整体设计更加统一,便于后续扩展和维护
已完成的实现修改已经通过Maven编译验证确保了代码的正确性和稳定性。在实现过程中还修复了多个编译错误包括移除不存在的ServiceException导入、调整SpringApp导入路径并修复了ProjectFundPlan.java中调用不存在的setProjectName方法的问题。

View File

@@ -10,7 +10,7 @@
</parent> </parent>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>Contract-Manager</artifactId> <artifactId>Contract-Manager</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<module>server</module> <module>server</module>

View File

@@ -6,12 +6,12 @@
<parent> <parent>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>Contract-Manager</artifactId> <artifactId>Contract-Manager</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
</parent> </parent>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>server</artifactId> <artifactId>server</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
<properties> <properties>
<maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.source>${java.version}</maven.compiler.source>
@@ -22,7 +22,7 @@
<dependency> <dependency>
<groupId>com.ecep.contract</groupId> <groupId>com.ecep.contract</groupId>
<artifactId>common</artifactId> <artifactId>common</artifactId>
<version>0.0.84-SNAPSHOT</version> <version>0.0.86-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@@ -5,6 +5,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import com.ecep.contract.ds.customer.service.CustomerCatalogService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
@@ -73,8 +74,7 @@ public class CustomerClassSyncTask extends Tasker<Object> {
String code = (String) map.get("cCCCode"); String code = (String) map.get("cCCCode");
String name = (String) map.get("cCCName"); String name = (String) map.get("cCCName");
CompanyCustomerService customerService = getCompanyCustomerService(); CustomerCatalog customerCatalog = getCachedBean(CustomerCatalogService.class).findByCode(code);
CustomerCatalog customerCatalog = customerService.findCatalogByCode(code);
if (customerCatalog == null) { if (customerCatalog == null) {
customerCatalog = new CustomerCatalog(); customerCatalog = new CustomerCatalog();
holder.info("新建客户分类:" + code); holder.info("新建客户分类:" + code);
@@ -93,7 +93,7 @@ public class CustomerClassSyncTask extends Tasker<Object> {
} }
if (modified) { if (modified) {
customerService.save(customerCatalog); getCachedBean(CustomerCatalogService.class).save(customerCatalog);
} }
} }
} }

View File

@@ -1,61 +1,36 @@
package com.ecep.contract.cloud.u8.ctx; package com.ecep.contract.cloud.u8.ctx;
import java.io.File;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.ecep.contract.ds.contract.service.*;
import com.ecep.contract.util.FileUtils;
import org.hibernate.Hibernate;
import org.springframework.util.StringUtils;
import com.ecep.contract.ContractFileType; import com.ecep.contract.ContractFileType;
import com.ecep.contract.ContractPayWay; import com.ecep.contract.ContractPayWay;
import com.ecep.contract.MessageHolder; import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils; import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.constant.CloudServiceConstant; import com.ecep.contract.constant.CloudServiceConstant;
import com.ecep.contract.ds.company.CompanyFileUtils; import com.ecep.contract.ds.company.CompanyFileUtils;
import com.ecep.contract.ds.contract.service.*;
import com.ecep.contract.ds.customer.service.CompanyCustomerEntityService; import com.ecep.contract.ds.customer.service.CompanyCustomerEntityService;
import com.ecep.contract.ds.customer.service.CompanyCustomerService; import com.ecep.contract.ds.customer.service.CompanyCustomerService;
import com.ecep.contract.ds.project.ProjectCtx; import com.ecep.contract.ds.project.ProjectCtx;
import com.ecep.contract.ds.project.service.ProjectSaleTypeService; import com.ecep.contract.ds.project.service.ProjectSaleTypeService;
import com.ecep.contract.ds.vendor.service.VendorEntityService; import com.ecep.contract.ds.vendor.service.VendorEntityService;
import com.ecep.contract.ds.vendor.service.VendorService; import com.ecep.contract.ds.vendor.service.VendorService;
import com.ecep.contract.model.Company; import com.ecep.contract.model.*;
import com.ecep.contract.model.CompanyCustomer; import com.ecep.contract.util.FileUtils;
import com.ecep.contract.model.CompanyCustomerEntity;
import com.ecep.contract.model.Vendor;
import com.ecep.contract.model.VendorEntity;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractCatalog;
import com.ecep.contract.model.ContractFile;
import com.ecep.contract.model.ContractFileTypeLocal;
import com.ecep.contract.model.ContractGroup;
import com.ecep.contract.model.ContractItem;
import com.ecep.contract.model.ContractKind;
import com.ecep.contract.model.ContractPayPlan;
import com.ecep.contract.model.ContractType;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.util.NumberUtils; import com.ecep.contract.util.NumberUtils;
import com.ecep.contract.util.TaxRateUtils; import com.ecep.contract.util.TaxRateUtils;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.hibernate.Hibernate;
import org.springframework.util.StringUtils;
import java.io.File;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* 合同上下文 * 合同上下文
@@ -985,7 +960,7 @@ public class ContractCtx extends AbstractYongYouU8Ctx {
// 从关联项目上未取得合同目录,尝试根据合同编码来确定合同目录 // 从关联项目上未取得合同目录,尝试根据合同编码来确定合同目录
if (contractPath == null) { if (contractPath == null) {
ContractCatalog catalog = getContractService().findContractCatalogByContract(contract); ContractCatalog catalog = getContractService().findContractCatalogByContract(contract.getCode());
if (catalog != null) { if (catalog != null) {
contractPath = getContractService().getContractCatalogPath(catalog, contract); contractPath = getContractService().getContractCatalogPath(catalog, contract);
} }
@@ -1198,10 +1173,15 @@ public class ContractCtx extends AbstractYongYouU8Ctx {
List<ContractFileTypeLocal> matched = getCachedBean(ContractFileTypeService.class) List<ContractFileTypeLocal> matched = getCachedBean(ContractFileTypeService.class)
.findAll(getLocale()).values().stream() .findAll(getLocale()).values().stream()
.filter(local -> { .filter(local -> {
ContractFileType type = local.getType();
if (type == null) {
holder.warn("#" + local.getId() + " 的 type 未设置");
return false;
}
if (payWay == ContractPayWay.PAY) { if (payWay == ContractPayWay.PAY) {
return local.getType().isSupportVendor(); return type.isSupportVendor();
} else if (payWay == ContractPayWay.RECEIVE) { } else if (payWay == ContractPayWay.RECEIVE) {
return local.getType().isSupportCustomer(); return type.isSupportCustomer();
} }
return false; return false;
}).filter(local -> { }).filter(local -> {

View File

@@ -9,6 +9,7 @@ import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.ecep.contract.ds.customer.service.CustomerCatalogService;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -168,7 +169,7 @@ public class CustomerCtx extends AbstractYongYouU8Ctx {
private boolean updateCustomerCatalog(Supplier<CustomerCatalog> getter, Consumer<CustomerCatalog> setter, String catalogCode, MessageHolder holder, String topic) { private boolean updateCustomerCatalog(Supplier<CustomerCatalog> getter, Consumer<CustomerCatalog> setter, String catalogCode, MessageHolder holder, String topic) {
CustomerCatalog catalog = null; CustomerCatalog catalog = null;
if (StringUtils.hasText(catalogCode)) { if (StringUtils.hasText(catalogCode)) {
catalog = getCompanyCustomerService().findCatalogByCode(catalogCode); catalog = getCachedBean(CustomerCatalogService.class).findByCode(catalogCode);
} }
if (catalog == null) { if (catalog == null) {
setter.accept(null); setter.accept(null);
@@ -177,7 +178,7 @@ public class CustomerCtx extends AbstractYongYouU8Ctx {
} else { } else {
if (!Objects.equals(getter.get(), catalog)) { if (!Objects.equals(getter.get(), catalog)) {
if (!Hibernate.isInitialized(catalog)) { if (!Hibernate.isInitialized(catalog)) {
catalog = getCompanyCustomerService().findCatalogByCode(catalogCode); catalog = getCachedBean(CustomerCatalogService.class).findByCode(catalogCode);
} }
setter.accept(catalog); setter.accept(catalog);
holder.info(topic + "修改为: " + catalog.getName()); holder.info(topic + "修改为: " + catalog.getName());

View File

@@ -15,15 +15,19 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.company.repository.CompanyBlackReasonRepository; import com.ecep.contract.ds.company.repository.CompanyBlackReasonRepository;
import com.ecep.contract.model.Company; import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyBlackReason; import com.ecep.contract.model.CompanyBlackReason;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.CompanyBlackReasonVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
public class CompanyBlackReasonService implements IEntityService<CompanyBlackReason>, QueryService<CompanyBlackReason> { public class CompanyBlackReasonService implements IEntityService<CompanyBlackReason>, QueryService<CompanyBlackReason>,
VoableService<CompanyBlackReason, CompanyBlackReasonVo> {
private static final Logger logger = LoggerFactory.getLogger(CompanyContactService.class); private static final Logger logger = LoggerFactory.getLogger(CompanyContactService.class);
@Autowired @Autowired
@@ -77,4 +81,21 @@ public class CompanyBlackReasonService implements IEntityService<CompanyBlackRea
spec = SpecificationUtils.andParam(spec, paramsNode, "company"); spec = SpecificationUtils.andParam(spec, paramsNode, "company");
return findAll(spec, pageable); return findAll(spec, pageable);
} }
@Override
public void updateByVo(CompanyBlackReason entity, CompanyBlackReasonVo vo) {
entity.setCompany(SpringApp.getBean(CompanyService.class).findById(vo.getCompanyId()));
// 更新基础字段
entity.setType(vo.getType());
entity.setApplyName(vo.getApplyName());
entity.setApplyDate(vo.getApplyDate());
entity.setUpdateTime(vo.getUpdateTime());
entity.setCreateTime(vo.getCreateTime());
entity.setIncludeDate(vo.getIncludeDate());
entity.setBlackReason(vo.getBlackReason());
entity.setDescription(vo.getDescription());
entity.setKey(vo.getKey());
}
} }

View File

@@ -1,8 +1,8 @@
package com.ecep.contract.ds.company.service; package com.ecep.contract.ds.company.service;
import com.ecep.contract.CompanyFileType; import com.ecep.contract.CompanyFileType;
import com.ecep.contract.VendorType;
import com.ecep.contract.constant.ServiceConstant; import com.ecep.contract.constant.ServiceConstant;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
@@ -18,6 +18,7 @@ import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.repository.CompanyFileTypeLocalRepository; import com.ecep.contract.ds.company.repository.CompanyFileTypeLocalRepository;
import com.ecep.contract.model.CompanyFileTypeLocal; import com.ecep.contract.model.CompanyFileTypeLocal;
import com.ecep.contract.vo.CompanyFileTypeLocalVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@@ -30,7 +31,7 @@ import java.util.Map;
@Service @Service
@CacheConfig(cacheNames = "company-file-type") @CacheConfig(cacheNames = "company-file-type")
public class CompanyFileTypeService public class CompanyFileTypeService
implements IEntityService<CompanyFileTypeLocal>, QueryService<CompanyFileTypeLocal> { implements IEntityService<CompanyFileTypeLocal>, QueryService<CompanyFileTypeLocal>, VoableService<CompanyFileTypeLocal, CompanyFileTypeLocalVo> {
@Resource @Resource
private CompanyFileTypeLocalRepository repository; private CompanyFileTypeLocalRepository repository;
@@ -97,4 +98,14 @@ public class CompanyFileTypeService
public CompanyFileTypeLocal save(CompanyFileTypeLocal entity) { public CompanyFileTypeLocal save(CompanyFileTypeLocal entity) {
return repository.save(entity); return repository.save(entity);
} }
@Override
public void updateByVo(CompanyFileTypeLocal model, CompanyFileTypeLocalVo vo) {
// 映射基本属性
model.setId(vo.getId());
model.setType(vo.getType());
model.setLang(vo.getLang());
model.setValue(vo.getValue());
// 实体中没有active字段不需要映射
}
} }

View File

@@ -4,7 +4,6 @@ import java.io.File;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
import com.ecep.contract.util.FileUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -21,13 +20,16 @@ import com.ecep.contract.QueryService;
import com.ecep.contract.ds.company.repository.CompanyOldNameRepository; import com.ecep.contract.ds.company.repository.CompanyOldNameRepository;
import com.ecep.contract.model.Company; import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyOldName; import com.ecep.contract.model.CompanyOldName;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.MyStringUtils; import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.CompanyOldNameVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
public class CompanyOldNameService implements IEntityService<CompanyOldName>, QueryService<CompanyOldName> { public class CompanyOldNameService implements IEntityService<CompanyOldName>, QueryService<CompanyOldName>, VoableService<CompanyOldName, CompanyOldNameVo> {
private static final Logger logger = LoggerFactory.getLogger(CompanyOldNameService.class); private static final Logger logger = LoggerFactory.getLogger(CompanyOldNameService.class);
@Lazy @Lazy
@Autowired @Autowired
@@ -227,4 +229,20 @@ public class CompanyOldNameService implements IEntityService<CompanyOldName>, Qu
companyOldName.setAmbiguity(ambiguity); companyOldName.setAmbiguity(ambiguity);
return companyOldName; return companyOldName;
} }
@Override
public void updateByVo(CompanyOldName model, CompanyOldNameVo vo) {
model.setCompanyId(vo.getCompanyId());
model.setName(vo.getName());
model.setBeginDate(vo.getBeginDate());
model.setEndDate(vo.getEndDate());
model.setAmbiguity(vo.isAmbiguity());
model.setPath(vo.getPath());
model.setMemo(vo.getMemo());
if (model.getVersion() != vo.getVersion()) {
logger.warn("CompanyOldName version not equal, id: {}, version: {}, vo version: {}",
model.getId(), model.getVersion(), vo.getVersion());
}
}
} }

View File

@@ -20,6 +20,8 @@ import com.ecep.contract.model.Vendor;
import com.ecep.contract.util.FileUtils; import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.MyStringUtils; import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.CompanyVo;
import com.ecep.contract.service.VoableService;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
@@ -49,7 +51,8 @@ import java.util.stream.Collectors;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "company") @CacheConfig(cacheNames = "company")
public class CompanyService extends EntityService<Company, Integer> implements IEntityService<Company>, QueryService<Company> { public class CompanyService extends EntityService<Company, Integer>
implements IEntityService<Company>, QueryService<Company>, VoableService<Company, CompanyVo> {
private static final Logger logger = LoggerFactory.getLogger(CompanyService.class); private static final Logger logger = LoggerFactory.getLogger(CompanyService.class);
@Lazy @Lazy
@@ -116,7 +119,6 @@ public class CompanyService extends EntityService<Company, Integer> implements I
return companyRepository.findAllByName(name); return companyRepository.findAllByName(name);
} }
@Override @Override
protected Specification<Company> buildParameterSpecification(JsonNode paramsNode) { protected Specification<Company> buildParameterSpecification(JsonNode paramsNode) {
return null; return null;
@@ -345,7 +347,6 @@ public class CompanyService extends EntityService<Company, Integer> implements I
return companyRepository.save(company); return companyRepository.save(company);
} }
public File getBasePath() { public File getBasePath() {
return new File(confService.getString(CompanyConstant.COMPANY_BASE_PATH)); return new File(confService.getString(CompanyConstant.COMPANY_BASE_PATH));
} }
@@ -440,7 +441,6 @@ public class CompanyService extends EntityService<Company, Integer> implements I
} }
} }
@Override @Override
public Specification<Company> getSpecification(String searchText) { public Specification<Company> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) { if (!StringUtils.hasText(searchText)) {
@@ -495,7 +495,7 @@ public class CompanyService extends EntityService<Company, Integer> implements I
} }
public Predicate buildSearchPredicate(String searchText, Path<Company> root, CriteriaQuery<?> query, public Predicate buildSearchPredicate(String searchText, Path<Company> root, CriteriaQuery<?> query,
CriteriaBuilder builder) { CriteriaBuilder builder) {
return builder.or( return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"), builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("shortName"), "%" + searchText + "%"), builder.like(root.get("shortName"), "%" + searchText + "%"),
@@ -518,4 +518,33 @@ public class CompanyService extends EntityService<Company, Integer> implements I
}); });
return list; return list;
} }
@Override
public void updateByVo(Company company, CompanyVo vo) {
company.setName(vo.getName());
company.setUniscid(vo.getUniscid());
company.setShortName(vo.getShortName());
company.setPathExist(vo.isPathExist());
company.setPath(vo.getPath());
company.setCreated(vo.getCreated());
company.setEntStatus(vo.getEntStatus());
company.setEntType(vo.getEntType());
company.setDistrict(vo.getDistrict());
company.setIndustry(vo.getIndustry());
company.setTelephone(vo.getTelephone());
company.setRegAddr(vo.getRegAddr());
company.setAddress(vo.getAddress());
company.setSetupDate(vo.getSetupDate());
company.setOperationPeriodBegin(vo.getOperationPeriodBegin());
company.setOperationPeriodEnd(vo.getOperationPeriodEnd());
company.setRegisteredCapital(vo.getRegisteredCapital());
company.setRegisteredCapitalCurrency(vo.getRegisteredCapitalCurrency());
company.setLegalRepresentative(vo.getLegalRepresentative());
company.setMemo(vo.getMemo());
if (company.getVersion() != vo.getVersion()) {
logger.warn("company version not equal, company id: {}, version: {}, vo version: {}", company.getId(),
company.getVersion(), vo.getVersion());
}
}
} }

View File

@@ -9,7 +9,6 @@ import java.util.Objects;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.ecep.contract.EntityService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -24,19 +23,26 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.ContractPayWay; import com.ecep.contract.ContractPayWay;
import com.ecep.contract.EntityService;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.ContractConstant; import com.ecep.contract.constant.ContractConstant;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.contract.repository.ContractRepository; import com.ecep.contract.ds.contract.repository.ContractRepository;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.ds.other.service.SysConfService; import com.ecep.contract.ds.other.service.SysConfService;
import com.ecep.contract.ds.project.service.ProjectService;
import com.ecep.contract.model.Company; import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer; import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.Vendor;
import com.ecep.contract.model.Contract; import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractCatalog; import com.ecep.contract.model.ContractCatalog;
import com.ecep.contract.model.Project; import com.ecep.contract.model.Project;
import com.ecep.contract.model.Vendor;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.MyStringUtils; import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.ContractVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Predicate;
@@ -48,7 +54,8 @@ import jakarta.persistence.criteria.Predicate;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "contract") @CacheConfig(cacheNames = "contract")
public class ContractService extends EntityService<Contract, Integer> implements IEntityService<Contract>, QueryService<Contract> { public class ContractService extends EntityService<Contract, Integer>
implements IEntityService<Contract>, QueryService<Contract>, VoableService<Contract, ContractVo> {
private static final Logger logger = LoggerFactory.getLogger(ContractService.class); private static final Logger logger = LoggerFactory.getLogger(ContractService.class);
@Lazy @Lazy
@Autowired @Autowired
@@ -122,7 +129,6 @@ public class ContractService extends EntityService<Contract, Integer> implements
return new File(confService.getString(ContractConstant.KEY_BASE_PATH)); return new File(confService.getString(ContractConstant.KEY_BASE_PATH));
} }
/** /**
* 返回合同的分类目录 * 返回合同的分类目录
*/ */
@@ -166,19 +172,21 @@ public class ContractService extends EntityService<Contract, Integer> implements
/** /**
* 查找合同的分类 * 查找合同的分类
*/ */
public ContractCatalog findContractCatalogByContract(Contract contract) { public ContractCatalog findContractCatalogByContract(String contractCode) {
String code = contract.getCode(); if (!StringUtils.hasText(contractCode)) {
return null;
}
String catalogCode = null; String catalogCode = null;
// 第二个字符是数字时,快速处理 // 第二个字符是数字时,快速处理
if (Character.isDigit(code.charAt(1))) { if (Character.isDigit(contractCode.charAt(1))) {
// 只有一个字母表示合同类型 // 只有一个字母表示合同类型
catalogCode = code.substring(0, 1); catalogCode = contractCode.substring(0, 1);
} else { } else {
// 使用正则找出 合同类型 // 使用正则找出 合同类型
String regex = "^([A-Z]{1,4})(\\d{4,5})"; String regex = "^([A-Z]{1,4})(\\d{4,5})";
Pattern pattern = Pattern.compile(regex); Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(code); Matcher matcher = pattern.matcher(contractCode);
if (matcher.find()) { if (matcher.find()) {
catalogCode = matcher.group(1); catalogCode = matcher.group(1);
System.out.println("字母部分: " + matcher.group(1)); System.out.println("字母部分: " + matcher.group(1));
@@ -186,7 +194,7 @@ public class ContractService extends EntityService<Contract, Integer> implements
} }
if (catalogCode == null) { if (catalogCode == null) {
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
logger.info("contract {} can't find catalog code", code); logger.info("contract {} can't find catalog code", contractCode);
} }
return null; return null;
} }
@@ -359,8 +367,30 @@ public class ContractService extends EntityService<Contract, Integer> implements
return contractRepository.findAllByParentCode(contract.getCode()); return contractRepository.findAllByParentCode(contract.getCode());
} }
public List<Contract> findByCodeStartsWith(ContractPayWay payWay, String parentCode) { public List<Contract> findByCodeStartsWith(ContractPayWay payWay, String parentCode) {
return contractRepository.findByPayWayAndCodeStartsWith(payWay, parentCode); return contractRepository.findByPayWayAndCodeStartsWith(payWay, parentCode);
} }
@Override
public void updateByVo(Contract contract, ContractVo vo) {
contract.setCode(vo.getCode());
contract.setName(vo.getName());
contract.setCompany(SpringApp.getBean(CompanyService.class).findById(vo.getCompanyId()));
contract.setGroup(SpringApp.getBean(ContractGroupService.class).findById(vo.getGroupId()));
contract.setType(SpringApp.getBean(ContractTypeService.class).findById(vo.getTypeId()));
contract.setKind(SpringApp.getBean(ContractKindService.class).findById(vo.getKindId()));
contract.setProject(SpringApp.getBean(ProjectService.class).findById(vo.getProject()));
contract.setParentCode(vo.getParentCode());
contract.setOrderDate(vo.getOrderDate());
contract.setStartDate(vo.getStartDate());
contract.setEndDate(vo.getEndDate());
EmployeeService employeeService = SpringApp.getBean(EmployeeService.class);
contract.setEmployee(employeeService.findById(vo.getEmployeeId()));
contract.setHandler(employeeService.findById(vo.getHandlerId()));
contract.setSetupPerson(employeeService.findById(vo.getSetupPersonId()));
contract.setSetupDate(vo.getSetupDate());
contract.setInurePerson(employeeService.findById(vo.getInurePersonId()));
contract.setInureDate(vo.getInureDate());
}
} }

View File

@@ -18,13 +18,16 @@ import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.ds.contract.repository.PurchaseBillVoucherItemRepository; import com.ecep.contract.ds.contract.repository.PurchaseBillVoucherItemRepository;
import com.ecep.contract.model.PurchaseBillVoucherItem; import com.ecep.contract.model.PurchaseBillVoucherItem;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.PurchaseBillVoucherItemVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "purchase-bill-voucher-item") @CacheConfig(cacheNames = "purchase-bill-voucher-item")
public class PurchaseBillVoucherItemService public class PurchaseBillVoucherItemService
implements IEntityService<PurchaseBillVoucherItem>, QueryService<PurchaseBillVoucherItem> { implements IEntityService<PurchaseBillVoucherItem>, QueryService<PurchaseBillVoucherItem>,
VoableService<PurchaseBillVoucherItem, PurchaseBillVoucherItemVo> {
@Lazy @Lazy
@Autowired @Autowired
private PurchaseBillVoucherItemRepository repository; private PurchaseBillVoucherItemRepository repository;
@@ -78,4 +81,18 @@ public class PurchaseBillVoucherItemService
public List<PurchaseBillVoucherItem> findAll(Specification<PurchaseBillVoucherItem> spec, Sort sort) { public List<PurchaseBillVoucherItem> findAll(Specification<PurchaseBillVoucherItem> spec, Sort sort) {
return repository.findAll(spec, sort); return repository.findAll(spec, sort);
} }
@Override
public void updateByVo(PurchaseBillVoucherItem model, PurchaseBillVoucherItemVo vo) {
model.setId(vo.getId());
model.setRefId(vo.getRefId());
// 关联实体ID设置
// voucher, orderItem, invoice, inventory, contract等实体需要在service层进行设置
// 这里只设置基本属性,关联实体的设置需要在调用此方法的地方处理
model.setQuantity(vo.getQuantity());
model.setPrice(vo.getPrice());
model.setDescription(vo.getDescription());
}
} }

View File

@@ -108,7 +108,7 @@ public class ContractRepairComm {
parentDir = new File(parentPath); parentDir = new File(parentPath);
} else { } else {
// 主合同 // 主合同
ContractCatalog catalog = getContractService().findContractCatalogByContract(contract); ContractCatalog catalog = getContractService().findContractCatalogByContract(contract.getCode());
if (catalog == null) { if (catalog == null) {
return null; return null;
} }

View File

@@ -2,8 +2,6 @@ package com.ecep.contract.ds.customer.service;
import java.util.List; import java.util.List;
import com.ecep.contract.QueryService;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
@@ -17,19 +15,33 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.customer.repository.CompanyCustomerEntityRepository; import com.ecep.contract.ds.customer.repository.CompanyCustomerEntityRepository;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.model.CompanyCustomer; import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerEntity; import com.ecep.contract.model.CompanyCustomerEntity;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.CompanyCustomerEntityVo;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "company-customer-entity") @CacheConfig(cacheNames = "company-customer-entity")
public class CompanyCustomerEntityService implements IEntityService<CompanyCustomerEntity>, QueryService<CompanyCustomerEntity> { public class CompanyCustomerEntityService implements IEntityService<CompanyCustomerEntity>, QueryService<CompanyCustomerEntity>, VoableService<CompanyCustomerEntity, CompanyCustomerEntityVo> {
@Lazy @Lazy
@Autowired @Autowired
private CompanyCustomerEntityRepository repository; private CompanyCustomerEntityRepository repository;
@Autowired
private CompanyCustomerService companyCustomerService;
@Autowired
private CustomerCatalogService customerCatalogService;
@Autowired
private EmployeeService employeeService;
@Cacheable(key = "#p0") @Cacheable(key = "#p0")
@Override @Override
public CompanyCustomerEntity findById(Integer id) { public CompanyCustomerEntity findById(Integer id) {
@@ -109,4 +121,32 @@ public class CompanyCustomerEntityService implements IEntityService<CompanyCusto
repository.saveAll(entities); repository.saveAll(entities);
} }
@Override
public void updateByVo(CompanyCustomerEntity entity, CompanyCustomerEntityVo vo) {
if (vo.getCustomerId() != null) {
entity.setCustomer(companyCustomerService.findById(vo.getCustomerId()));
}
entity.setName(vo.getName());
entity.setAbbName(vo.getAbbName());
entity.setCode(vo.getCode());
if (vo.getCustomerCatalogId() != null) {
entity.setCatalog(customerCatalogService.findById(vo.getCustomerCatalogId()));
}
if (vo.getCreatorId() != null) {
entity.setCreator(employeeService.findById(vo.getCreatorId()));
}
if (vo.getModifierId() != null) {
entity.setModifier(employeeService.findById(vo.getModifierId()));
}
entity.setModifyDate(vo.getModifyDate());
entity.setDevelopDate(vo.getDevelopDate());
entity.setUpdatedDate(vo.getUpdatedDate());
entity.setFetchedTime(vo.getFetchedTime());
}
} }

View File

@@ -11,12 +11,6 @@ import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.ecep.contract.QueryService;
import com.ecep.contract.constant.CompanyCustomerConstant;
import com.ecep.contract.model.*;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.util.CompanyUtils;
import com.ecep.contract.util.FileUtils;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -34,13 +28,27 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.CustomerFileType; import com.ecep.contract.CustomerFileType;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.CompanyCustomerConstant;
import com.ecep.contract.ds.company.service.CompanyBasicService; import com.ecep.contract.ds.company.service.CompanyBasicService;
import com.ecep.contract.ds.customer.repository.CompanyCustomerEvaluationFormFileRepository; import com.ecep.contract.ds.company.service.CompanyContactService;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.customer.repository.CompanyCustomerRepository; import com.ecep.contract.ds.customer.repository.CompanyCustomerRepository;
import com.ecep.contract.ds.customer.repository.CustomerCatalogRepository;
import com.ecep.contract.ds.other.service.SysConfService; import com.ecep.contract.ds.other.service.SysConfService;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyBasicFile;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerEntity;
import com.ecep.contract.model.CompanyCustomerEvaluationFormFile;
import com.ecep.contract.model.CompanyCustomerFile;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.CompanyUtils;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.MyStringUtils; import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.CompanyCustomerVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -51,7 +59,8 @@ import jakarta.persistence.criteria.Path;
@Service @Service
@CacheConfig(cacheNames = "company-customer") @CacheConfig(cacheNames = "company-customer")
public class CompanyCustomerService extends CompanyBasicService public class CompanyCustomerService extends CompanyBasicService
implements IEntityService<CompanyCustomer>, QueryService<CompanyCustomer> { implements IEntityService<CompanyCustomer>, QueryService<CompanyCustomer>,
VoableService<CompanyCustomer, CompanyCustomerVo> {
private static final Logger logger = LoggerFactory.getLogger(CompanyCustomerService.class); private static final Logger logger = LoggerFactory.getLogger(CompanyCustomerService.class);
@Lazy @Lazy
@@ -62,15 +71,9 @@ public class CompanyCustomerService extends CompanyBasicService
private CompanyCustomerFileService companyCustomerFileService; private CompanyCustomerFileService companyCustomerFileService;
@Lazy @Lazy
@Autowired @Autowired
private CompanyCustomerEvaluationFormFileRepository companyCustomerEvaluationFormFileRepository;
@Lazy
@Autowired
private SysConfService confService; private SysConfService confService;
@Lazy @Lazy
@Autowired @Autowired
private CustomerCatalogRepository customerCatalogRepository;
@Lazy
@Autowired
private CompanyCustomerEntityService companyCustomerEntityService; private CompanyCustomerEntityService companyCustomerEntityService;
public CompanyCustomer findByCompany(Company company) { public CompanyCustomer findByCompany(Company company) {
@@ -152,7 +155,7 @@ public class CompanyCustomerService extends CompanyBasicService
* 重置 客户文件 * 重置 客户文件
* *
* @param companyCustomer 客户对象 * @param companyCustomer 客户对象
* @param holder 消息持有者 * @param holder 消息持有者
*/ */
public boolean reBuildingFiles(CompanyCustomer companyCustomer, MessageHolder holder) { public boolean reBuildingFiles(CompanyCustomer companyCustomer, MessageHolder holder) {
List<CompanyCustomerFile> dbFiles = companyCustomerFileService.findAllByCustomer(companyCustomer); List<CompanyCustomerFile> dbFiles = companyCustomerFileService.findAllByCustomer(companyCustomer);
@@ -245,8 +248,7 @@ public class CompanyCustomerService extends CompanyBasicService
objectMapper.updateValue(formFile, data); objectMapper.updateValue(formFile, data);
logger.info("load json data from {}", jsonFile.getName()); logger.info("load json data from {}", jsonFile.getName());
formFile.setCatalog(type.asText()); formFile.setCatalog(type.asText());
companyCustomerEvaluationFormFileRepository.save(formFile); SpringApp.getBean(CompanyCustomerEvaluationFormFileService.class).save(formFile);
// companyCustomerEvaluationFormFileRepository.save(formFile);
if (jsonFile.delete()) { if (jsonFile.delete()) {
logger.info("delete json file {}", jsonFile.getName()); logger.info("delete json file {}", jsonFile.getName());
} }
@@ -391,26 +393,21 @@ public class CompanyCustomerService extends CompanyBasicService
} }
} }
@Cacheable(key = "'catalog-'+#p0") @Override
public CustomerCatalog findCatalogById(Integer id) { public void updateByVo(CompanyCustomer customer, CompanyCustomerVo vo) {
return customerCatalogRepository.findById(id).orElse(null); customer.setCompany(SpringApp.getBean(CompanyService.class).findById(vo.getCompanyId()));
} customer.setCatalog(SpringApp.getBean(CustomerCatalogService.class).findById(vo.getCatalogId()));
customer.setDevelopDate(vo.getDevelopDate());
customer.setPath(vo.getPath());
customer.setContact(SpringApp.getBean(CompanyContactService.class).findById(vo.getContactId()));
public List<CustomerCatalog> findAllCatalogs() { customer.setDescription(vo.getDescription());
return customerCatalogRepository.findAll(); customer.setCreated(vo.getCreated());
}
@Cacheable(key = "'catalog-code-'+#p0") if (customer.getVersion() != vo.getVersion()) {
public CustomerCatalog findCatalogByCode(String code) { logger.warn("customer version not equal, customer id: {}, version: {}, vo version: {}", customer.getId(),
return customerCatalogRepository.findByCode(code).orElse(null); customer.getVersion(), vo.getVersion());
} }
@Caching(evict = {
@CacheEvict(key = "'catalog-'+#p0.id"),
@CacheEvict(key = "'catalog-code-'+#p0.code")
})
public CustomerCatalog save(CustomerCatalog catalog) {
return customerCatalogRepository.save(catalog);
} }
} }

View File

@@ -0,0 +1,112 @@
package com.ecep.contract.ds.customer.tasker;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.customer.service.CompanyCustomerFileService;
import com.ecep.contract.ds.customer.service.CompanyCustomerService;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerFile;
import com.ecep.contract.service.WebSocketServerTasker;
import com.ecep.contract.ui.Tasker;
import com.fasterxml.jackson.databind.JsonNode;
import org.hibernate.Hibernate;
import org.springframework.util.StringUtils;
import java.io.File;
import java.util.logging.Level;
/**
* 客户文件移动到公司目录任务器
* 用于将客户相关文件从客户目录移动到公司目录
*/
public class CustomerFileMoveTasker extends Tasker<Object> implements WebSocketServerTasker {
private CompanyCustomerFile file;
@Override
public void init(JsonNode argsNode) {
if (argsNode != null && argsNode.size() > 0) {
this.file = getCompanyCustomerFileService().findById(argsNode.get(0).asInt());
}
}
@Override
protected Object execute(MessageHolder holder) throws Exception {
try {
updateTitle("移动文件到公司目录");
holder.addMessage(Level.INFO, "开始执行文件移动任务...");
if (file == null) {
throw new IllegalArgumentException("文件信息不能为空");
}
// 获取客户信息
CompanyCustomer customer = file.getCustomer();
if (customer == null) {
throw new IllegalArgumentException("客户不存在");
}
if (!Hibernate.isInitialized(customer)) {
customer = getCompanyCustomerService().findById(customer.getId());
}
// 获取公司信息
Company company = customer.getCompany();
if (company == null) {
throw new IllegalArgumentException("公司不存在: " + customer.getCompany());
}
if (!Hibernate.isInitialized(company)) {
company = getCompanyService().findById(company.getId());
}
if (!StringUtils.hasText(company.getPath())) {
throw new IllegalArgumentException("公司目录未设置");
}
File companyPath = new File(company.getPath());
if (!companyPath.exists()) {
throw new IllegalArgumentException("公司目录设置异常,无法访问: " + company.getPath());
}
// 移动文件
boolean moveFile = moveFile(file.getFilePath(), companyPath, holder);;
moveFile(file.getEditFilePath(), companyPath, holder);
// 删除数据库记录
if (moveFile) {
getCompanyCustomerFileService().delete(file);
holder.addMessage(Level.INFO, "文件移动任务执行完成");
updateProperty("filesUpdated", true);
}
return true;
} catch (Exception e) {
holder.addMessage(Level.SEVERE, "文件移动失败: " + e.getMessage());
throw e;
}
}
private boolean moveFile(String filePath, File companyPath, MessageHolder holder) {
if (StringUtils.hasText(filePath)) {
File file = new File(filePath);
if (file.exists()) {
File dest = new File(companyPath, file.getName());
if (file.renameTo(dest)) {
holder.info(file.getAbsolutePath() + " -> " + dest.getAbsolutePath());
return true;
} else {
holder.error("无法移动文件: " + file.getAbsolutePath());
}
}
}
return false;
}
private CompanyCustomerFileService getCompanyCustomerFileService() {
return getCachedBean(CompanyCustomerFileService.class);
}
private CompanyCustomerService getCompanyCustomerService() {
return getCachedBean(CompanyCustomerService.class);
}
}

View File

@@ -18,12 +18,14 @@ import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.ds.other.repository.BankRepository; import com.ecep.contract.ds.other.repository.BankRepository;
import com.ecep.contract.model.Bank; import com.ecep.contract.model.Bank;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.BankVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "bank") @CacheConfig(cacheNames = "bank")
public class BankService implements IEntityService<Bank>, QueryService<Bank> { public class BankService implements IEntityService<Bank>, QueryService<Bank>, VoableService<Bank, BankVo> {
@Lazy @Lazy
@Autowired @Autowired
private BankRepository bankRepository; private BankRepository bankRepository;
@@ -84,4 +86,10 @@ public class BankService implements IEntityService<Bank>, QueryService<Bank> {
public void delete(Bank entity) { public void delete(Bank entity) {
bankRepository.delete(entity); bankRepository.delete(entity);
} }
@Override
public void updateByVo(Bank bank, BankVo vo) {
bank.setCode(vo.getCode());
bank.setName(vo.getName());
}
} }

View File

@@ -18,6 +18,9 @@ import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.ds.other.repository.DepartmentRepository; import com.ecep.contract.ds.other.repository.DepartmentRepository;
import com.ecep.contract.model.Department; import com.ecep.contract.model.Department;
import com.ecep.contract.model.Employee;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.DepartmentVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
/** /**
@@ -26,7 +29,7 @@ import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "department") @CacheConfig(cacheNames = "department")
public class DepartmentService implements IEntityService<Department>, QueryService<Department> { public class DepartmentService implements IEntityService<Department>, QueryService<Department>, VoableService<Department, DepartmentVo> {
@Lazy @Lazy
@Autowired @Autowired
private DepartmentRepository repository; private DepartmentRepository repository;
@@ -92,4 +95,13 @@ public class DepartmentService implements IEntityService<Department>, QueryServi
public Department save(Department entity) { public Department save(Department entity) {
return repository.save(entity); return repository.save(entity);
} }
@Override
public void updateByVo(Department department, DepartmentVo vo) {
department.setCode(vo.getCode());
department.setName(vo.getName());
department.setActive(vo.isActive());
// 处理leader字段需要将leaderId转换为Employee对象
// 这里暂时不实现因为需要依赖EmployeeService
}
} }

View File

@@ -17,10 +17,12 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.service.VoableService;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.ecep.contract.ds.other.repository.EmployeeRoleRepository; import com.ecep.contract.ds.other.repository.EmployeeRoleRepository;
import com.ecep.contract.model.EmployeeRole; import com.ecep.contract.model.EmployeeRole;
import com.ecep.contract.model.Function; import com.ecep.contract.model.Function;
import com.ecep.contract.vo.EmployeeRoleVo;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
@@ -29,7 +31,8 @@ import jakarta.transaction.Transactional;
*/ */
@Service @Service
@CacheConfig(cacheNames = "employee-role") @CacheConfig(cacheNames = "employee-role")
public class EmployeeRoleService implements IEntityService<EmployeeRole>, QueryService<EmployeeRole> { public class EmployeeRoleService implements IEntityService<EmployeeRole>, QueryService<EmployeeRole>,
VoableService<EmployeeRole, EmployeeRoleVo> {
@Lazy @Lazy
@Autowired @Autowired
private EmployeeRoleRepository roleRepository; private EmployeeRoleRepository roleRepository;
@@ -96,4 +99,13 @@ public class EmployeeRoleService implements IEntityService<EmployeeRole>, QueryS
} }
return null; return null;
} }
@Override
public void updateByVo(EmployeeRole role, EmployeeRoleVo vo) {
role.setCode(vo.getCode());
role.setName(vo.getName());
role.setSystemAdministrator(vo.isSystemAdministrator());
role.setManager(vo.isManager());
role.setActive(vo.isActive());
}
} }

View File

@@ -2,9 +2,12 @@ package com.ecep.contract.ds.other.service;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.ds.other.repository.EmployeeRepository; import com.ecep.contract.ds.other.repository.EmployeeRepository;
import com.ecep.contract.model.Employee; import com.ecep.contract.model.Employee;
import com.ecep.contract.model.EmployeeRole; import com.ecep.contract.model.EmployeeRole;
import com.ecep.contract.vo.EmployeeVo;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
@@ -31,7 +34,8 @@ import java.util.Optional;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "employee") @CacheConfig(cacheNames = "employee")
public class EmployeeService implements IEntityService<Employee>, QueryService<Employee> { public class EmployeeService
implements IEntityService<Employee>, QueryService<Employee>, VoableService<Employee, EmployeeVo> {
private static final Logger logger = LoggerFactory.getLogger(EmployeeService.class); private static final Logger logger = LoggerFactory.getLogger(EmployeeService.class);
public static final int DEFAULT_SYSTEM_EMPLOYEE_ID = 26; public static final int DEFAULT_SYSTEM_EMPLOYEE_ID = 26;
@Lazy @Lazy
@@ -165,6 +169,30 @@ public class EmployeeService implements IEntityService<Employee>, QueryService<E
return null; return null;
} }
@Override
public void updateByVo(Employee entity, EmployeeVo vo) {
// 更新基础字段
entity.setName(vo.getName());
entity.setAccount(vo.getAccount());
entity.setAlias(vo.getAlias());
entity.setCode(vo.getCode());
entity.setDepartment(SpringApp.getBean(DepartmentService.class).findById(vo.getDepartmentId()));
entity.setPhone(vo.getPhone());
entity.setEmail(vo.getEmail());
entity.setCreated(vo.getCreated());
entity.setEntryDate(vo.getEntryDate());
entity.setLeaveDate(vo.getLeaveDate());
// 区域设置
entity.setLocale(vo.getLocale());
entity.setDateTimeFormatter(vo.getDateTimeFormatter());
entity.setDateFormatter(vo.getDateFormatter());
entity.setTimeFormatter(vo.getTimeFormatter());
entity.setTimeZone(vo.getTimeZone());
entity.setNumberFormatter(vo.getNumberFormatter());
entity.setCurrencyFormatter(vo.getCurrencyFormatter());
entity.setActive(vo.isActive());
}
} }

View File

@@ -14,22 +14,20 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.service.VoableService;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.ecep.contract.ds.other.repository.FunctionRepository; import com.ecep.contract.ds.other.repository.FunctionRepository;
import com.ecep.contract.model.Function; import com.ecep.contract.model.Function;
import com.ecep.contract.vo.FunctionVo;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "function") @CacheConfig(cacheNames = "function")
public class FunctionService implements IEntityService<Function>, QueryService<Function> { public class FunctionService implements IEntityService<Function>, QueryService<Function>, VoableService<Function, FunctionVo> {
@Lazy @Lazy
@Autowired @Autowired
private FunctionRepository repository; private FunctionRepository repository;
/*
*/
@Cacheable(key = "#p0") @Cacheable(key = "#p0")
public Function findById(Integer id) { public Function findById(Integer id) {
return repository.findById(id).orElse(null); return repository.findById(id).orElse(null);
@@ -78,4 +76,15 @@ public class FunctionService implements IEntityService<Function>, QueryService<F
); );
}; };
} }
@Override
public void updateByVo(Function function, FunctionVo vo) {
function.setName(vo.getName());
function.setKey(vo.getKey());
function.setActive(vo.isActive());
function.setController(vo.getController());
function.setIcon(vo.getIcon());
function.setDescription(vo.getDescription());
// parentId和order字段在实体类中不存在暂不处理
}
} }

View File

@@ -13,10 +13,12 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.fasterxml.jackson.databind.JsonNode;
import com.ecep.contract.ds.other.repository.InventoryHistoryPriceRepository; import com.ecep.contract.ds.other.repository.InventoryHistoryPriceRepository;
import com.ecep.contract.model.Inventory; import com.ecep.contract.model.Inventory;
import com.ecep.contract.model.InventoryHistoryPrice; import com.ecep.contract.model.InventoryHistoryPrice;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.InventoryHistoryPriceVo;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Path;
@@ -24,11 +26,16 @@ import jakarta.persistence.criteria.Path;
@Service @Service
@CacheConfig(cacheNames = "inventory-history-price") @CacheConfig(cacheNames = "inventory-history-price")
public class InventoryHistoryPriceService public class InventoryHistoryPriceService
implements IEntityService<InventoryHistoryPrice>, QueryService<InventoryHistoryPrice> { implements IEntityService<InventoryHistoryPrice>, QueryService<InventoryHistoryPrice>,
VoableService<InventoryHistoryPrice, InventoryHistoryPriceVo> {
@Lazy @Lazy
@Autowired @Autowired
InventoryHistoryPriceRepository repository; InventoryHistoryPriceRepository repository;
@Lazy
@Autowired
InventoryService inventoryService;
@Override @Override
public InventoryHistoryPrice findById(Integer id) { public InventoryHistoryPrice findById(Integer id) {
return repository.findById(id).orElse(null); return repository.findById(id).orElse(null);
@@ -76,4 +83,64 @@ public class InventoryHistoryPriceService
return repository.save(entity); return repository.save(entity);
} }
@Override
public void updateByVo(InventoryHistoryPrice entity, InventoryHistoryPriceVo vo) {
if (entity == null || vo == null) {
return;
}
// 映射基本属性
if (vo.getInventoryId() != null) {
Inventory inventory = inventoryService.findById(vo.getInventoryId());
if (inventory != null) {
entity.setInventory(inventory);
}
}
entity.setYear(vo.getYear());
// 映射各种价格属性
if (vo.getLatestPurchasePrice() != null) {
entity.getLatestPurchasePrice().setTaxRate(vo.getLatestPurchasePrice().getTaxRate());
entity.getLatestPurchasePrice().setPreTaxPrice(vo.getLatestPurchasePrice().getPreTaxPrice());
entity.getLatestPurchasePrice().setPostTaxPrice(vo.getLatestPurchasePrice().getPostTaxPrice());
entity.getLatestPurchasePrice().setMonthDay(vo.getLatestPurchasePrice().getMonthDay());
}
if (vo.getLatestSalePrice() != null) {
entity.getLatestSalePrice().setTaxRate(vo.getLatestSalePrice().getTaxRate());
entity.getLatestSalePrice().setPreTaxPrice(vo.getLatestSalePrice().getPreTaxPrice());
entity.getLatestSalePrice().setPostTaxPrice(vo.getLatestSalePrice().getPostTaxPrice());
entity.getLatestSalePrice().setMonthDay(vo.getLatestSalePrice().getMonthDay());
}
if (vo.getMiniPurchasePrice() != null) {
entity.getMiniPurchasePrice().setTaxRate(vo.getMiniPurchasePrice().getTaxRate());
entity.getMiniPurchasePrice().setPreTaxPrice(vo.getMiniPurchasePrice().getPreTaxPrice());
entity.getMiniPurchasePrice().setPostTaxPrice(vo.getMiniPurchasePrice().getPostTaxPrice());
entity.getMiniPurchasePrice().setMonthDay(vo.getMiniPurchasePrice().getMonthDay());
}
if (vo.getMiniSalePrice() != null) {
entity.getMiniSalePrice().setTaxRate(vo.getMiniSalePrice().getTaxRate());
entity.getMiniSalePrice().setPreTaxPrice(vo.getMiniSalePrice().getPreTaxPrice());
entity.getMiniSalePrice().setPostTaxPrice(vo.getMiniSalePrice().getPostTaxPrice());
entity.getMiniSalePrice().setMonthDay(vo.getMiniSalePrice().getMonthDay());
}
if (vo.getMaxPurchasePrice() != null) {
entity.getMaxPurchasePrice().setTaxRate(vo.getMaxPurchasePrice().getTaxRate());
entity.getMaxPurchasePrice().setPreTaxPrice(vo.getMaxPurchasePrice().getPreTaxPrice());
entity.getMaxPurchasePrice().setPostTaxPrice(vo.getMaxPurchasePrice().getPostTaxPrice());
entity.getMaxPurchasePrice().setMonthDay(vo.getMaxPurchasePrice().getMonthDay());
}
if (vo.getMaxSalePrice() != null) {
entity.getMaxSalePrice().setTaxRate(vo.getMaxSalePrice().getTaxRate());
entity.getMaxSalePrice().setPreTaxPrice(vo.getMaxSalePrice().getPreTaxPrice());
entity.getMaxSalePrice().setPostTaxPrice(vo.getMaxSalePrice().getPostTaxPrice());
entity.getMaxSalePrice().setMonthDay(vo.getMaxSalePrice().getMonthDay());
}
}
} }

View File

@@ -18,9 +18,14 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.other.repository.InventoryRepository; import com.ecep.contract.ds.other.repository.InventoryRepository;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Inventory; import com.ecep.contract.model.Inventory;
import com.ecep.contract.model.InventoryCatalog;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.InventoryVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.Join;
@@ -31,7 +36,8 @@ import lombok.Setter;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "inventory") @CacheConfig(cacheNames = "inventory")
public class InventoryService implements IEntityService<Inventory>, QueryService<Inventory> { public class InventoryService
implements IEntityService<Inventory>, QueryService<Inventory>, VoableService<Inventory, InventoryVo> {
@Lazy @Lazy
@Autowired @Autowired
private InventoryRepository inventoryRepository; private InventoryRepository inventoryRepository;
@@ -129,4 +135,78 @@ public class InventoryService implements IEntityService<Inventory>, QueryService
inventory.setCreateTime(LocalDate.now()); inventory.setCreateTime(LocalDate.now());
return inventory; return inventory;
} }
@Override
public void updateByVo(Inventory entity, InventoryVo vo) {
if (entity == null || vo == null) {
return;
}
// 映射基本属性
if (vo.getCatalogId() != null) {
InventoryCatalog catalog = SpringApp.getBean(InventoryCatalogService.class).findById(vo.getCatalogId());
entity.setCatalog(catalog);
}
entity.setCode(vo.getCode());
entity.setSpecification(vo.getSpecification());
entity.setSpecificationLock(vo.isSpecificationLock());
entity.setName(vo.getName());
entity.setNameLock(vo.isNameLock());
entity.setUnit(vo.getUnit());
entity.setDescription(vo.getDescription());
// 映射重量相关属性
if (vo.getWeight() != null) {
entity.setWeight(vo.getWeight());
}
if (vo.getPackagedWeight() != null) {
entity.setPackagedWeight(vo.getPackagedWeight());
}
entity.setWeightUnit(vo.getWeightUnit());
entity.setVolumeUnit(vo.getVolumeUnit());
entity.setSizeUnit(vo.getSizeUnit());
// 映射价格相关属性
if (vo.getPurchasePrice() != null) {
entity.getPurchasePrice().setTaxRate(vo.getPurchasePrice().getTaxRate());
entity.getPurchasePrice().setPreTaxPrice(vo.getPurchasePrice().getPreTaxPrice());
entity.getPurchasePrice().setPostTaxPrice(vo.getPurchasePrice().getPostTaxPrice());
}
if (vo.getSalePrice() != null) {
entity.getSalePrice().setTaxRate(vo.getSalePrice().getTaxRate());
entity.getSalePrice().setPreTaxPrice(vo.getSalePrice().getPreTaxPrice());
entity.getSalePrice().setPostTaxPrice(vo.getSalePrice().getPostTaxPrice());
}
// 映射体积尺寸相关属性
if (vo.getVolumeSize() != null) {
entity.getVolumeSize().setVolume(vo.getVolumeSize().getVolume());
entity.getVolumeSize().setLength(vo.getVolumeSize().getLength());
entity.getVolumeSize().setWidth(vo.getVolumeSize().getWidth());
entity.getVolumeSize().setHeight(vo.getVolumeSize().getHeight());
}
if (vo.getPackagedVolumeSize() != null) {
entity.getPackagedVolumeSize().setVolume(vo.getPackagedVolumeSize().getVolume());
entity.getPackagedVolumeSize().setLength(vo.getPackagedVolumeSize().getLength());
entity.getPackagedVolumeSize().setWidth(vo.getPackagedVolumeSize().getWidth());
entity.getPackagedVolumeSize().setHeight(vo.getPackagedVolumeSize().getHeight());
}
EmployeeService employeeService = SpringApp.getBean(EmployeeService.class);
entity.setCreateTime(vo.getCreateTime());
if (vo.getCreatorId() != null) {
Employee creator = employeeService.findById(vo.getCreatorId());
entity.setCreator(creator);
}
entity.setUpdateDate(vo.getUpdateDate());
if (vo.getUpdaterId() != null) {
Employee updater = employeeService.findById(vo.getUpdaterId());
entity.setUpdater(updater);
}
// 忽略active属性因为实体中没有这个属性
}
} }

View File

@@ -16,14 +16,19 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.other.repository.PermissionRepository; import com.ecep.contract.ds.other.repository.PermissionRepository;
import com.ecep.contract.model.Function;
import com.ecep.contract.model.Permission; import com.ecep.contract.model.Permission;
import com.ecep.contract.service.ServiceException;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.PermissionVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "permission") @CacheConfig(cacheNames = "permission")
public class PermissionService implements IEntityService<Permission>, QueryService<Permission> { public class PermissionService implements IEntityService<Permission>, QueryService<Permission>, VoableService<Permission, PermissionVo> {
@Lazy @Lazy
@Autowired @Autowired
@@ -85,4 +90,26 @@ public class PermissionService implements IEntityService<Permission>, QueryServi
return permissionRepository.findAllByFunctionId(functionId); return permissionRepository.findAllByFunctionId(functionId);
} }
@Override
public void updateByVo(Permission permission, PermissionVo vo) {
// 映射基本属性
permission.setName(vo.getName());
permission.setKey(vo.getKey());
// 处理关联对象 function
if (vo.getFunctionId() != null) {
try {
Function function = SpringApp.getBean(FunctionService.class).findById(vo.getFunctionId());
if (function != null) {
permission.setFunction(function);
}
} catch (Exception e) {
throw new ServiceException("Failed to find Function: " + e.getMessage(), e);
}
}
// PermissionVo中的description和active字段在Permission实体中不存在这里不做处理
// 如果需要处理,可以添加日志记录或者其他逻辑
}
} }

View File

@@ -2,11 +2,6 @@ package com.ecep.contract.ds.project.service;
import java.util.List; import java.util.List;
import com.ecep.contract.QueryService;
import com.ecep.contract.constant.ServiceConstant;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@@ -16,8 +11,18 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.ServiceConstant;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.ds.project.repository.CustomerSatisfactionSurveyRepository; import com.ecep.contract.ds.project.repository.CustomerSatisfactionSurveyRepository;
import com.ecep.contract.model.CustomerSatisfactionSurvey; import com.ecep.contract.model.CustomerSatisfactionSurvey;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Project;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.CustomerSatisfactionSurveyVo;
import com.fasterxml.jackson.databind.JsonNode;
/** /**
* 项目客户满意度调查服务 * 项目客户满意度调查服务
@@ -25,7 +30,8 @@ import com.ecep.contract.model.CustomerSatisfactionSurvey;
@Lazy @Lazy
@Service @Service
public class CustomerSatisfactionSurveyService public class CustomerSatisfactionSurveyService
implements IEntityService<CustomerSatisfactionSurvey>, QueryService<CustomerSatisfactionSurvey> { implements IEntityService<CustomerSatisfactionSurvey>, QueryService<CustomerSatisfactionSurvey>,
VoableService<CustomerSatisfactionSurvey, CustomerSatisfactionSurveyVo> {
@Lazy @Lazy
@Autowired @Autowired
private CustomerSatisfactionSurveyRepository repository; private CustomerSatisfactionSurveyRepository repository;
@@ -109,4 +115,27 @@ public class CustomerSatisfactionSurveyService
spec = SpecificationUtils.andParam(spec, paramsNode, "project", "applicant"); spec = SpecificationUtils.andParam(spec, paramsNode, "project", "applicant");
return findAll(spec, pageable); return findAll(spec, pageable);
} }
@Override
public void updateByVo(CustomerSatisfactionSurvey model, CustomerSatisfactionSurveyVo vo) {
model.setCode(vo.getCode());
model.setDate(vo.getDate());
model.setTotalScore(vo.getTotalScore());
model.setData(vo.getData());
model.setApplyTime(vo.getApplyTime());
model.setDescription(vo.getDescription());
// 处理关联对象
if (vo.getProject() != null) {
Project project = SpringApp.getBean(ProjectService.class).findById(vo.getProject());
model.setProject(project);
}
if (vo.getApplicantId() != null) {
Employee employee = SpringApp.getBean(EmployeeService.class).findById(vo.getApplicantId());
model.setApplicant(employee);
}
// active属性在实体中不存在忽略
}
} }

View File

@@ -3,7 +3,6 @@ package com.ecep.contract.ds.project.service;
import java.util.List; import java.util.List;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -21,11 +20,13 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.ds.project.repository.ProductTypeRepository; import com.ecep.contract.ds.project.repository.ProductTypeRepository;
import com.ecep.contract.model.ProductType; import com.ecep.contract.model.ProductType;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.ProductTypeVo;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "product-type") @CacheConfig(cacheNames = "product-type")
public class ProductTypeService implements IEntityService<ProductType>, QueryService<ProductType> { public class ProductTypeService implements IEntityService<ProductType>, QueryService<ProductType>, VoableService<ProductType, ProductTypeVo> {
@Lazy @Lazy
@Autowired @Autowired
private ProductTypeRepository productTypeRepository; private ProductTypeRepository productTypeRepository;
@@ -97,4 +98,15 @@ public class ProductTypeService implements IEntityService<ProductType>, QuerySer
public void delete(ProductType type) { public void delete(ProductType type) {
productTypeRepository.delete(type); productTypeRepository.delete(type);
} }
@Override
public void updateByVo(ProductType productType, ProductTypeVo vo) {
// 映射基本属性
productType.setName(vo.getName());
productType.setCode(vo.getCode());
productType.setDescription(vo.getDescription());
// ProductTypeVo中的parentId、order和active字段在ProductType实体中不存在这里不做处理
// 如果需要处理,可以添加日志记录或者其他逻辑
}
} }

View File

@@ -4,6 +4,7 @@ import java.util.List;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.model.CompanyBankAccount; import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -21,11 +22,12 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.ds.project.repository.ProductUsageRepository; import com.ecep.contract.ds.project.repository.ProductUsageRepository;
import com.ecep.contract.model.ProductUsage; import com.ecep.contract.model.ProductUsage;
import com.ecep.contract.vo.ProductUsageVo;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "product-usage") @CacheConfig(cacheNames = "product-usage")
public class ProductUsageService implements IEntityService<ProductUsage>, QueryService<ProductUsage> { public class ProductUsageService implements IEntityService<ProductUsage>, QueryService<ProductUsage>, VoableService<ProductUsage, ProductUsageVo> {
@Lazy @Lazy
@Autowired @Autowired
private ProductUsageRepository productUsageRepository; private ProductUsageRepository productUsageRepository;
@@ -100,4 +102,14 @@ public class ProductUsageService implements IEntityService<ProductUsage>, QueryS
public void delete(ProductUsage usage) { public void delete(ProductUsage usage) {
productUsageRepository.delete(usage); productUsageRepository.delete(usage);
} }
@Override
public void updateByVo(ProductUsage productUsage, ProductUsageVo vo) {
// 映射基本属性
productUsage.setName(vo.getName());
productUsage.setCode(vo.getCode());
productUsage.setDescription(vo.getDescription());
// ProductUsageVo中的active字段在ProductUsage实体中不存在这里不做处理
}
} }

View File

@@ -2,10 +2,6 @@ package com.ecep.contract.ds.project.service;
import java.util.List; import java.util.List;
import com.ecep.contract.QueryService;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@@ -15,13 +11,18 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.ds.project.repository.ProjectCostItemRepository; import com.ecep.contract.ds.project.repository.ProjectCostItemRepository;
import com.ecep.contract.model.ProjectCost; import com.ecep.contract.model.ProjectCost;
import com.ecep.contract.model.ProjectCostItem; import com.ecep.contract.model.ProjectCostItem;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.ProjectCostItemVo;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
public class ProjectCostItemService implements IEntityService<ProjectCostItem>, QueryService<ProjectCostItem> { public class ProjectCostItemService implements IEntityService<ProjectCostItem>, QueryService<ProjectCostItem>, VoableService<ProjectCostItem, ProjectCostItemVo> {
@Lazy @Lazy
@Autowired @Autowired
private ProjectCostItemRepository repository; private ProjectCostItemRepository repository;
@@ -73,4 +74,10 @@ public class ProjectCostItemService implements IEntityService<ProjectCostItem>,
return repository.save(entity); return repository.save(entity);
} }
@Override
public void updateByVo(ProjectCostItem item, ProjectCostItemVo vo) {
throw new UnsupportedOperationException("Not supported yet.");
}
} }

View File

@@ -3,10 +3,6 @@ package com.ecep.contract.ds.project.service;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import com.ecep.contract.QueryService;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -18,13 +14,22 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.contract.service.ContractPayPlanService;
import com.ecep.contract.ds.project.repository.ProjectFundPlanRepository; import com.ecep.contract.ds.project.repository.ProjectFundPlanRepository;
import com.ecep.contract.model.ContractPayPlan;
import com.ecep.contract.model.Project; import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectFundPlan; import com.ecep.contract.model.ProjectFundPlan;
import com.ecep.contract.service.ServiceException;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.ProjectFundPlanVo;
import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
public class ProjectFundPlanService implements IEntityService<ProjectFundPlan>, QueryService<ProjectFundPlan> { public class ProjectFundPlanService implements IEntityService<ProjectFundPlan>, QueryService<ProjectFundPlan>, VoableService<ProjectFundPlan, ProjectFundPlanVo> {
private static final Logger logger = LoggerFactory.getLogger(ProjectFundPlanService.class); private static final Logger logger = LoggerFactory.getLogger(ProjectFundPlanService.class);
@Lazy @Lazy
@@ -84,4 +89,39 @@ public class ProjectFundPlanService implements IEntityService<ProjectFundPlan>,
public List<ProjectFundPlan> findAll(Specification<ProjectFundPlan> spec, Sort sort) { public List<ProjectFundPlan> findAll(Specification<ProjectFundPlan> spec, Sort sort) {
return repository.findAll(spec, sort); return repository.findAll(spec, sort);
} }
@Override
public void updateByVo(ProjectFundPlan fundPlan, ProjectFundPlanVo vo) {
// 映射基本属性
fundPlan.setPayDate(vo.getPayDate());
fundPlan.setPayWay(vo.getPayWay());
fundPlan.setPayRatio(vo.getPayRatio());
fundPlan.setPayCurrency(vo.getPayCurrency());
fundPlan.setPayTerm(vo.getPayTerm());
fundPlan.setUpdateDate(vo.getUpdateDate());
// 处理关联对象 project
if (vo.getProjectId() != null) {
try {
Project project = SpringApp.getBean(ProjectService.class).findById(vo.getProjectId());
if (project != null) {
fundPlan.setProject(project);
}
} catch (Exception e) {
throw new ServiceException("Failed to find Project: " + e.getMessage(), e);
}
}
// 处理关联对象 contractPayPlan
if (vo.getContractPayPlanId() != null) {
try {
ContractPayPlan contractPayPlan = SpringApp.getBean(ContractPayPlanService.class).findById(vo.getContractPayPlanId());
if (contractPayPlan != null) {
fundPlan.setContractPayPlan(contractPayPlan);
}
} catch (Exception e) {
throw new ServiceException("Failed to find ContractPayPlan: " + e.getMessage(), e);
}
}
}
} }

View File

@@ -3,7 +3,6 @@ package com.ecep.contract.ds.project.service;
import java.util.List; import java.util.List;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -21,11 +20,13 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.ds.project.repository.ProjectIndustryRepository; import com.ecep.contract.ds.project.repository.ProjectIndustryRepository;
import com.ecep.contract.model.ProjectIndustry; import com.ecep.contract.model.ProjectIndustry;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.ProjectIndustryVo;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "project-industry") @CacheConfig(cacheNames = "project-industry")
public class ProjectIndustryService implements IEntityService<ProjectIndustry>, QueryService<ProjectIndustry> { public class ProjectIndustryService implements IEntityService<ProjectIndustry>, QueryService<ProjectIndustry>, VoableService<ProjectIndustry, ProjectIndustryVo> {
@Lazy @Lazy
@Autowired @Autowired
private ProjectIndustryRepository industryRepository; private ProjectIndustryRepository industryRepository;
@@ -101,4 +102,15 @@ public class ProjectIndustryService implements IEntityService<ProjectIndustry>,
public void delete(ProjectIndustry industry) { public void delete(ProjectIndustry industry) {
industryRepository.delete(industry); industryRepository.delete(industry);
} }
@Override
public void updateByVo(ProjectIndustry industry, ProjectIndustryVo vo) {
// 映射基本属性
industry.setName(vo.getName());
industry.setCode(vo.getCode());
industry.setDescription(vo.getDescription());
// ProjectIndustryVo中的active字段在ProjectIndustry实体中不存在这里不做处理
// 如果需要处理,可以添加日志记录或者其他逻辑
}
} }

View File

@@ -20,11 +20,13 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.ds.project.repository.ProjectSaleTypeRepository; import com.ecep.contract.ds.project.repository.ProjectSaleTypeRepository;
import com.ecep.contract.model.ProjectSaleType; import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.vo.ProjectSaleTypeVo;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "project-sale-type") @CacheConfig(cacheNames = "project-sale-type")
public class ProjectSaleTypeService implements IEntityService<ProjectSaleType>, QueryService<ProjectSaleType> { public class ProjectSaleTypeService implements IEntityService<ProjectSaleType>, QueryService<ProjectSaleType>, VoableService<ProjectSaleType, ProjectSaleTypeVo> {
@Lazy @Lazy
@Autowired @Autowired
private ProjectSaleTypeRepository saleTypeRepository; private ProjectSaleTypeRepository saleTypeRepository;
@@ -92,4 +94,25 @@ public class ProjectSaleTypeService implements IEntityService<ProjectSaleType>,
public void delete(ProjectSaleType type) { public void delete(ProjectSaleType type) {
saleTypeRepository.delete(type); saleTypeRepository.delete(type);
} }
@Override
public void updateByVo(ProjectSaleType saleType, ProjectSaleTypeVo vo) {
// 映射基本属性
saleType.setName(vo.getName());
saleType.setCode(vo.getCode());
saleType.setPath(vo.getPath());
saleType.setDescription(vo.getDescription());
saleType.setStoreByYear(vo.isStoreByYear());
saleType.setCriticalProjectDecision(vo.isCriticalProjectDecision());
// 处理Double类型的criticalProjectLimit
if (vo.getCriticalProjectLimit() != null) {
saleType.setCriticalProjectLimit(vo.getCriticalProjectLimit());
}
saleType.setActive(vo.isActive());
// ProjectSaleTypeVo中的created和version字段在ProjectSaleType实体中不存在这里不做处理
// 如果需要处理,可以添加日志记录或者其他逻辑
}
} }

View File

@@ -23,7 +23,10 @@ import org.springframework.util.StringUtils;
import com.ecep.contract.IEntityService; import com.ecep.contract.IEntityService;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.ProjectConstant; import com.ecep.contract.constant.ProjectConstant;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.ds.other.service.SysConfService; import com.ecep.contract.ds.other.service.SysConfService;
import com.ecep.contract.ds.project.repository.ProjectRepository; import com.ecep.contract.ds.project.repository.ProjectRepository;
import com.ecep.contract.model.Contract; import com.ecep.contract.model.Contract;
@@ -34,7 +37,9 @@ import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectIndustry; import com.ecep.contract.model.ProjectIndustry;
import com.ecep.contract.model.ProjectSaleType; import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.model.ProjectType; import com.ecep.contract.model.ProjectType;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.ProjectVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
/** /**
@@ -43,7 +48,8 @@ import com.fasterxml.jackson.databind.JsonNode;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "project") @CacheConfig(cacheNames = "project")
public class ProjectService implements IEntityService<Project>, QueryService<Project> { public class ProjectService
implements IEntityService<Project>, QueryService<Project>, VoableService<Project, ProjectVo> {
private static final Logger logger = LoggerFactory.getLogger(ProjectService.class); private static final Logger logger = LoggerFactory.getLogger(ProjectService.class);
@Lazy @Lazy
@@ -137,13 +143,13 @@ public class ProjectService implements IEntityService<Project>, QueryService<Pro
spec = getSpecification(paramsNode.get("searchText").asText()); spec = getSpecification(paramsNode.get("searchText").asText());
} }
// field // field
spec = SpecificationUtils.andParam(spec, paramsNode, "customer","industry","saleType", "projectType", "productType","deliverySignMethod", "productUsage"); spec = SpecificationUtils.andParam(spec, paramsNode, "customer", "industry", "saleType", "projectType",
spec = SpecificationUtils.andParam(spec, paramsNode, "applicant","authorizer"); "productType", "deliverySignMethod", "productUsage");
spec = SpecificationUtils.andParam(spec, paramsNode, "applicant", "authorizer");
// //
spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "code"); spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "code");
return findAll(spec, pageable); return findAll(spec, pageable);
} }
@@ -304,6 +310,45 @@ public class ProjectService implements IEntityService<Project>, QueryService<Pro
return project; return project;
} }
@Override
public void updateByVo(Project project, ProjectVo vo) {
project.setName(vo.getName());
project.setCode(vo.getCode());
project.setCreated(vo.getCreated());
project.setProjectType(
vo.getProjectTypeId() != null ? projectTypeService.findById(vo.getProjectTypeId()) : null);
project.setSaleType(vo.getSaleTypeId() != null ? projectSaleTypeService.findById(vo.getSaleTypeId()) : null);
project.setIndustry(vo.getIndustryId() != null ? projectIndustryService.findById(vo.getIndustryId()) : null);
project.setProductType(
vo.getProductTypeId() != null ? productTypeService.findById(vo.getProductTypeId()) : null);
project.setProductUsage(
vo.getProductUsageId() != null ? productUsageService.findById(vo.getProductUsageId()) : null);
project.setDeliverySignMethod(
vo.getDeliverySignMethodId() != null ? deliverySignMethodService.findById(vo.getDeliverySignMethodId())
: null);
project.setCustomer(
vo.getCustomerId() != null ? SpringApp.getBean(CompanyService.class).findById(vo.getCustomerId())
: null);
project.setApplicant(
vo.getApplicantId() != null ? SpringApp.getBean(EmployeeService.class).findById(vo.getApplicantId())
: null);
project.setDescription(vo.getDescription());
project.setAmount(vo.getAmount());
project.setCodeYear(vo.getCodeYear());
project.setCodeSequenceNumber(vo.getCodeSequenceNumber());
project.setAddress(vo.getAddress());
project.setUseBid(vo.isUseBid());
project.setUseOffer(vo.isUseOffer());
project.setStandardPayWay(vo.isStandardPayWay());
project.setPath(vo.getPath());
project.setPlannedStartTime(vo.getPlannedStartTime());
project.setPlannedCompletionTime(vo.getPlannedCompletionTime());
if (project.getVersion() != vo.getVersion()) {
logger.warn("project version not equal, project id: {}, version: {}, vo version: {}", project.getId(),
project.getVersion(), vo.getVersion());
}
}
} }

View File

@@ -4,7 +4,9 @@ import java.util.List;
import com.ecep.contract.QueryService; import com.ecep.contract.QueryService;
import com.ecep.contract.model.CompanyBankAccount; import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.ProjectTypeVo;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheConfig;
@@ -25,7 +27,7 @@ import com.ecep.contract.model.ProjectType;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = "project-type") @CacheConfig(cacheNames = "project-type")
public class ProjectTypeService implements IEntityService<ProjectType>, QueryService<ProjectType> { public class ProjectTypeService implements IEntityService<ProjectType>, QueryService<ProjectType>, VoableService<ProjectType, ProjectTypeVo> {
@Lazy @Lazy
@Autowired @Autowired
private ProjectTypeRepository projectTypeRepository; private ProjectTypeRepository projectTypeRepository;
@@ -97,4 +99,11 @@ public class ProjectTypeService implements IEntityService<ProjectType>, QuerySer
projectTypeRepository.delete(type); projectTypeRepository.delete(type);
} }
@Override
public void updateByVo(ProjectType model, ProjectTypeVo vo) {
model.setName(vo.getName());
model.setCode(vo.getCode());
model.setDescription(vo.getDescription());
}
} }

View File

@@ -1,20 +1,16 @@
package com.ecep.contract.ds.vendor.service; package com.ecep.contract.ds.vendor.service;
import com.ecep.contract.*; import java.io.File;
import com.ecep.contract.constant.CompanyVendorConstant; import java.time.LocalDate;
import com.ecep.contract.constant.ServiceConstant; import java.util.ArrayList;
import com.ecep.contract.ds.company.service.CompanyBasicService; import java.util.HashMap;
import com.ecep.contract.ds.other.service.SysConfService; import java.util.List;
import com.ecep.contract.ds.vendor.repository.VendorRepository; import java.util.Map;
import com.ecep.contract.ds.vendor.repository.VendorClassRepository; import java.util.Objects;
import com.ecep.contract.ds.vendor.repository.VendorTypeLocalRepository; import java.util.Optional;
import com.ecep.contract.model.*; import java.util.function.Consumer;
import com.ecep.contract.util.CompanyUtils; import java.util.stream.Collectors;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.Path;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -30,17 +26,46 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.io.File; import com.ecep.contract.IEntityService;
import java.time.LocalDate; import com.ecep.contract.MessageHolder;
import java.util.*; import com.ecep.contract.QueryService;
import java.util.function.Consumer; import com.ecep.contract.VendorFileType;
import java.util.stream.Collectors; import com.ecep.contract.VendorType;
import com.ecep.contract.constant.CompanyVendorConstant;
import com.ecep.contract.constant.ServiceConstant;
import com.ecep.contract.ds.company.service.CompanyBasicService;
import com.ecep.contract.ds.company.service.CompanyContactService;
import com.ecep.contract.ds.other.service.SysConfService;
import com.ecep.contract.ds.vendor.repository.VendorClassRepository;
import com.ecep.contract.ds.vendor.repository.VendorRepository;
import com.ecep.contract.ds.vendor.repository.VendorTypeLocalRepository;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyBasicFile;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.Vendor;
import com.ecep.contract.model.VendorCatalog;
import com.ecep.contract.model.VendorEntity;
import com.ecep.contract.model.VendorFile;
import com.ecep.contract.model.VendorTypeLocal;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.util.CompanyUtils;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.VendorVo;
import com.fasterxml.jackson.databind.JsonNode;
import jakarta.persistence.criteria.Path;
@Lazy @Lazy
@Service @Service
@CacheConfig(cacheNames = CompanyVendorConstant.CACHE_NAME) @CacheConfig(cacheNames = CompanyVendorConstant.CACHE_NAME)
public class VendorService extends CompanyBasicService public class VendorService extends CompanyBasicService
implements IEntityService<Vendor>, QueryService<Vendor> { implements IEntityService<Vendor>, QueryService<Vendor>, VoableService<Vendor, VendorVo> {
@Autowired
private VendorCatalogService vendorCatalogService;
@Autowired
private CompanyContactService companyContactService;
private static final Logger logger = LoggerFactory.getLogger(VendorService.class); private static final Logger logger = LoggerFactory.getLogger(VendorService.class);
@@ -452,4 +477,22 @@ public class VendorService extends CompanyBasicService
return repository.count(spec); return repository.count(spec);
} }
@Override
public void updateByVo(Vendor vendor, VendorVo vo) {
vendor.setType(vo.getType());
vendor.setProtocolProvider(vo.isProtocolProvider());
vendor.setDevelopDate(vo.getDevelopDate());
vendor.setPath(vo.getPath());
vendor.setPurchase(vo.getPurchase());
vendor.setDescription(vo.getDescription());
if (vo.getCatalogId() != null) {
vendor.setCatalog(vendorCatalogService.findById(vo.getCatalogId()));
}
if (vo.getContactId() != null) {
vendor.setContact(companyContactService.findById(vo.getContactId()));
}
}
} }

View File

@@ -1,28 +1,5 @@
package com.ecep.contract.handler; package com.ecep.contract.handler;
import com.ecep.contract.*;
import com.ecep.contract.constant.WebSocketConstant;
import com.ecep.contract.ds.other.service.EmployeeLoginHistoryService;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.EmployeeLoginHistory;
import com.ecep.contract.model.Voable;
import com.ecep.contract.service.WebSocketServerTaskManager;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -38,6 +15,41 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.PingMessage;
import org.springframework.web.socket.PongMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.ecep.contract.IEntityService;
import com.ecep.contract.PageArgument;
import com.ecep.contract.PageContent;
import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.WebSocketConstant;
import com.ecep.contract.ds.other.service.EmployeeLoginHistoryService;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.EmployeeLoginHistory;
import com.ecep.contract.model.Voable;
import com.ecep.contract.service.VoableService;
import com.ecep.contract.service.WebSocketServerTaskManager;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.Data;
/** /**
* WebSocket处理器 * WebSocket处理器
* 处理与客户端的WebSocket连接、消息传递和断开连接 * 处理与客户端的WebSocket连接、消息传递和断开连接
@@ -291,11 +303,21 @@ public class WebSocketServerHandler extends TextWebSocketHandler {
} }
} else { } else {
entity = createNewEntity(entityService); entity = createNewEntity(entityService);
if (entity == null) {
throw new UnsupportedOperationException("无法创建实体对象, " + service.getClass().getName());
}
} }
objectMapper.updateValue(entity, paramsNode);
if (service instanceof VoableService<?, ?>) {
String typeClz = argumentsNode.get(1).asText();
Class<?> type = null;
try {
type = Class.forName(typeClz);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
Object object = objectMapper.convertValue(paramsNode, type);
((VoableService<Object, Object>) service).updateByVo(entity, object);
} else {
objectMapper.updateValue(entity, paramsNode);
}
return ((IEntityService<Object>) entityService).save(entity); return ((IEntityService<Object>) entityService).save(entity);
} }

View File

@@ -0,0 +1,13 @@
package com.ecep.contract.service;
public class ServiceException extends RuntimeException {
public ServiceException(String message) {
super(message);
}
public ServiceException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,8 @@
package com.ecep.contract.service;
/**
* 可转换为VO的服务
*/
public interface VoableService<M, Vo> {
void updateByVo(M model, Vo vo);
}

View File

@@ -19,6 +19,7 @@ import org.springframework.web.socket.WebSocketSession;
import com.ecep.contract.Message; import com.ecep.contract.Message;
import com.ecep.contract.constant.WebSocketConstant; import com.ecep.contract.constant.WebSocketConstant;
import com.ecep.contract.model.Voable;
import com.ecep.contract.ui.Tasker; import com.ecep.contract.ui.Tasker;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@@ -107,7 +108,12 @@ public class WebSocketServerTaskManager implements InitializingBean {
if (tasker instanceof WebSocketServerTasker t) { if (tasker instanceof WebSocketServerTasker t) {
t.setTitleHandler(title -> sendToSession(session, sessionId, "title", title)); t.setTitleHandler(title -> sendToSession(session, sessionId, "title", title));
t.setMessageHandler(msg -> sendMessageToSession(session, sessionId, msg)); t.setMessageHandler(msg -> sendMessageToSession(session, sessionId, msg));
t.setPropertyHandler((name, value) -> sendToSession(session, sessionId, "property", name, value)); t.setPropertyHandler((name, value) -> {
if (value instanceof Voable<?> voable) {
value = voable.toVo();
}
sendToSession(session, sessionId, "property", name, value);
});
t.setProgressHandler((current, total) -> sendToSession(session, sessionId, "progress", current, total)); t.setProgressHandler((current, total) -> sendToSession(session, sessionId, "progress", current, total));
t.init(argsNode.get(2)); t.init(argsNode.get(2));
} }

View File

@@ -0,0 +1,13 @@
{
"taskers": {
"ContractSyncTask": "com.ecep.contract.cloud.u8.ContractSyncTask",
"ContractRepairTask": "com.ecep.contract.ds.contract.tasker.ContractRepairTask",
"ContractVerifyTask": "com.ecep.contract.ds.contract.tasker.ContractVerifyTask",
"ProjectCostImportItemsFromContractsTasker": "com.ecep.contract.ds.project.ProjectCostImportItemsFromContractsTasker",
"CompanyCustomerEvaluationFormUpdateTask": "com.ecep.contract.ds.customer.tasker.CompanyCustomerEvaluationFormUpdateTask",
"CompanyCustomerNextSignDateTask": "com.ecep.contract.ds.customer.tasker.CompanyCustomerNextSignDateTask",
"CompanyCustomerRebuildFilesTasker": "com.ecep.contract.ds.customer.tasker.CompanyCustomerRebuildFilesTasker",
"CustomerFileMoveTasker": "com.ecep.contract.ds.customer.tasker.CustomerFileMoveTasker"
},
"descriptions": "任务注册信息"
}