Compare commits

...

2 Commits

Author SHA1 Message Date
c42ff7501d refactor: 重构WebSocket服务及相关实体类
重构WebSocket服务名称从WebSocketService改为WebSocketClientService,并实现Serializable接口
添加WebSocket常量定义和消息处理实现
优化实体类equals和hashCode方法
修复控制器路径和日志配置
添加查询服务和任务接口方法
2025-09-17 11:45:50 +08:00
30deb0a280 feat: 实现WebSocket通信框架及任务管理功能
新增WebSocket客户端和服务端通信框架,包括会话管理、心跳检测和自动重连机制
添加任务管理器用于处理WebSocket任务创建和执行
实现消息回调处理和错误处理机制
重构销售类型服务并添加缓存支持
移除旧的销售类型服务实现
2025-09-17 11:44:39 +08:00
154 changed files with 2387 additions and 1118 deletions

View File

@@ -1,6 +1,8 @@
package com.ecep.contract;
import com.ecep.contract.constant.WebSocketConstant;
import com.ecep.contract.msg.SimpleMessage;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import javafx.application.Platform;
@@ -24,17 +26,19 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* WebSocket消息服务
* 提供向服务器端发送WebSocket消息的功能
*/
@Service
public class WebSocketService {
private static final Logger logger = LoggerFactory.getLogger(WebSocketService.class);
public class WebSocketClientService {
private static final Logger logger = LoggerFactory.getLogger(WebSocketClientService.class);
@Getter
@Setter
private WebSocket webSocket;
@Getter
@Autowired
private ObjectMapper objectMapper;
private static final int RECONNECT_DELAY_MS = 5000; // 重连延迟时间毫秒
@@ -49,6 +53,9 @@ public class WebSocketService {
private SimpleBooleanProperty online = new SimpleBooleanProperty(false);
private SimpleStringProperty message = new SimpleStringProperty("");
// 存储所有活跃的WebSocket会话
private final Map<String, WebSocketClientSession> sessions = Collections.synchronizedMap(new HashMap<>());
// 存储所有活跃的WebSocket会话
private final Map<String, CompletableFuture<JsonNode>> callbacks = Collections.synchronizedMap(new HashMap<>());
@@ -75,29 +82,27 @@ public class WebSocketService {
try {
JsonNode node = objectMapper.readTree(text);
if (node.has("messageId")) {
String messageId = node.get("messageId").asText();
if (node.has(WebSocketConstant.MESSAGE_ID_FIELD_NAME)) {
String messageId = node.get(WebSocketConstant.MESSAGE_ID_FIELD_NAME).asText();
CompletableFuture<JsonNode> future = callbacks.remove(messageId);
if (future != null) {
if (node.has("success")) {
if (!node.get("success").asBoolean()) {
future.completeExceptionally(
new RuntimeException("请求失败:来自服务器的消息=" + node.get("message").asText()));
return;
}
}
// 使用具体类型后这里不会再出现类型不匹配的错误
if (node.has("data")) {
future.complete(node.get("data"));
} else {
future.complete(node);
}
onCallbackMessage(future, node);
} else {
logger.error("未找到对应的回调future: {}", messageId);
}
} else if (node.has("errorCode")) {
int errorCode = node.get("errorCode").asInt();
String errorMsg = node.get("message").asText();
} else if (node.has(WebSocketConstant.SESSION_ID_FIELD_NAME)) {
String sessionId = node.get(WebSocketConstant.SESSION_ID_FIELD_NAME).asText();
WebSocketClientSession session = sessions.get(sessionId);
if (session != null) {
try {
session.onMessage(node);
} catch (Exception e) {
session.updateMessage(java.util.logging.Level.SEVERE, "会话异常: " + e.getMessage());
}
}
} else if (node.has(WebSocketConstant.ERROR_CODE_FIELD_NAME)) {
int errorCode = node.get(WebSocketConstant.ERROR_CODE_FIELD_NAME).asInt();
String errorMsg = node.get(WebSocketConstant.MESSAGE_FIELD_NAME).asText();
// TODO 需要重新登录
logger.error("收到错误消息: 错误码={}, 错误信息={}", errorCode, errorMsg);
}
@@ -106,6 +111,7 @@ public class WebSocketService {
}
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
// 处理收到的二进制消息
@@ -139,6 +145,22 @@ public class WebSocketService {
}
};
private void onCallbackMessage(CompletableFuture<JsonNode> future, JsonNode node) {
if (node.has(WebSocketConstant.SUCCESS_FIELD_VALUE)) {
if (!node.get(WebSocketConstant.SUCCESS_FIELD_VALUE).asBoolean()) {
future.completeExceptionally(
new RuntimeException("请求失败:来自服务器的消息=" + node.get(WebSocketConstant.MESSAGE_FIELD_NAME).asText()));
return;
}
}
// 使用具体类型后这里不会再出现类型不匹配的错误
if (node.has("data")) {
future.complete(node.get("data"));
} else {
future.complete(node);
}
}
public void send(String string) {
if (webSocket != null && webSocket.send(string)) {
logger.debug("send message success:{}", string);
@@ -147,6 +169,10 @@ public class WebSocketService {
}
}
public void send(Object message) throws JsonProcessingException {
send(objectMapper.writeValueAsString(message));
}
public CompletableFuture<JsonNode> send(SimpleMessage msg) {
CompletableFuture<JsonNode> future = new CompletableFuture<>();
try {
@@ -168,6 +194,14 @@ public class WebSocketService {
return future;
}
public CompletableFuture<JsonNode> invoke(String service, String method, Object... params) {
SimpleMessage msg = new SimpleMessage();
msg.setService(service);
msg.setMethod(method);
msg.setArguments(params);
return send(msg).orTimeout(getReadTimeout(), TimeUnit.MILLISECONDS);
}
public void initWebSocket() {
isActive = true;
OkHttpClient httpClient = Desktop.instance.getHttpClient();
@@ -278,4 +312,25 @@ public class WebSocketService {
return online;
}
public void withSession(Consumer<WebSocketClientSession> sessionConsumer) {
WebSocketClientSession session = createSession();
try {
sessionConsumer.accept(session);
} finally {
// closeSession(session);
}
}
private void closeSession(WebSocketClientSession session) {
if (session != null) {
sessions.remove(session.getSessionId());
session.close();
}
}
private WebSocketClientSession createSession() {
WebSocketClientSession session = new WebSocketClientSession(this);
sessions.put(session.getSessionId(), session);
return session;
}
}

View File

@@ -0,0 +1,89 @@
package com.ecep.contract;
import com.ecep.contract.constant.WebSocketConstant;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Getter;
import org.springframework.beans.BeanUtils;
import java.beans.PropertyDescriptor;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
public class WebSocketClientSession {
@Getter
private String sessionId = UUID.randomUUID().toString();
private WebSocketClientTasker tasker;
private final WebSocketClientService webSocketService;
public WebSocketClientSession(WebSocketClientService webSocketService) {
this.webSocketService = webSocketService;
}
public void close() {
}
public void submitTask(WebSocketClientTasker tasker, Object... args) throws JsonProcessingException {
this.tasker = tasker;
// 将 tasker.getTaskName() 和 args 合并到一个数组参数中
Object[] mergedArgs = new Object[args.length + 1];
mergedArgs[0] = tasker.getTaskName();
System.arraycopy(args, 0, mergedArgs, 1, args.length);
send("createTask", mergedArgs);
}
public void send(String type, Object... args) throws JsonProcessingException {
Map<String, Object> arguments = Map.of(
WebSocketConstant.SESSION_ID_FIELD_NAME, getSessionId(),
"type", type,
WebSocketConstant.ARGUMENTS_FIELD_NAME, args);
webSocketService.send(arguments);
}
public void onMessage(JsonNode node) {
if (node.has("type")) {
String type = node.get("type").asText();
JsonNode args = node.get(WebSocketConstant.ARGUMENTS_FIELD_NAME);
if (type.equals("message")) {
String message = args.get(1).asText();
String level = args.get(0).asText();
updateMessage(java.util.logging.Level.parse(level), message);
} else if (type.equals("title")) {
String message = args.get(0).asText();
tasker.updateTitle(message);
} else if (type.equals("property")) {
String name = args.get(0).asText();
Object value = args.get(1);
try {
PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(tasker.getClass(), name);
System.out.println("descriptor = " + descriptor);
System.out.println("descriptor.getPropertyType() = " + descriptor.getPropertyType());
Object object = webSocketService.getObjectMapper().convertValue(value, descriptor.getPropertyType());
System.out.println("object = " + object);
System.out.println("descriptor.getWriteMethod() = " + descriptor.getWriteMethod());
System.out.println("descriptor.getWriteMethod().getParameterTypes() = " + descriptor.getWriteMethod().getParameterTypes());
descriptor.getWriteMethod().invoke(tasker, object);
} catch (Exception e) {
tasker.updateMessage(java.util.logging.Level.SEVERE, "属性设置失败: " + name + " = " + value);
}
} else if (type.equals("progress")) {
long current = args.get(0).asLong();
long total = args.get(1).asLong();
tasker.updateProgress(current, total);
} else {
tasker.updateMessage(java.util.logging.Level.INFO, "未知的消息类型: " + node.toString());
}
} else {
tasker.updateMessage(java.util.logging.Level.INFO, "未知的消息: " + node.toString());
}
}
public void updateMessage(Level level, String message) {
tasker.updateMessage(level, message);
}
}

View File

@@ -0,0 +1,13 @@
package com.ecep.contract;
import java.util.logging.Level;
public interface WebSocketClientTasker {
String getTaskName();
void updateMessage(Level level, String message);
void updateTitle(String title);
void updateProgress(long current, long total);
}

View File

@@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
import com.ecep.contract.Desktop;
import com.ecep.contract.DesktopUtils;
import com.ecep.contract.WebSocketService;
import com.ecep.contract.WebSocketClientService;
import com.ecep.contract.controller.bank.BankManagerWindowController;
import com.ecep.contract.controller.company.CompanyManagerWindowController;
import com.ecep.contract.controller.contract.ContractManagerWindowController;
@@ -101,7 +101,7 @@ public class HomeWindowController extends BaseController {
Desktop.instance.getTaskMonitorCenter().bindStatusLabel(taskMonitorLabel);
Desktop.instance.getActiveEmployee().initialize();
WebSocketService webSocketService = getBean(WebSocketService.class);
WebSocketClientService webSocketService = getBean(WebSocketClientService.class);
webSocketMonitorIcon.iconProperty()
.bind(webSocketService.getOnlineProperty().map(b -> b ? "CHAIN" : "CHAIN_BROKEN"));
webSocketMonitorLabel.textProperty().bind(webSocketService.getMessageProperty());
@@ -219,7 +219,7 @@ public class HomeWindowController extends BaseController {
@Override
public void onHidden(WindowEvent windowEvent) {
System.out.println("windowEvent = " + windowEvent);
WebSocketService webSocketService = getBean(WebSocketService.class);
WebSocketClientService webSocketService = getBean(WebSocketClientService.class);
webSocketService.closeWebSocket(); // 在窗口隐藏时关闭WebSocket连接
super.onHidden(windowEvent);
}

View File

@@ -10,6 +10,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
@@ -263,9 +264,11 @@ public class ContractVerifyWindowController extends BaseController {
viewTableDataSet.clear();
Pageable pageRequest = PageRequest.ofSize(200);
AtomicInteger counter = new AtomicInteger(0);
Map<String, Object> params = new HashMap<>();
params.put("setupDate",
ParamUtils.between(setupDateBeginSelector.getValue(), setupDateEndSelector.getValue()));
Map<String, Object> params = ParamUtils.builder().
between("setupDate", setupDateBeginSelector.getValue(), setupDateEndSelector.getValue())
.build();
long total = contractService.count(params);
setStatus("合同:" + total + "");
@@ -293,6 +296,7 @@ public class ContractVerifyWindowController extends BaseController {
model.getCode().set(contract.getCode());
model.getName().set(contract.getName());
model.getSetupDate().set(contract.getSetupDate());
comm.verify(contract, model);
setStatus("合同验证进度:" + counter.get() + " / " + total);
// 移除中间消息
@@ -332,7 +336,13 @@ public class ContractVerifyWindowController extends BaseController {
return;
}
runAsync(() -> {
Contract contract = contractService.findByCode(contractCode);
Contract contract = null;
try {
contract = contractService.findByCode(contractCode);
} catch (Exception e) {
handleException("查找合同 " + contractCode + " 时发生错误", e);
return;
}
if (contract == null) {
return;
}
@@ -369,7 +379,13 @@ public class ContractVerifyWindowController extends BaseController {
if (!StringUtils.hasText(contractCode)) {
return;
}
Contract contract = contractService.findByCode(contractCode);
Contract contract = null;
try {
contract = contractService.findByCode(contractCode);
} catch (Exception e) {
handleException("查找合同 " + contractCode + " 时发生错误", e);
return;
}
if (contract == null) {
return;
}

View File

@@ -1,23 +1,10 @@
package com.ecep.contract.controller.contract;
import java.io.File;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.ecep.contract.ContractPayWay;
import com.ecep.contract.DesktopUtils;
import com.ecep.contract.controller.AbstEntityController;
import com.ecep.contract.controller.company.CompanyWindowController;
import com.ecep.contract.controller.tab.ContractTabSkinBase;
import com.ecep.contract.controller.tab.ContractTabSkinFiles;
import com.ecep.contract.controller.tab.ContractTabSkinItemsV2;
import com.ecep.contract.controller.tab.ContractTabSkinPayPlan;
import com.ecep.contract.controller.tab.ContractTabSkinPurchaseOrders;
import com.ecep.contract.controller.tab.ContractTabSkinSaleOrders;
import com.ecep.contract.controller.tab.ContractTabSkinSubContract;
import com.ecep.contract.controller.tab.ContractTabSkinVendorBid;
import com.ecep.contract.controller.tab.*;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.Contract;
import com.ecep.contract.service.CompanyService;
@@ -27,19 +14,18 @@ import com.ecep.contract.task.ContractVerifyTasker;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.ContractViewModel;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.File;
@Lazy
@Scope("prototype")
@@ -145,8 +131,8 @@ public class ContractWindowController
ObservableList<Tab> tabs = tabPane.getTabs();
registerTabSkin(baseInfoTab, tab -> new ContractTabSkinBase(this));
switch (viewModel.getPayWay().get()) {
case RECEIVE -> {
ContractPayWay payWay = viewModel.getPayWay().get();
if (payWay == ContractPayWay.RECEIVE) {
tabs.remove(extendVendorInfo);
registerTabSkin(contractTab, t -> new ContractTabSkinSubContract(this));
tabs.remove(bidVendorTab);
@@ -154,9 +140,7 @@ public class ContractWindowController
tabs.add(saleOrderTab);
registerTabSkin(saleOrderTab, tab -> new ContractTabSkinSaleOrders(this, tab));
tabs.add(new Tab("票据"));
break;
}
case PAY -> {
} else if (payWay == ContractPayWay.PAY) {
registerTabSkin(extendVendorInfo, t -> new ContractTabSkinExtendVendorInfo(this));
tabs.remove(contractTab);
registerTabSkin(bidVendorTab, t -> new ContractTabSkinVendorBid(this));
@@ -168,8 +152,6 @@ public class ContractWindowController
tabs.add(new Tab("发货单"));
tabs.add(new Tab("签收单"));
tabs.add(new Tab("付款单"));
break;
}
}
registerTabSkin(itemTab, tab -> new ContractTabSkinItemsV2(this));

View File

@@ -9,6 +9,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
import com.ecep.contract.service.CompanyCustomerFileTypeService;
import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyCustomerFileType;
@@ -104,9 +105,9 @@ public class CustomerTabSkinFile
table.disableProperty().bind(viewModel.getPath().isEmpty());
fileTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
CompanyCustomerFileTypeService fileTypeService = getCachedBean(CompanyCustomerFileTypeService.class);
ObservableMap<CompanyCustomerFileType, CompanyCustomerFileTypeLocal> observableMapByLocal = FXCollections
.observableMap(companyCustomerFileService.getFileTypeLocalMap(getLocale()));
.observableMap(fileTypeService.findAll(getLocale()));
fileTable_typeColumn.setCellValueFactory(param -> Bindings.valueAt(observableMapByLocal,
param.getValue().getType()).map(BaseEnumEntity::getValue));
@@ -215,7 +216,6 @@ public class CustomerTabSkinFile
}
List<CompanyCustomerFile> companyCustomerFiles = new ArrayList<>();
for (File file : files) {
File dest = new File(dir, file.getName());
if (file.renameTo(dest)) {
@@ -224,12 +224,9 @@ public class CustomerTabSkinFile
ccf.setType(CompanyCustomerFileType.General);
ccf.setFilePath(dest.getAbsolutePath());
ccf.setValid(false);
companyCustomerFiles.add(ccf);
getCompanyCustomerFileService().save(ccf);
}
}
getCompanyCustomerFileService().saveAll(companyCustomerFiles);
loadTableDataSet();
}

View File

@@ -83,7 +83,7 @@ public class EmployeeTabSkinAuthBind
MenuItem menuItem = new MenuItem("导入未关联");
menuItem.setOnAction(event -> {
EmployeeAuthBindService service = getEmployeeAuthBindService();
List<EmployeeAuthBind> authBinds = service.findAllByEmployee(null, Sort.unsorted());
List<EmployeeAuthBind> authBinds = service.findAllByEmployee(null);
for (EmployeeAuthBind authBind : authBinds) {
authBind.setEmployee(getEntity());
authBind.setUpdateTime(LocalDateTime.now());

View File

@@ -1,19 +1,18 @@
package com.ecep.contract.controller.employee;
import java.util.HashMap;
import java.util.List;
import org.springframework.data.domain.Pageable;
import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.EmployeeRole;
import com.ecep.contract.service.EmployeeRoleService;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ListChangeListener;
import javafx.scene.control.ListCell;
import javafx.scene.control.Tab;
import org.springframework.data.domain.Pageable;
import java.util.HashMap;
import java.util.List;
public class EmployeeTabSkinRole
extends AbstEmployeeBasedTabSkin

View File

@@ -17,7 +17,7 @@ import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.service.EmployeeService;
import com.ecep.contract.service.ProjectService;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.vm.ProjectViewModel;
@@ -45,7 +45,7 @@ public class ApplyNewProjectWindowController extends BaseController {
@Autowired
private ProjectService projectService;
@Autowired
private SaleTypeService saleTypeService;
private ProjectSaleTypeService saleTypeService;
@Autowired
private EmployeeService employeeService;

View File

@@ -1,15 +0,0 @@
package com.ecep.contract.controller.project;
import java.util.List;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyInvoiceInfo;
import com.ecep.contract.service.ViewModelService;
import com.ecep.contract.vm.CompanyInvoiceInfoViewModel;
public class CompanyInvoiceInfoService implements ViewModelService<CompanyInvoiceInfo, CompanyInvoiceInfoViewModel> {
public List<CompanyInvoiceInfo> searchByCompany(Company company, String searchText) {
throw new UnsupportedOperationException("未实现");
}
}

View File

@@ -17,7 +17,7 @@ import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.ProductTypeService;
import com.ecep.contract.service.ProjectService;
import com.ecep.contract.service.ProjectTypeService;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.vm.ProjectViewModel;
import javafx.application.Platform;
@@ -36,7 +36,7 @@ public class ProjectManagerSkin
@Setter
private ProjectTypeService projectTypeService;
@Setter
private SaleTypeService saleTypeService;
private ProjectSaleTypeService saleTypeService;
@Setter
private ProductTypeService productTypeService;
@@ -55,9 +55,9 @@ public class ProjectManagerSkin
return companyService;
}
public SaleTypeService getSaleTypeService() {
public ProjectSaleTypeService getSaleTypeService() {
if (saleTypeService == null) {
saleTypeService = getBean(SaleTypeService.class);
saleTypeService = getBean(ProjectSaleTypeService.class);
}
return saleTypeService;
}

View File

@@ -25,7 +25,7 @@ import com.ecep.contract.service.ProductUsageService;
import com.ecep.contract.service.ProjectCostService;
import com.ecep.contract.service.ProjectIndustryService;
import com.ecep.contract.service.ProjectTypeService;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.util.UITools;
import javafx.beans.binding.Bindings;
@@ -57,7 +57,7 @@ public class ProjectTabSkinBase extends AbstProjectBasedTabSkin implements TabSk
@Setter
private ProductTypeService productTypeService;
@Setter
private SaleTypeService saleTypeService;
private ProjectSaleTypeService saleTypeService;
@Setter
private ProductUsageService productUsageService;
@Setter
@@ -96,9 +96,9 @@ public class ProjectTabSkinBase extends AbstProjectBasedTabSkin implements TabSk
return productTypeService;
}
private SaleTypeService getSaleTypeService() {
private ProjectSaleTypeService getSaleTypeService() {
if (saleTypeService == null) {
saleTypeService = getBean(SaleTypeService.class);
saleTypeService = getBean(ProjectSaleTypeService.class);
}
return saleTypeService;
}

View File

@@ -3,6 +3,7 @@ package com.ecep.contract.controller.project;
import java.util.List;
import java.util.function.BiFunction;
import com.ecep.contract.service.*;
import org.controlsfx.control.textfield.AutoCompletionBinding;
import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StringUtils;
@@ -17,10 +18,6 @@ import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.model.CompanyContact;
import com.ecep.contract.model.CompanyInvoiceInfo;
import com.ecep.contract.service.BankService;
import com.ecep.contract.service.CompanyBankAccountService;
import com.ecep.contract.service.CompanyContactService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.UITools;

View File

@@ -48,7 +48,7 @@ import com.ecep.contract.service.ProjectCostService;
import com.ecep.contract.service.ProjectIndustryService;
import com.ecep.contract.service.ProjectService;
import com.ecep.contract.service.ProjectTypeService;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.task.Tasker;
import lombok.Setter;
@@ -211,7 +211,7 @@ public class ProjectCostExportExcelTasker extends Tasker<Object> {
ProjectSaleType saleType = project.getSaleType();
if (saleType != null) {
if (!ProxyUtils.isInitialized(saleType)) {
saleType = getBean(SaleTypeService.class).findById(saleType.getId());
saleType = getBean(ProjectSaleTypeService.class).findById(saleType.getId());
project.setSaleType(saleType);
}
setCellValue(sheet, "M5", saleType.getName());

View File

@@ -2,10 +2,7 @@ package com.ecep.contract.controller.project.cost;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
import org.controlsfx.control.textfield.AutoCompletionBinding;
@@ -165,7 +162,7 @@ public class ProjectCostTabSkinItems
@Override
public Map<String, Object> getSpecification(ProjectCost parent) {
Map<String, Object> params = getSpecification();
Map<String, Object> params = new HashMap<>();
params.put("cost", parent);
return params;
}

View File

@@ -3,7 +3,7 @@ package com.ecep.contract.controller.project.sale_type;
import com.ecep.contract.controller.tab.AbstEntityBasedTabSkin;
import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.vm.ProjectSaleTypeViewModel;
public abstract class AbstProjectSaleTypeBasedTabSkin
@@ -14,7 +14,7 @@ public abstract class AbstProjectSaleTypeBasedTabSkin
super(controller);
}
public SaleTypeService getSaleTypeService() {
public ProjectSaleTypeService getSaleTypeService() {
return controller.saleTypeService;
}
}

View File

@@ -6,7 +6,7 @@ import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.controller.table.AbstEntityTableTabSkin;
import com.ecep.contract.model.IdentityEntity;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.vm.IdentityViewModel;
import com.ecep.contract.vm.ProjectSaleTypeViewModel;
@@ -18,7 +18,7 @@ public abstract class AbstProjectSaleTypeTableTabSkin<T extends IdentityEntity,
super(controller);
}
public SaleTypeService getSaleTypeService() {
public ProjectSaleTypeService getSaleTypeService() {
return controller.saleTypeService;
}

View File

@@ -9,7 +9,7 @@ import com.ecep.contract.controller.AbstEntityManagerSkin;
import com.ecep.contract.controller.ManagerSkin;
import com.ecep.contract.controller.table.EditableEntityTableTabSkin;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.service.ViewModelService;
import com.ecep.contract.vm.ProjectSaleTypeViewModel;
@@ -24,15 +24,15 @@ public class ProjectSaleTypeManagerSkin
implements ManagerSkin, EditableEntityTableTabSkin<ProjectSaleType, ProjectSaleTypeViewModel> {
@Setter
private SaleTypeService saleTypeService;
private ProjectSaleTypeService saleTypeService;
public ProjectSaleTypeManagerSkin(ProjectSaleTypeManagerWindowController controller) {
super(controller);
}
public SaleTypeService getSaleTypeService() {
public ProjectSaleTypeService getSaleTypeService() {
if (saleTypeService == null) {
saleTypeService = getBean(SaleTypeService.class);
saleTypeService = getBean(ProjectSaleTypeService.class);
}
return saleTypeService;
}

View File

@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
import com.ecep.contract.controller.AbstManagerWindowController;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.vm.ProjectSaleTypeViewModel;
@@ -24,7 +24,7 @@ public class ProjectSaleTypeManagerWindowController
extends AbstManagerWindowController<ProjectSaleType, ProjectSaleTypeViewModel, ProjectSaleTypeManagerSkin> {
@Autowired
private SaleTypeService saleTypeService;
private ProjectSaleTypeService saleTypeService;
public TableColumn<ProjectSaleTypeViewModel, Number> idColumn;
public TableColumn<ProjectSaleTypeViewModel, String> nameColumn;
@@ -51,7 +51,7 @@ public class ProjectSaleTypeManagerWindowController
@Override
public SaleTypeService getViewModelService() {
public ProjectSaleTypeService getViewModelService() {
return saleTypeService;
}
}

View File

@@ -13,7 +13,7 @@ import org.springframework.stereotype.Component;
import com.ecep.contract.ContractFileType;
import com.ecep.contract.controller.AbstEntityController;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.service.SaleTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.vm.DeliverySignMethodViewModel;
import com.ecep.contract.vm.ProjectSaleTypeViewModel;
@@ -82,7 +82,7 @@ public class ProjectSaleTypeWindowController
public TableColumn<DeliverySignMethodViewModel, LocalDate> signMethodTable_createdColumn;
@Autowired
protected SaleTypeService saleTypeService;
protected ProjectSaleTypeService saleTypeService;
@Override
public void show(Stage stage) {
@@ -98,7 +98,7 @@ public class ProjectSaleTypeWindowController
}
@Override
public SaleTypeService getViewModelService() {
public ProjectSaleTypeService getViewModelService() {
return saleTypeService;
}

View File

@@ -7,6 +7,7 @@ import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import org.controlsfx.control.textfield.TextFields;
import org.controlsfx.glyphfont.Glyph;
@@ -327,7 +328,13 @@ public class ContractTabSkinBase extends AbstContractBasedTabSkin {
public void onContractOpenMainContractAction(ActionEvent event) {
String parentCode = viewModel.getParentCode().get();
Contract parent = getContractService().findByCode(parentCode);
Contract parent = null;
try {
parent = getContractService().findByCode(parentCode);
} catch (Exception e) {
handleException("查找合同 " + parentCode + " 时发生错误", e);
return;
}
if (parent == null) {
UITools.showAlertAndWait("没有找到上级合同:" + parentCode);
return;
@@ -394,6 +401,7 @@ public class ContractTabSkinBase extends AbstContractBasedTabSkin {
// 根据上级合同设置初始目录
String parentCode = entity.getParentCode();
if (StringUtils.hasText(parentCode)) {
try {
Contract parent = getContractService().findByCode(parentCode);
if (parent != null) {
if (StringUtils.hasText(parent.getPath())) {
@@ -403,6 +411,10 @@ public class ContractTabSkinBase extends AbstContractBasedTabSkin {
}
}
}
} catch (Exception e) {
handleException("查找合同 " + parentCode + " 时发生错误", e);
return;
}
}
}
if (initialDirectory == null) {

View File

@@ -1,20 +1,21 @@
package com.ecep.contract.service;
import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.SpringApp;
import com.ecep.contract.model.*;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.CompanyCustomerFileViewModel;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.io.File;
import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.springframework.stereotype.Service;
import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerEvaluationFormFile;
import com.ecep.contract.model.CompanyCustomerFile;
import com.ecep.contract.model.CompanyCustomerFileTypeLocal;
import com.ecep.contract.vm.CompanyCustomerFileViewModel;
@Service
public class CompanyCustomerFileService extends QueryService<CompanyCustomerFile, CompanyCustomerFileViewModel> {
@@ -23,20 +24,69 @@ public class CompanyCustomerFileService extends QueryService<CompanyCustomerFile
}
public LocalDate getNextSignDate(CompanyCustomer companyCustomer, MessageHolder holder) {
throw new UnsupportedOperationException();
LocalDate miniContractDate = LocalDate.of(2022, 1, 1);
Company company = companyCustomer.getCompany();
ContractService contractService = SpringApp.getBean(ContractService.class);
Map<String, Object> params = ParamUtils.builder().equals("company", company.getId()).build();
long count = contractService.count(params);
if (count == 0) {
holder.info("未发现已登记的合同");
return null;
}
// 检索评估表
List<CompanyCustomerFile> files = findAllByCustomerAndType(companyCustomer, CompanyCustomerFileType.EvaluationForm);
CompanyCustomerFile latestFile = files.stream()
.filter(v -> v.getSignDate() != null && v.isValid())
.max(Comparator.comparing(CompanyCustomerFile::getSignDate))
.orElse(null);
if (latestFile == null) {
// 没有有效的评估表的评价日期
holder.warn("未发现有效的评估表");
// 返回最早的合同日期
Contract firstContract = contractService.findAll(params, Pageable.unpaged()).stream()
.filter(v -> v.getSetupDate() != null && !v.getSetupDate().isBefore(miniContractDate))
.min(Comparator.comparing(Contract::getSetupDate))
.orElse(null);
if (firstContract == null) {
holder.warn("最早的合同不存在?");
return null;
}
LocalDate setupDate = firstContract.getSetupDate();
holder.info("依据合同 " + firstContract.getCode() + " 的日期 " + setupDate + " 推算");
return SpringApp.getBean(HolidayService.class).adjustToWorkDay(setupDate.plusDays(-7));
}
// 检查失效日期起的第一个合同
LocalDate nextInValidDate = latestFile.getSignDate().plusYears(1);
File file = new File(latestFile.getFilePath());
holder.info("依据 " + file.getName() + " 的失效期 " + nextInValidDate + " 检索合同");
List<Contract> matchedContracts = contractService.findAll(params, Pageable.unpaged()).stream()
.filter(v -> v.getSetupDate().isAfter(nextInValidDate)).toList();
// 没有在失效日期后的合同时,使用失效日期
if (matchedContracts.isEmpty()) {
holder.info("未发现失效期 " + nextInValidDate + " 后的合同");
return null;
}
holder.info("发现匹配合同 " + matchedContracts.size() + "");
// 按时间取最早一个
Contract firstContract = matchedContracts.stream()
.min(Comparator.comparing(Contract::getSetupDate))
.orElse(null);
LocalDate setupDate = firstContract.getSetupDate();
holder.info("匹配失效期 " + nextInValidDate + " 后的第一个合同 " + firstContract.getCode() + ", 依据合同 " + firstContract.getCode() + " 的日期 " + setupDate + " 推算");
return SpringApp.getBean(HolidayService.class).adjustToWorkDay(setupDate.plusDays(-7));
}
public File getEvaluationFormTemplate() {
throw new UnsupportedOperationException();
}
public void saveAll(List<CompanyCustomerFile> companyCustomerFiles) {
throw new UnsupportedOperationException();
}
public List<CompanyCustomerFile> findAllByCustomer(CompanyCustomer companyCustomer) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllByCustomer'");
return findAll(ParamUtils.builder().equals("customer", companyCustomer).build(), Pageable.unpaged()).getContent();
}
public CompanyCustomerEvaluationFormFile findCustomerEvaluationFormFileByCustomerFile(
@@ -60,10 +110,8 @@ public class CompanyCustomerFileService extends QueryService<CompanyCustomerFile
throw new UnsupportedOperationException("Unimplemented method 'getFileTypeLocalMap'");
}
public List<CompanyCustomerFile> findAllByCustomerAndType(CompanyCustomer customer,
CompanyCustomerFileType evaluationform) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllByCustomerAndType'");
public List<CompanyCustomerFile> findAllByCustomerAndType(CompanyCustomer customer, CompanyCustomerFileType type) {
return findAll(ParamUtils.builder().equals("customer", customer.getId()).equals("type", type.name()).build(), Pageable.unpaged()).getContent();
}
public List<CompanyCustomerEvaluationFormFile> searchEvaluationFile(CompanyCustomer customer, String searchText) {

View File

@@ -0,0 +1,27 @@
package com.ecep.contract.service;
import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.model.CompanyCustomerFileTypeLocal;
import com.ecep.contract.vm.CompanyCustomerFileTypeLocalViewModel;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@CacheConfig(cacheNames = "company-file-type")
public class CompanyCustomerFileTypeService extends QueryService<CompanyCustomerFileTypeLocal, CompanyCustomerFileTypeLocalViewModel>{
@Cacheable
public Map<CompanyCustomerFileType, CompanyCustomerFileTypeLocal> findAll(Locale locale) {
Map<String, Object> params = new HashMap<>();
params.put("lang", locale.toLanguageTag());
return findAll(params, Pageable.unpaged()).stream()
.collect(Collectors.toMap(CompanyCustomerFileTypeLocal::getType, Function.identity()));
}
}

View File

@@ -1,14 +1,20 @@
package com.ecep.contract.service;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyExtendInfo;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.CompanyExtendInfoViewModel;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@Service
public class CompanyExtendInfoService extends QueryService<CompanyExtendInfo, CompanyExtendInfoViewModel> {
public CompanyExtendInfo findByCompany(Company company) {
throw new UnsupportedOperationException("Unimplemented method 'findByCompany'");
Page<CompanyExtendInfo> page = findAll(ParamUtils.equal("company", company.getId()), Pageable.ofSize(1));
if (page.isEmpty()) {
return null;
}
return page.getContent().getFirst();
}
}

View File

@@ -10,6 +10,7 @@ import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyFile;
import com.ecep.contract.model.CompanyOldName;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.CompanyFileViewModel;
import javafx.collections.ObservableList;
import org.springframework.data.domain.Pageable;
@@ -234,9 +235,41 @@ public class CompanyFileService extends QueryService<CompanyFile, CompanyFileVie
}
public void verify(Company company, LocalDate setupDate, MessageHolder holder) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'verify'");
public void verify(Company company, LocalDate verifyDate, MessageHolder holder) {
// 查询公司的资信评估报告
List<CompanyFile> files = findFileByCompanyAndType(company, CompanyFileType.CreditReport);
CompanyFile companyFile = files.stream()
.filter(v -> v.getApplyDate() != null && v.getExpiringDate() != null)
.filter(v -> MyDateTimeUtils.dateValidFilter(verifyDate, v.getApplyDate(), v.getExpiringDate(), 30))
.findFirst().orElse(null);
if (companyFile == null) {
List<LocalDate> dates = new ArrayList<>();
files.stream()
.filter(v -> v.getApplyDate() != null && !verifyDate.isBefore(v.getApplyDate()))
.max(Comparator.comparing(CompanyFile::getApplyDate))
.map(CompanyFile::getApplyDate)
.ifPresent(dates::add);
files.stream()
.filter(v -> v.getExpiringDate() != null && !verifyDate.isAfter(v.getExpiringDate()))
.min(Comparator.comparing(CompanyFile::getApplyDate))
.map(CompanyFile::getApplyDate)
.ifPresent(dates::add);
if (dates.isEmpty()) {
holder.error("未匹配到资信评估报告");
} else if (dates.size() == 1) {
holder.error("未匹配到资信评估报告, 最接近日期:" + dates.getFirst());
} else {
LocalDate localDate = dates.stream().max(LocalDate::compareTo).orElse(null);
holder.error("未匹配到资信评估报告, 最接近日期:" + localDate);
}
}
}
private List<CompanyFile> findFileByCompanyAndType(Company company, CompanyFileType companyFileType) {
return findAll(ParamUtils.builder().equals("company", company.getId()).equals("type", companyFileType).build(), Pageable.unpaged()).getContent();
}
public LocalDate getNextCreditReportDate(Company company, Consumer<String> state) {

View File

@@ -0,0 +1,23 @@
package com.ecep.contract.service;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyInvoiceInfo;
import com.ecep.contract.vm.CompanyInvoiceInfoViewModel;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class CompanyInvoiceInfoService extends QueryService<CompanyInvoiceInfo, CompanyInvoiceInfoViewModel> {
public List<CompanyInvoiceInfo> searchByCompany(Company company, String searchText) {
Map<String, Object> params = new HashMap<>();
params.put("company", company);
params.put("searchText", searchText);
return findAll(params, Pageable.unpaged()).getContent();
}
}

View File

@@ -1,12 +1,15 @@
package com.ecep.contract.service;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp;
import com.ecep.contract.constant.CompanyConstant;
import com.ecep.contract.model.Company;
import com.ecep.contract.util.FileUtils;
import com.ecep.contract.vm.CompanyViewModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@@ -18,6 +21,7 @@ import java.util.List;
import java.util.Map;
@Service
@CacheConfig(cacheNames = "company")
public class CompanyService extends QueryService<Company, CompanyViewModel> {
@Autowired
@@ -37,6 +41,11 @@ public class CompanyService extends QueryService<Company, CompanyViewModel> {
return basePath;
}
@Cacheable(key = "#p0")
public Company findById(Integer id) {
return super.findById(id);
}
public Company findByName(String name) {
List<Company> list = findAllByName(name);
if (list.isEmpty()) {
@@ -64,18 +73,45 @@ public class CompanyService extends QueryService<Company, CompanyViewModel> {
}
public boolean existsCompanyPath(Company company) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'existsCompanyPath'");
if (!StringUtils.hasText(company.getPath())) {
return false;
}
File path = new File(company.getPath());
return path.exists();
}
public boolean checkCompanyPathInBasePath(Company company) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'checkCompanyPathInBasePath'");
if (!existsCompanyPath(company)) {
return false;
}
File basePath = getBasePath();
if (basePath == null || !basePath.exists()) {
throw new IllegalArgumentException("basePath 不存在");
}
File path = new File(company.getPath());
return path.getAbsolutePath().startsWith(basePath.getAbsolutePath());
}
public void verifyEnterpriseStatus(Company company, LocalDate setupDate, MessageHolder holder) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'verifyEnterpriseStatus'");
public void verifyEnterpriseStatus(Company company, LocalDate verifyDate, MessageHolder holder) {
// 检查营业状态
String entStatus = company.getEntStatus();
if (StringUtils.hasText(entStatus)) {
if (entStatus.contains("注销")) {
LocalDate end = company.getOperationPeriodEnd();
LocalDate begin = company.getOperationPeriodBegin();
if (begin == null || end == null) {
// 注销时间未知,无法判断是否在 verifyDate 之后注销
holder.error("营业状态异常:" + entStatus);
} else {
if (!MyDateTimeUtils.dateValidFilter(verifyDate, begin, end, 0)) {
holder.error("营业状态异常:" + entStatus);
}
}
}
} else {
holder.error("营业状态异常:未设置");
}
}
public boolean makePathAbsent(Company company) {

View File

@@ -1,11 +1,15 @@
package com.ecep.contract.service;
import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.MyDateTimeUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.ecep.contract.CompanyVendorFileType;
@@ -30,4 +34,38 @@ public class CompanyVendorFileService extends QueryService<CompanyVendorFile, Co
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getFileTypeLocalMap'");
}
public void verify(CompanyVendor companyVendor, LocalDate verifyDate, MessageHolder holder) {
// 查询所有评价表
List<CompanyVendorFile> files = findAllByVendorAndType(companyVendor, CompanyVendorFileType.EvaluationForm);
if (files == null || files.isEmpty()) {
holder.error("未见供应商评价");
return;
}
// 检索 验证日期最近一年内的有效评价表日期宽限7天
LocalDate begin = verifyDate.plusYears(-1);
CompanyVendorFile vendorFile = files.stream()
.filter(v -> v.getSignDate() != null && v.isValid())
.filter(v -> MyDateTimeUtils.dateValidFilter(v.getSignDate(), begin, verifyDate, 7))
.findFirst().orElse(null);
if (vendorFile == null) {
// 检索最后一个有效评价表
CompanyVendorFile latestFile = files.stream()
.filter(v -> v.getSignDate() != null && v.isValid())
.max(Comparator.comparing(CompanyVendorFile::getSignDate))
.orElse(null);
if (latestFile == null) {
holder.error("未匹配的供应商评价");
return;
}
// 提示评价表已过期
holder.error("供应商评价已过期:" + latestFile.getSignDate() + ", 检测日期:" + verifyDate);
}
}
public List<CompanyVendorFile> findAllByVendorAndType(CompanyVendor vendor, CompanyVendorFileType type) {
return findAll(Map.of("vendor", vendor.getId(), "type", type.name()), Pageable.unpaged()).getContent();
}
}

View File

@@ -0,0 +1,12 @@
package com.ecep.contract.service;
import com.ecep.contract.model.CompanyVendorFileTypeLocal;
import com.ecep.contract.vm.CompanyVendorFileTypeLocalViewModel;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
@Service
@CacheConfig(cacheNames = "vendor-file-type")
public class CompanyVendorFileTypeService extends QueryService<CompanyVendorFileTypeLocal, CompanyVendorFileTypeLocalViewModel> {
}

View File

@@ -1,18 +1,30 @@
package com.ecep.contract.service;
import java.io.File;
import java.time.LocalDate;
import java.util.*;
import com.ecep.contract.VendorType;
import com.ecep.contract.model.*;
import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.ProxyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.vm.CompanyVendorViewModel;
import org.springframework.util.StringUtils;
@Service
public class CompanyVendorService extends QueryService<CompanyVendor, CompanyVendorViewModel> {
@Autowired
private CompanyService companyService;
@Autowired
private CompanyFileService companyFileService;
@Autowired
private CompanyVendorFileService companyVendorFileService;
public VendorCatalog findCatalogById(Integer id) {
// TODO Auto-generated method stub
@@ -35,8 +47,70 @@ public class CompanyVendorService extends QueryService<CompanyVendor, CompanyVen
}
public void verify(Contract contract, MessageHolder holder) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'verify'");
Company company = contract.getCompany();
if (company == null) {
holder.error("合同未关联公司");
return;
}
CompanyVendor companyVendor = findByCompany(company);
if (companyVendor == null) {
holder.error("合同未关联供应商");
return;
}
if (companyVendor.getType() == null) {
holder.error("供应商未设置类型");
return;
}
VendorType vendorType = companyVendor.getType();
if (vendorType == VendorType.UNQUALIFIED) {
holder.error("不合格供应商");
return;
}
if (vendorType == VendorType.QUALIFIED) {
holder.debug(VendorType.QUALIFIED.name());
return;
}
if (vendorType == VendorType.TYPICALLY) {
if (verifyAsTypicallyVendor(companyVendor, contract.getSetupDate(), holder)) {
return;
}
}
companyFileService.verify(company, contract.getSetupDate(), holder);
companyVendorFileService.verify(companyVendor, contract.getSetupDate(), holder);
}
private boolean verifyAsTypicallyVendor(CompanyVendor companyVendor, LocalDate verifyDate, MessageHolder holder) {
boolean valid = false;
Company company = companyVendor.getCompany();
if (!ProxyUtils.isInitialized(company)) {
company = companyService.findById(company.getId());
}
// 检查营业状态
String entStatus = company.getEntStatus();
if (StringUtils.hasText(entStatus)) {
if (entStatus.contains("注销")) {
holder.error("营业状态异常:" + entStatus + ", 自动设置为不合格");
companyVendor.setType(VendorType.UNQUALIFIED);
companyVendor.setDescription(MyStringUtils.appendIfAbsent(companyVendor.getDescription(), "自动检测到营业状态为" + entStatus + ",设置为不合格供应商."));
valid = true;
}
} else {
holder.error("营业状态异常:" + entStatus);
valid = true;
}
if (!StringUtils.hasText(companyVendor.getPurchase())) {
holder.error("未设置采购的产品");
valid = true;
}
if (!StringUtils.hasText(companyVendor.getPath())) {
holder.error("未设置文件夹");
valid = true;
}
return valid;
}
public List<VendorTypeLocal> findAllTypes(Locale locale) {

View File

@@ -2,6 +2,8 @@ package com.ecep.contract.service;
import java.util.List;
import com.ecep.contract.util.ParamUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.Company;
@@ -13,13 +15,16 @@ import com.ecep.contract.vm.ContractBidVendorViewModel;
public class ContractBidVendorService extends QueryService<ContractBidVendor, ContractBidVendorViewModel> {
public List<ContractBidVendor> findByContract(Contract contract) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByContract'");
return findAll(ParamUtils.builder()
.equals("contract", contract.getId())
.build(), Pageable.unpaged()).getContent();
}
public List<ContractBidVendor> findByContractAndCompany(Contract contract, Company company) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByContractAndCompany'");
return findAll(ParamUtils.builder()
.equals("contract", contract.getId())
.equals("company", company.getId())
.build(), Pageable.unpaged()).getContent();
}
}

View File

@@ -1,29 +1,46 @@
package com.ecep.contract.service;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.constant.CompanyConstant;
import com.ecep.contract.constant.ContractConstant;
import com.ecep.contract.model.*;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.ContractViewModel;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.io.File;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractFile;
import com.ecep.contract.model.Project;
import com.ecep.contract.vm.ContractViewModel;
import io.micrometer.common.util.StringUtils;
import java.util.concurrent.ExecutionException;
@Service
@CacheConfig(cacheNames = "contract")
public class ContractService extends QueryService<Contract, ContractViewModel> {
@Autowired
private SysConfService confService;
private File basePath;
/**
* 返回合同的基础目录
*
* @return 合同的基础目录
*/
public File getBasePath() {
if (basePath == null) {
basePath = new File(confService.getString(ContractConstant.KEY_BASE_PATH));
}
return basePath;
}
@Cacheable(key = "#p0")
public Contract findById(Integer id) {
@@ -55,13 +72,30 @@ public class ContractService extends QueryService<Contract, ContractViewModel> {
}
@Cacheable(key = "'code-'+#p0")
public Contract findByCode(String string) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByCode'");
public Contract findByCode(String code) {
try {
return async("findByCode", code, String.class).handle((response, ex) -> {
if (response != null) {
return updateValue(new Contract(), response);
}
return null;
}).get();
} catch (Exception e) {
throw new RuntimeException("查找合同 " + code + " 时发生错误", e);
}
}
public Contract findByName(String name) {
throw new UnsupportedOperationException("Unimplemented method 'findByName'");
try {
return async("findByName", name, String.class).handle((response, ex) -> {
if (response != null) {
return updateValue(new Contract(), response);
}
return null;
}).get();
} catch (Exception e) {
throw new RuntimeException("查找合同 " + name + " 时发生错误", e);
}
}
public List<Contract> findAllBySaleContract(Contract contract) {
@@ -69,19 +103,28 @@ public class ContractService extends QueryService<Contract, ContractViewModel> {
if (StringUtils.isEmpty(parentCode)) {
return List.of();
}
HashMap<String, Object> params = new HashMap<>();
params.put("parentCode", contract.getCode());
return findAll(params, Pageable.unpaged()).getContent();
return findAll(ParamUtils.equal("parentCode", parentCode), Pageable.unpaged()).getContent();
}
public boolean checkContractPathInBasePath(Contract v) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'checkContractPathInBasePath'");
if (!existsContractPath(v)) {
return false;
}
File basePath = getBasePath();
if (basePath == null || !basePath.exists()) {
throw new IllegalArgumentException("basePath 不存在");
}
File path = new File(v.getPath());
return path.getAbsolutePath().startsWith(basePath.getAbsolutePath());
}
public boolean existsContractPath(Contract v) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'existsContractPath'");
if (!org.springframework.util.StringUtils.hasText(v.getPath())) {
return false;
}
File path = new File(v.getPath());
return path.exists();
}
public boolean makePathAbsent(Contract contract) {
@@ -89,29 +132,37 @@ public class ContractService extends QueryService<Contract, ContractViewModel> {
throw new UnsupportedOperationException("Unimplemented method 'makePathAbsent'");
}
public List<Contract> findAllByCompanyVendor(CompanyVendor vendor, LocalDate miniDate, LocalDate date) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllByCompanyVendor'");
public List<Contract> findAllByCompanyVendor(CompanyVendor vendor, LocalDate beginDate, LocalDate endDate) {
Company company = vendor.getCompany();
return findAll(ParamUtils.builder()
.equals("company", company.getId())
.between("setupDate", beginDate, endDate)
.build(), Pageable.unpaged()).getContent();
}
public Contract[] findAllSalesByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllSalesByProject'");
public List<Contract> findAllSalesByProject(Project project) {
HashMap<String, Object> params = new HashMap<>();
params.put("parentCode", "");
params.put("project", project.getId());
return findAll(params, Pageable.unpaged()).getContent();
}
public Contract findSalesByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findSalesByProject'");
HashMap<String, Object> params = new HashMap<>();
params.put("parentCode", "");
params.put("project", project.getId());
Page<Contract> page = findAll(params, Pageable.ofSize(1));
if (page.isEmpty()) {
return null;
}
return page.getContent().getFirst();
}
public File getBasePath() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getBasePath'");
}
public List<Contract> findAllByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllByProject'");
HashMap<String, Object> params = new HashMap<>();
params.put("project", project.getId());
return findAll(params, Pageable.unpaged()).getContent();
}
public void syncContractFile(ContractFile contractFile, File outputFile, MessageHolder holder) {

View File

@@ -1,19 +1,22 @@
package com.ecep.contract.service;
import java.util.List;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.EmployeeAuthBind;
import com.ecep.contract.vm.EmployeeAuthBindViewModel;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class EmployeeAuthBindService extends QueryService<EmployeeAuthBind, EmployeeAuthBindViewModel> {
public List<EmployeeAuthBind> findAllByEmployee(Object object, Sort unsorted) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllByEmployee'");
public List<EmployeeAuthBind> findAllByEmployee(Employee employee) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("employee", null);
return findAll(params, Pageable.unpaged()).getContent();
}
}

View File

@@ -1,12 +1,15 @@
package com.ecep.contract.service;
import java.util.List;
import org.springframework.stereotype.Service;
import com.ecep.contract.PageContent;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.EmployeeRole;
import com.ecep.contract.vm.EmployeeViewModel;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
@Service
public class EmployeeService extends QueryService<Employee, EmployeeViewModel> {
@@ -19,14 +22,33 @@ public class EmployeeService extends QueryService<Employee, EmployeeViewModel> {
}
public List<EmployeeRole> getRolesByEmployeeId(Integer id) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getRolesByEmployeeId'");
try {
return async("getRolesByEmployeeId", List.of(id), List.of(Integer.class)).handle((response, ex) -> {
if (response != null) {
try {
List<EmployeeRole> content = new ArrayList<>();
for (JsonNode node : response) {
EmployeeRole newEntity = new EmployeeRole();
objectMapper.updateValue(newEntity, node);
content.add(newEntity);
}
return content;
} catch (Exception e) {
throw new RuntimeException(response.toString(), e);
}
}
return null;
}).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
public void updateActive(int sessionId) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'updateActive'");
}
public Employee findByCode(String personCode) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByCode'");

View File

@@ -1,21 +1,48 @@
package com.ecep.contract.service;
import com.ecep.contract.util.ParamUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ExtendVendorInfo;
import com.ecep.contract.vm.ExtendVendorInfoViewModel;
import org.springframework.util.StringUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
public class ExtendVendorInfoService extends QueryService<ExtendVendorInfo, ExtendVendorInfoViewModel> {
@Autowired
private VendorGroupService vendorGroupService;
public ExtendVendorInfo findByContract(Contract contract) {
throw new UnsupportedOperationException("Unimplemented method 'findByContract'");
Page<ExtendVendorInfo> page = findAll(ParamUtils.builder().equals("contract", contract).build(), Pageable.ofSize(1));
if (page.isEmpty()) {
return null;
}
return page.getContent().getFirst();
}
public ExtendVendorInfo newInstanceByContract(Contract contract) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'newInstanceByContract'");
ExtendVendorInfo info = new ExtendVendorInfo();
info.setContract(contract);
if (StringUtils.hasText(contract.getCode())) {
String regex = "-([A-Z]{1,4})(\\d{1,4})";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(contract.getCode());
if (matcher.find()) {
info.setGroup(vendorGroupService.findByCode(matcher.group(1)));
info.setCodeSequenceNumber(Integer.parseInt(matcher.group(2)));
}
}
info.setAssignedProvider(false);
info.setPrePurchase(false);
return info;
}
}

View File

@@ -0,0 +1,15 @@
package com.ecep.contract.service;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
@Lazy
@Service
public class HolidayService {
public LocalDate adjustToWorkDay(LocalDate date) {
throw new RuntimeException("Not implemented");
}
}

View File

@@ -2,6 +2,11 @@ package com.ecep.contract.service;
import java.util.List;
import com.ecep.contract.util.ParamUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import com.ecep.contract.MessageHolder;
@@ -13,18 +18,29 @@ import com.ecep.contract.vm.ProjectCostViewModel;
public class ProjectCostService extends QueryService<ProjectCost, ProjectCostViewModel> {
public ProjectCost findAutoCostByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAutoCostByProject'");
Page<ProjectCost> page = findAll(ParamUtils.builder().equals("project", project.getId()).build(), Pageable.unpaged());
if (page.isEmpty()) {
return null;
}
return page.getContent().getFirst();
}
public ProjectCost newInstanceByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'newInstanceByProject'");
ProjectCost cost = new ProjectCost();
cost.setProject(project);
// 0.3‰:购销合同、建筑安装工程承包合同、技术合同
cost.setStampTax(0.03f);
cost.setTaxAndSurcharges(11f);
return cost;
}
public ProjectCost findLatestByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findLatestByProject'");
PageRequest pageRequest = PageRequest.of(0, 1, Sort.Direction.DESC, "version");
Page<ProjectCost> page = findAll(ParamUtils.builder().equals("project", project.getId()).build(), pageRequest);
if (page.isEmpty()) {
return null;
}
return page.getContent().getFirst();
}
public void updateAutoCost(Project project, MessageHolder holder) {
@@ -33,8 +49,7 @@ public class ProjectCostService extends QueryService<ProjectCost, ProjectCostVie
}
public List<ProjectCost> findAllByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllByProject'");
return findAll(ParamUtils.builder().equals("project", project.getId()).build(), Pageable.unpaged()).getContent();
}
}

View File

@@ -1,19 +1,19 @@
package com.ecep.contract.service;
import java.util.List;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectQuotation;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.ProjectQuotationViewModel;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProjectQuotationService extends QueryService<ProjectQuotation, ProjectQuotationViewModel> {
public List<ProjectQuotation> findAllByProject(Project project) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAllByProject'");
return findAll(ParamUtils.builder().equals("project", project.getId()).build(), Pageable.unpaged()).getContent();
}
}

View File

@@ -2,6 +2,8 @@ package com.ecep.contract.service;
import java.util.List;
import com.ecep.contract.util.ParamUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.ProjectSaleTypeRequireFileType;
@@ -12,8 +14,7 @@ public class ProjectSaleTypeRequireFileTypeService
extends QueryService<ProjectSaleTypeRequireFileType, ProjectSaleTypeRequireFileTypeViewModel> {
public List<ProjectSaleTypeRequireFileType> findBySaleTypeId(Integer id) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findBySaleTypeId'");
return findAll(ParamUtils.equal("fileType", id), Pageable.unpaged()).getContent();
}
}

View File

@@ -1,16 +1,19 @@
package com.ecep.contract.service;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.ProjectSaleTypeViewModel;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@Service
public class ProjectSaleTypeService extends QueryService<ProjectSaleType, ProjectSaleTypeViewModel> {
public ProjectSaleType findByCode(String substring) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByCode'");
public ProjectSaleType findByCode(String code) {
return findAll(ParamUtils.builder().equals("code", code).build(), Pageable.ofSize(1)).getContent().getFirst();
}
public ProjectSaleType findByName(String name) {
return findAll(ParamUtils.builder().equals("name", name).build(), Pageable.ofSize(1)).getContent().getFirst();
}
}

View File

@@ -2,14 +2,15 @@ package com.ecep.contract.service;
import com.ecep.contract.PageArgument;
import com.ecep.contract.PageContent;
import com.ecep.contract.WebSocketService;
import com.ecep.contract.WebSocketClientService;
import com.ecep.contract.model.IdentityEntity;
import com.ecep.contract.msg.SimpleMessage;
import com.ecep.contract.vm.IdentityViewModel;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -19,13 +20,15 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;
public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel<T>>
implements ViewModelService<T, TV> {
// 添加日志记录器
private static final Logger logger = LoggerFactory.getLogger(QueryService.class);
@Autowired
protected WebSocketService webSocketService;
protected WebSocketClientService webSocketService;
@Autowired
protected ObjectMapper objectMapper;
@@ -61,56 +64,60 @@ public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel
@Override
public T save(T entity) {
SimpleMessage msg = new SimpleMessage();
msg.setService(getBeanName());
msg.setMethod("save");
msg.setArguments(entity);
try {
Object response = webSocketService.send(msg).get(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS);
return async("save", entity, entity.getClass().getName()).handle((response, ex) -> {
if (response != null) {
try {
objectMapper.updateValue(entity, response);
} catch (JsonMappingException e) {
throw new RuntimeException(e);
}
} catch (Exception e) {
e.printStackTrace();
}
return entity;
}).get();
} catch (Exception e) {
throw new RuntimeException("保存实体失败", e);
}
}
@Override
public void delete(T entity) {
SimpleMessage msg = new SimpleMessage();
msg.setService(getBeanName());
msg.setMethod("delete");
msg.setArguments(entity);
try {
JsonNode response = webSocketService.send(msg).get(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS);
async("delete", entity, entity.getClass().getName()).handle((response, ex) -> {
if (response != null) {
objectMapper.updateValue(entity, response);
return updateValue(entity, response);
}
return null;
}).get();
} catch (Exception e) {
e.printStackTrace();
logger.error("删除实体失败 #{}", entity.getId(), e);
throw new RuntimeException("删除实体失败", e);
}
}
public CompletableFuture<T> asyncFindById(Integer id) {
SimpleMessage msg = new SimpleMessage();
msg.setService(getBeanName());
msg.setMethod("findById");
msg.setArguments(id);
return webSocketService.send(msg).orTimeout(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS).handle((response, ex) -> {
if (ex != null) {
return null;
}
if (response == null) {
return null;
}
T newEntity = createNewEntity();
public T updateValue(T entity, JsonNode node) {
try {
objectMapper.updateValue(newEntity, response);
objectMapper.updateValue(entity, node);
} catch (JsonMappingException e) {
throw new RuntimeException(response.toString(), e);
throw new RuntimeException(e);
}
return newEntity;
return entity;
}
public CompletableFuture<JsonNode> async(String method, Object... params) {
return webSocketService.invoke(getBeanName(), method, params).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+" + method + "+调用失败", ex);
}
return response;
});
}
public CompletableFuture<T> asyncFindById(Integer id) {
return async("findById", id, Integer.class).handle((response, ex) -> {
T newEntity = createNewEntity();
return updateValue(newEntity, response);
});
}
@@ -119,45 +126,77 @@ public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel
try {
return asyncFindById(id).get();
} catch (Exception e) {
e.printStackTrace();
logger.error("查询实体失败 #{}", id, e);
throw new RuntimeException("查询实体失败", e);
}
return null;
}
public List<T> findAll() {
return findAll(null, Pageable.unpaged()).getContent();
}
/**
* 异步查询所有实体数据返回CompletableFuture对象
*
* @param params 查询参数映射表,可以包含过滤条件等信息
* @param pageable 分页参数,包含页码、每页条数、排序规则等
* @return 包含分页结果的CompletableFuture对象
*/
public CompletableFuture<Page<T>> asyncFindAll(Map<String, Object> params, Pageable pageable) {
SimpleMessage msg = new SimpleMessage();
msg.setService(getBeanName());
msg.setMethod("findAll");
msg.setArguments(params, PageArgument.of(pageable));
return webSocketService.send(msg).orTimeout(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS).handle((response, ex) -> {
if (ex != null) {
return null;
}
if (response == null) {
return null;
}
// 调用async方法发送WebSocket请求获取异步响应结果
return async("findAll", params, PageArgument.of(pageable)).handle((response, ex) -> {
try {
// 将响应结果转换为PageContent对象使用当前类的createNewEntity方法创建实体实例
PageContent<T> pageContent = of(response, objectMapper, this::createNewEntity);
// 将PageContent转换为Spring Data的Page对象并返回
return pageContent.toPage();
} catch (Exception e) {
// 处理转换过程中的异常包装为RuntimeException并附带响应内容
throw new RuntimeException(response.toString(), e);
}
});
}
/**
* 同步查询所有实体数据实现了ViewModelService接口的findAll方法
*
* @param params 查询参数映射表,可以包含过滤条件等信息
* @param pageable 分页参数,包含页码、每页条数、排序规则等
* @return 包含查询结果的Page对象
* @throws RuntimeException 当查询失败时抛出异常
*/
@Override
public Page<T> findAll(Map<String, Object> params, Pageable pageable) {
try {
// 调用异步方法并阻塞等待结果返回
return asyncFindAll(params, pageable).get();
} catch (Exception e) {
e.printStackTrace();
// 处理异步查询过程中的任何异常,转换为运行时异常抛出
throw new RuntimeException("查询所有实体失败", e);
}
}
/**
* 异步执行计数操作返回CompletableFuture<Long>类型结果
*
* @param params 包含计数所需参数的Map集合
* @return 返回一个CompletableFuture<Long>对象,用于获取异步操作的结果
*/
public CompletableFuture<Long> asyncCount(Map<String, Object> params) {
// 调用async方法执行名为"count"的异步操作传入参数params
// 使用handle方法处理异步操作的结果或异常
return async("count", params).handle((response, ex) -> {
// 将响应结果转换为Long类型并返回
return response.asLong();
});
}
public long count(Map<String, Object> params) {
try {
return asyncCount(params).get();
} catch (Exception e) {
throw new RuntimeException("计数失败", e);
}
return null;
}
public List<T> search(String searchText) {

View File

@@ -1,16 +0,0 @@
package com.ecep.contract.service;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.vm.ProjectSaleTypeViewModel;
@Service
public class SaleTypeService extends QueryService<ProjectSaleType, ProjectSaleTypeViewModel> {
public ProjectSaleType findByName(String name) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByName'");
}
}

View File

@@ -2,9 +2,8 @@ package com.ecep.contract.service;
import com.ecep.contract.PageArgument;
import com.ecep.contract.PageContent;
import com.ecep.contract.WebSocketService;
import com.ecep.contract.WebSocketClientService;
import com.ecep.contract.model.SysConf;
import com.ecep.contract.msg.SimpleMessage;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
@@ -18,27 +17,19 @@ import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@Service
@CacheConfig(cacheNames = "sys_conf")
public class SysConfService {
@Autowired
protected WebSocketService webSocketService;
protected WebSocketClientService webSocketService;
@Autowired
protected ObjectMapper objectMapper;
public CompletableFuture<SysConf> asyncFindById(String id) {
SimpleMessage msg = new SimpleMessage();
msg.setService(getBeanName());
msg.setMethod("findById");
msg.setArguments(id);
return webSocketService.send(msg).orTimeout(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS).handle((response, ex) -> {
return webSocketService.invoke(getBeanName(), "findById", id).handle((response, ex) -> {
if (ex != null) {
return null;
}
if (response == null) {
return null;
throw new RuntimeException("远程方法+findById+调用失败", ex);
}
SysConf newEntity = new SysConf();
try {
@@ -60,16 +51,9 @@ public class SysConfService {
}
public CompletableFuture<Page<SysConf>> asyncFindAll(Map<String, Object> params, Pageable pageable) {
SimpleMessage msg = new SimpleMessage();
msg.setService(getBeanName());
msg.setMethod("findAll");
msg.setArguments(params, PageArgument.of(pageable));
return webSocketService.send(msg).orTimeout(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS).handle((response, ex) -> {
return webSocketService.invoke(getBeanName(), "findAll", params, PageArgument.of(pageable)).handle((response, ex) -> {
if (ex != null) {
return null;
}
if (response == null) {
return null;
throw new RuntimeException("远程方法+findAll+调用失败", ex);
}
try {
PageContent<SysConf> pageContent = QueryService.of(response, objectMapper, SysConf::new);
@@ -163,20 +147,23 @@ public class SysConfService {
@CacheEvict(key = "#p0.id")
public SysConf save(SysConf entity) {
SimpleMessage msg = new SimpleMessage();
msg.setService(getBeanName());
msg.setMethod("save");
msg.setArguments(entity);
try {
Object response = webSocketService.send(msg).get(webSocketService.getReadTimeout(), TimeUnit.MILLISECONDS);
if (response != null) {
objectMapper.updateValue(entity, response);
return webSocketService.invoke(getBeanName(), "save", entity).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+save+调用失败", ex);
}
if (response != null) {
try {
objectMapper.updateValue(entity, response);
} catch (JsonMappingException e) {
throw new RuntimeException(e);
}
} catch (Exception e) {
e.printStackTrace();
}
return entity;
}).get();
} catch (Exception e) {
throw new RuntimeException("保存实体失败", e);
}
}
public String getBeanName() {

View File

@@ -1,7 +1,9 @@
package com.ecep.contract.service;
import java.util.List;
import java.util.Map;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.ecep.contract.model.VendorGroupRequireFileType;
@@ -12,8 +14,7 @@ public class VendorGroupRequireFileTypeService
extends QueryService<VendorGroupRequireFileType, VendorGroupRequireFileTypeViewModel> {
public List<VendorGroupRequireFileType> findByGroupId(Integer id) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findByGroupId'");
return findAll(Map.of("group", id), Pageable.unpaged()).getContent();
}
}

View File

@@ -9,8 +9,26 @@ import com.ecep.contract.vm.VendorGroupViewModel;
public class VendorGroupService extends QueryService<VendorGroup, VendorGroupViewModel> {
public VendorGroup newInstance() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'newInstance'");
VendorGroup group = new VendorGroup();
group.setCode("");
group.setName("");
group.setDescription("");
group.setActive(true);
group.setPriceComparison(true);
group.setRequireQuotationSheetForBid(true);
group.setCanPrePurchase(false);
return group;
}
public VendorGroup findByCode(String code) {
try {
return async("findByCode", code, String.class).handle((response, ex) -> {
VendorGroup newEntity = newInstance();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败", e);
}
}
}

View File

@@ -92,7 +92,6 @@ public interface ViewModelService<T extends IdentityEntity, TV extends IdentityV
}
default void delete(T entity) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'delete'");
}
@@ -102,12 +101,10 @@ public interface ViewModelService<T extends IdentityEntity, TV extends IdentityV
}
default Page<T> findAll(Map<String, Object> params, Pageable pageable) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'findAll'");
}
default long count(Map<String, Object> params) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'count'");
}

View File

@@ -1,15 +1,19 @@
package com.ecep.contract.task;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.SpringApp;
import com.ecep.contract.WebSocketClientService;
import com.ecep.contract.WebSocketClientTasker;
import com.ecep.contract.model.Contract;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Getter;
import lombok.Setter;
/**
*
*/
public class ContractRepairTask extends Tasker<Object> {
public class ContractRepairTask extends Tasker<Object> implements WebSocketClientTasker {
@Getter
@Setter
private Contract contract;
@@ -28,11 +32,35 @@ public class ContractRepairTask extends Tasker<Object> {
public ContractRepairTask() {
}
@Override
public String getTaskName() {
return "ContractRepairTask";
}
@Override
public void updateProgress(long current, long total) {
super.updateProgress(current, total);
}
@Override
protected Object execute(MessageHolder holder) throws Exception {
updateTitle("修复合同 " + contract.toPrettyString());
updateProgress(1, 1);
return callRemoteTask(holder);
}
private Object callRemoteTask(MessageHolder holder) {
WebSocketClientService webSocketService = SpringApp.getBean(WebSocketClientService.class);
webSocketService.withSession(session -> {
try {
session.submitTask(this, contract.getId(), getLocale().toLanguageTag());
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
});
return null;
}
}

View File

@@ -1,19 +1,55 @@
package com.ecep.contract.task;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.SpringApp;
import com.ecep.contract.WebSocketClientTasker;
import com.ecep.contract.WebSocketClientService;
import com.ecep.contract.service.YongYouU8Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ecep.contract.MessageHolder;
/**
* 合同同步任务
*/
public class ContractSyncTask extends Tasker<Object> {
public class ContractSyncTask extends Tasker<Object> implements WebSocketClientTasker {
private static final Logger logger = LoggerFactory.getLogger(ContractSyncTask.class);
private YongYouU8Service yongYouU8Service;
private YongYouU8Service getYongYouU8Service() {
if (yongYouU8Service == null) {
yongYouU8Service = SpringApp.getBean(YongYouU8Service.class);
}
return yongYouU8Service;
}
public String getTaskName() {
return "ContractSyncTask";
}
@Override
public void updateProgress(long current, long total) {
super.updateProgress(current, total);
}
@Override
protected Object execute(MessageHolder holder) throws Exception {
updateTitle("用友U8系统-同步合同");
return callRemoteTask(holder);
}
private Object callRemoteTask(MessageHolder holder) {
WebSocketClientService webSocketService = SpringApp.getBean(WebSocketClientService.class);
webSocketService.withSession(session -> {
try {
session.submitTask(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
});
return null;
}

View File

@@ -13,6 +13,7 @@ import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;
import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyCustomerFileType;
@@ -311,6 +312,12 @@ public class ContractVerifyComm {
}
CompanyExtendInfo companyExtendInfo = getCompanyExtendInfoService().findByCompany(company);
if (companyExtendInfo == null) {
CompanyExtendInfo extendInfo = new CompanyExtendInfo();
extendInfo.setCompany(company);
extendInfo.setDisableVerify(false);
companyExtendInfo = getCompanyExtendInfoService().save(extendInfo);
}
if (companyExtendInfo.isDisableVerify()) {
holder.debug("公司设定不做校验");
@@ -555,6 +562,9 @@ public class ContractVerifyComm {
verifyProject(contract, project, holder.sub("项目"));
ProjectSaleType saleType = project.getSaleType();
if (!ProxyUtils.isInitialized(saleType)) {
saleType = getSaleTypeService().findById(saleType.getId());
}
if (saleType != null) {
if (getContractService().existsContractPath(contract)) {
saleType = getSaleTypeService().findById(saleType.getId());

View File

@@ -1,12 +1,5 @@
package com.ecep.contract.task;
import java.util.Locale;
import java.util.logging.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import com.ecep.contract.Desktop;
import com.ecep.contract.Message;
import com.ecep.contract.MessageHolder;
@@ -15,12 +8,17 @@ import com.ecep.contract.model.Employee;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.EmployeeService;
import com.ecep.contract.service.SysConfService;
import javafx.application.Platform;
import javafx.beans.property.StringProperty;
import javafx.concurrent.Task;
import javafx.scene.control.ListCell;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import java.util.Locale;
import java.util.logging.Level;
public abstract class Tasker<T> extends Task<T> {
private static final Logger logger = LoggerFactory.getLogger(Tasker.class);
@@ -86,7 +84,7 @@ public abstract class Tasker<T> extends Task<T> {
updateMessage(Level.INFO, message);
}
protected void updateMessage(Level level, String message) {
public void updateMessage(Level level, String message) {
if (messageHandler != null) {
if (messageHandler.test(new Message(level, message))) {
return;
@@ -95,6 +93,10 @@ public abstract class Tasker<T> extends Task<T> {
super.updateMessage(message);
}
public void updateTitle(String title) {
super.updateTitle(title);
}
protected void skipUpdateCheckUpdateMessage(String message) {
if (Platform.isFxApplicationThread()) {
((StringProperty) messageProperty()).set(message);
@@ -172,4 +174,5 @@ public abstract class Tasker<T> extends Task<T> {
public Locale getLocale() {
return Desktop.instance.getActiveEmployee().localeProperty().get();
}
}

View File

@@ -6,23 +6,15 @@ import java.util.Map;
import java.util.Objects;
public class ParamUtils {
public static Map<String, Object> between(LocalDate begin, LocalDate end) {
Map<String, Object> params = new HashMap<>();
params.put("begin", begin);
params.put("end", end);
return params;
public static Map<String, Object> between(String key, LocalDate begin, LocalDate end) {
return Map.of(key, Map.of(
"begin", begin,
"end", end
));
}
public static Map<String, Object> equal(String key, boolean value) {
Map<String, Object> params = new HashMap<>();
params.put(key, value);
return params;
}
public static Map<String, Object> equal(String key, String value) {
Map<String, Object> params = new HashMap<>();
params.put(key, value);
return params;
public static Map<String, Object> equal(String key, Object value) {
return Map.of(key, value);
}
public static Map<String, Object> like(String key, String value) {
@@ -70,7 +62,7 @@ public class ParamUtils {
}
public Builder equals(String key, Object value) {
params.put(key, Map.of("equals", value));
params.put(key, value);
return this;
}

View File

@@ -0,0 +1,12 @@
package com.ecep.contract.vm;
import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.model.CompanyCustomerFileTypeLocal;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class CompanyCustomerFileTypeLocalViewModel extends EnumViewModel<CompanyCustomerFileType, CompanyCustomerFileTypeLocal> {
}

View File

@@ -0,0 +1,13 @@
package com.ecep.contract.vm;
import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.CompanyVendorFileType;
import com.ecep.contract.model.CompanyCustomerFileTypeLocal;
import com.ecep.contract.model.CompanyVendorFileTypeLocal;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class CompanyVendorFileTypeLocalViewModel extends EnumViewModel<CompanyVendorFileType, CompanyVendorFileTypeLocal> {
}

View File

@@ -12,40 +12,22 @@ import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class ContractFileTypeLocalViewModel extends IdentityViewModel<ContractFileTypeLocal> {
private SimpleObjectProperty<ContractFileType> type = new SimpleObjectProperty<>();
public class ContractFileTypeLocalViewModel extends EnumViewModel<ContractFileType, ContractFileTypeLocal> {
private SimpleStringProperty suggestFileName = new SimpleStringProperty();
private SimpleStringProperty lang = new SimpleStringProperty();
private SimpleStringProperty value = new SimpleStringProperty();
@Override
protected void updateFrom(ContractFileTypeLocal v) {
super.updateFrom(v);
type.set(v.getType());
suggestFileName.set(v.getSuggestFileName());
lang.set(v.getLang());
value.set(v.getValue());
}
@Override
public boolean copyTo(ContractFileTypeLocal v) {
boolean ret = super.copyTo(v);
if (!Objects.equals(type.get(), v.getType())) {
v.setType(type.get());
ret = true;
}
if (!Objects.equals(suggestFileName.get(), v.getSuggestFileName())) {
v.setSuggestFileName(suggestFileName.get());
ret = true;
}
if (!Objects.equals(lang.get(), v.getLang())) {
v.setLang(lang.get());
ret = true;
}
if (!Objects.equals(value.get(), v.getValue())) {
v.setValue(value.get());
ret = true;
}
return ret;
}
}

View File

@@ -0,0 +1,43 @@
package com.ecep.contract.vm;
import com.ecep.contract.model.BaseEnumEntity;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Objects;
@Data
@EqualsAndHashCode(callSuper = true)
public class EnumViewModel<K extends Enum<?>, T extends BaseEnumEntity<K>> extends IdentityViewModel<T> {
private SimpleObjectProperty<K> type = new SimpleObjectProperty<>();
private SimpleStringProperty lang = new SimpleStringProperty();
private SimpleStringProperty value = new SimpleStringProperty();
@Override
protected void updateFrom(T v) {
super.updateFrom(v);
type.set(v.getType());
lang.set(v.getLang());
value.set(v.getValue());
}
@Override
public boolean copyTo(T v) {
boolean ret = super.copyTo(v);
if (!Objects.equals(v.getType(), type.get())) {
v.setType(type.get());
ret = true;
}
if (!Objects.equals(v.getLang(), lang.get())) {
v.setLang(lang.get());
ret = true;
}
if (!Objects.equals(v.getValue(), value.get())) {
v.setValue(value.get());
ret = true;
}
return ret;
}
}

View File

@@ -11,7 +11,7 @@
</logger>
<!-- 特别设置 WebSocketService 类的日志级别为 DEBUG -->
<logger name="com.ecep.contract.WebSocketService" level="DEBUG" additivity="false">
<logger name="com.ecep.contract.WebSocketClientService" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>

View File

@@ -4,7 +4,7 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.ecep.contract.manager.ds.other.controller.inventory.InventoryTabSkinContracts">
fx:controller="com.ecep.contract.controller.inventory.InventoryTabSkinContracts">
<children>
<VBox AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0"
AnchorPane.topAnchor="5.0">

View File

@@ -4,7 +4,7 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.ecep.contract.manager.ds.other.controller.inventory.InventoryTabSkinHistoryPrice">
fx:controller="com.ecep.contract.controller.inventory.InventoryTabSkinHistoryPrice">
<children>
<VBox AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0"
AnchorPane.topAnchor="5.0">

View File

@@ -3,7 +3,7 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="680.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.ecep.contract.manager.ds.other.controller.inventory.InventoryManagerWindowController">
fx:controller="com.ecep.contract.controller.inventory.InventoryManagerWindowController">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>

View File

@@ -5,7 +5,7 @@
<?import javafx.scene.layout.*?>
<BorderPane fx:id="root" prefHeight="500.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/22"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.ecep.contract.manager.ds.other.controller.inventory.InventoryWindowController">
fx:controller="com.ecep.contract.controller.inventory.InventoryWindowController">
<top>
<ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<items>

View File

@@ -4,4 +4,5 @@ public class ProjectConstant {
public final static String KEY_CUSTOMER_SATISFACTION_SURVEY_TEMPLATE = "project.customer-satisfaction-survey.template";
public static final String KEY_BASE_PATH = "project.base.path";
}

View File

@@ -0,0 +1,16 @@
package com.ecep.contract.constant;
public class WebSocketConstant {
public static final String MESSAGE_ID_FIELD_NAME = "messageId";
public static final String MESSAGE_TYPE_FIELD_NAME = "messageType";
public static final String SUCCESS_FIELD_VALUE = "success";
public static final String MESSAGE_FIELD_NAME = "message";
public static final String ERROR_CODE_FIELD_NAME = "errorCode";
public static final String SERVICE_FIELD_NAME = "service";
public static final String METHOD_FIELD_NAME = "method";
public static final String ARGUMENTS_FIELD_NAME = "arguments";
public static final String SESSION_ID_FIELD_NAME = "sessionId";
}

View File

@@ -6,6 +6,8 @@ import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.hibernate.annotations.ColumnDefault;
import com.ecep.contract.VendorType;
@@ -56,6 +58,7 @@ public class CompanyVendor implements IdentityEntity, CompanyBasedEntity, Serial
private Company company;
@OneToMany(mappedBy = "vendor", fetch = FetchType.LAZY)
@JsonIgnore
@ToString.Exclude
private List<CompanyVendorEntity> entities;

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.CompanyVendorFileType;
@@ -19,7 +20,8 @@ import lombok.ToString;
@Entity
@Table(name = "COMPANY_VENDOR_FILE_TYPE_LOCAL")
@ToString
public class CompanyVendorFileTypeLocal extends BaseEnumEntity<CompanyVendorFileType> {
public class CompanyVendorFileTypeLocal extends BaseEnumEntity<CompanyVendorFileType> implements Serializable {
private static final long serialVersionUID = 1L;
@Override
public final boolean equals(Object object) {
if (this == object)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.ContractFileType;
@@ -20,7 +21,8 @@ import lombok.ToString;
@Entity
@Table(name = "CONTRACT_FILE_TYPE_LOCAL")
@ToString
public class ContractFileTypeLocal extends BaseEnumEntity<ContractFileType> {
public class ContractFileTypeLocal extends BaseEnumEntity<ContractFileType> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 建议的文件名
*/

View File

@@ -64,6 +64,7 @@ public class ContractGroup implements IdentityEntity, NamedEntity, Serializable
@Override
public final int hashCode() {
super.hashCode();
return HibernateProxyUtils.hashCode(this);
}
}

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.util.HibernateProxyUtils;
@@ -22,7 +23,8 @@ import lombok.ToString;
@Entity
@Table(name = "CUSTOMER_CATALOG", schema = "supplier_ms")
@ToString
public class CustomerCatalog implements BasedEntity, IdentityEntity {
public class CustomerCatalog implements BasedEntity, IdentityEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Objects;
@@ -27,7 +28,8 @@ import lombok.ToString;
@Entity
@Table(name = "PROJECT_CUSTOMER_SATISFACTION_SURVEY", schema = "supplier_ms")
@ToString
public class CustomerSatisfactionSurvey implements IdentityEntity, ProjectBasedEntity {
public class CustomerSatisfactionSurvey implements IdentityEntity, ProjectBasedEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.util.HibernateProxyUtils;
@@ -24,7 +25,8 @@ import lombok.ToString;
@Setter
@Entity
@Table(name = "PRODUCT_DELIVERY_SIGN_METHOD", schema = "supplier_ms")
public class DeliverySignMethod implements BasedEntity, IdentityEntity {
public class DeliverySignMethod implements BasedEntity, IdentityEntity , Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)

View File

@@ -117,8 +117,11 @@ public class Employee implements BasedEntity, IdentityEntity, NamedEntity, Seria
public final boolean equals(Object object) {
if (this == object)
return true;
if (object == null || HibernateProxyUtils.isNotEffectiveClassEquals(this, object))
if (object == null)
return false;
if (HibernateProxyUtils.isNotEffectiveClassEquals(object, this)) {
return false;
}
Employee employee = (Employee) object;
return getId() != null && Objects.equals(getId(), employee.getId());
}

View File

@@ -1,28 +1,21 @@
package com.ecep.contract.model;
import java.util.Objects;
import com.ecep.contract.util.HibernateProxyUtils;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.util.Objects;
@Getter
@Setter
@Entity
@Table(name = "CONTRACT_EXTEND_VENDOR_INFO", schema = "supplier_ms")
@ToString
public class ExtendVendorInfo implements IdentityEntity {
public class ExtendVendorInfo implements IdentityEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -3,11 +3,13 @@ package com.ecep.contract.model;
import jakarta.persistence.Embeddable;
import lombok.Data;
import java.io.Serializable;
import java.time.MonthDay;
@Embeddable
@Data
public class HistoryPrice {
public class HistoryPrice implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 税率1% =1100% =100
*/
@@ -22,7 +24,6 @@ public class HistoryPrice {
private double postTaxPrice;
/**
* 12-31, 字符串方式存储
* {@link com.ecep.contract.manager.ds.MonthDayConverter}
*/
private MonthDay monthDay;
}

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Objects;
@@ -21,7 +22,8 @@ import lombok.ToString;
@Entity
@Table(name = "HOLIDAY_TABLE")
@ToString
public class HolidayTable {
public class HolidayTable implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)
@JdbcTypeCode(SqlTypes.DATE)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.time.Year;
import java.util.Objects;
@@ -26,7 +27,8 @@ import lombok.ToString;
@ToString
@Entity
@Table(name = "INVENTORY_HISTORY", schema = "supplier_ms")
public class InventoryHistoryPrice implements IdentityEntity {
public class InventoryHistoryPrice implements IdentityEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -29,7 +29,7 @@ import lombok.ToString;
@Entity
@Table(name = "PROJECT_FILE")
@ToString
public class ProjectFile implements IdentityEntity, ProjectBasedEntity, Serializable {
public class ProjectFile implements IdentityEntity, ProjectBasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.ProjectFileType;
@@ -16,7 +17,8 @@ import lombok.ToString;
@Entity
@Table(name = "PROJECT_FILE_TYPE_LOCAL")
@ToString
public class ProjectFileTypeLocal extends BaseEnumEntity<ProjectFileType> {
public class ProjectFileTypeLocal extends BaseEnumEntity<ProjectFileType> implements java.io.Serializable {
private static final long serialVersionUID = 1L;
@Override
public final boolean equals(Object object) {
if (this == object) {

View File

@@ -32,7 +32,8 @@ import lombok.ToString;
@Entity
@Table(name = "PROJECT_FUND_PLAN")
@ToString
public class ProjectFundPlan implements IdentityEntity, ProjectBasedEntity {
public class ProjectFundPlan implements IdentityEntity, ProjectBasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -30,7 +30,8 @@ import lombok.ToString;
@Entity
@Table(name = "PROJECT_QUOTATION")
@ToString
public class ProjectQuotation implements IdentityEntity, ProjectBasedEntity {
public class ProjectQuotation implements IdentityEntity, ProjectBasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.util.HibernateProxyUtils;
@@ -20,7 +21,8 @@ import lombok.Setter;
@Setter
@Entity
@Table(name = "PROJECT_SALE_TYPE")
public class ProjectSaleType implements IdentityEntity, NamedEntity, BasedEntity {
public class ProjectSaleType implements IdentityEntity, NamedEntity, BasedEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)

View File

@@ -27,7 +27,8 @@ import lombok.ToString;
@Setter
@Entity
@Table(name = "PROJECT_SALE_TYPE_REQ_FILE_TYPE")
public class ProjectSaleTypeRequireFileType implements IdentityEntity, BasedEntity {
public class ProjectSaleTypeRequireFileType implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)

View File

@@ -21,7 +21,7 @@ import lombok.Setter;
@Setter
@Entity
@Table(name = "PROJECT_TYPE")
public class ProjectType implements IdentityEntity, NamedEntity, BasedEntity, Serializable {
public class ProjectType implements IdentityEntity, NamedEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)

View File

@@ -27,7 +27,8 @@ import lombok.ToString;
@Entity
@Table(name = "PURCHASE_BILL_VOUCHER", schema = "supplier_ms")
@ToString
public class PurchaseBillVoucher implements IdentityEntity, BasedEntity {
public class PurchaseBillVoucher implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -26,7 +26,8 @@ import lombok.ToString;
@Entity
@Table(name = "PURCHASE_BILL_VOUCHER_ITEM", schema = "supplier_ms")
@ToString
public class PurchaseBillVoucherItem implements IdentityEntity, BasedEntity {
public class PurchaseBillVoucherItem implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -27,7 +27,8 @@ import lombok.ToString;
@Entity
@Table(name = "PURCHASE_ORDER", schema = "supplier_ms")
@ToString
public class PurchaseOrder implements IdentityEntity, BasedEntity, ContractBasedEntity {
public class PurchaseOrder implements IdentityEntity, BasedEntity, ContractBasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -27,7 +27,8 @@ import lombok.ToString;
@Entity
@Table(name = "PURCHASE_ORDER_ITEM", schema = "supplier_ms")
@ToString
public class PurchaseOrderItem implements IdentityEntity, BasedEntity {
public class PurchaseOrderItem implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -27,7 +27,8 @@ import lombok.ToString;
@Entity
@Table(name = "PURCHASE_RECEIPT", schema = "supplier_ms")
@ToString
public class PurchaseReceipt implements IdentityEntity, BasedEntity {
public class PurchaseReceipt implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -27,7 +27,8 @@ import lombok.ToString;
@Entity
@Table(name = "PURCHASE_SETTLE_VOUCHER", schema = "supplier_ms")
@ToString
public class PurchaseSettlementVoucher implements IdentityEntity, BasedEntity {
public class PurchaseSettlementVoucher implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -26,7 +26,8 @@ import lombok.ToString;
@Entity
@Table(name = "PURCHASE_SETTLE_VOUCHER_ITEM", schema = "supplier_ms")
@ToString
public class PurchaseSettlementVoucherItem implements IdentityEntity, BasedEntity {
public class PurchaseSettlementVoucherItem implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -27,7 +27,8 @@ import lombok.ToString;
@Entity
@Table(name = "SALES_BILL_VOUCHER", schema = "supplier_ms")
@ToString
public class SalesBillVoucher implements IdentityEntity, BasedEntity {
public class SalesBillVoucher implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -26,7 +26,8 @@ import lombok.ToString;
@Entity
@Table(name = "SALES_BILL_VOUCHER_ITEM", schema = "supplier_ms")
@ToString
public class SalesBillVoucherItem implements IdentityEntity, BasedEntity {
public class SalesBillVoucherItem implements IdentityEntity, BasedEntity, java.io.Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Objects;
@@ -27,7 +28,8 @@ import lombok.ToString;
@Entity
@Table(name = "CONTRACT_SALES_ORDER", schema = "supplier_ms")
@ToString
public class SalesOrder implements IdentityEntity, BasedEntity, ContractBasedEntity {
public class SalesOrder implements IdentityEntity, BasedEntity, ContractBasedEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -0,0 +1,44 @@
package com.ecep.contract.model;
import com.ecep.contract.util.HibernateProxyUtils;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.proxy.HibernateProxy;
import java.io.Serializable;
import java.util.Objects;
/**
* 销售订单发票
*/
@Getter
@Setter
@RequiredArgsConstructor
@Entity
@Table(name = "SALES_ORDER_INVOICE", schema = "supplier_ms")
@ToString
public class SalesOrderInvoice implements IdentityEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (HibernateProxyUtils.isNotEffectiveClassEquals(o, this)) {
return false;
}
SalesOrderInvoice that = (SalesOrderInvoice) o;
return getId() != null && Objects.equals(getId(), that.getId());
}
@Override
public final int hashCode() {
return HibernateProxyUtils.hashCode(this);
}
}

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Objects;
@@ -27,7 +28,8 @@ import lombok.ToString;
@Entity
@Table(name = "CONTRACT_SALES_ORDER_ITEM", schema = "supplier_ms")
@ToString
public class SalesOrderItem implements IdentityEntity, BasedEntity {
public class SalesOrderItem implements IdentityEntity, BasedEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)

View File

@@ -1,19 +1,14 @@
package com.ecep.contract.model;
import java.util.Objects;
import com.ecep.contract.util.HibernateProxyUtils;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.io.Serializable;
import java.util.Objects;
/**
* 采购合同类型
*/
@@ -22,7 +17,8 @@ import lombok.ToString;
@Entity
@Table(name = "VENDOR_GROUP", schema = "supplier_ms")
@ToString
public class VendorGroup implements IdentityEntity, NamedEntity, BasedEntity {
public class VendorGroup implements IdentityEntity, NamedEntity, BasedEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.ContractFileType;
@@ -27,7 +28,8 @@ import lombok.ToString;
@Setter
@Entity
@Table(name = "VENDOR_GROUP_REQ_FILE_TYPE")
public class VendorGroupRequireFileType implements IdentityEntity, BasedEntity {
public class VendorGroupRequireFileType implements IdentityEntity, BasedEntity, Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.model;
import java.io.Serializable;
import java.util.Objects;
import com.ecep.contract.VendorType;
@@ -19,7 +20,8 @@ import lombok.ToString;
@Entity
@Table(name = "VENDOR_TYPE_LOCAL")
@ToString(callSuper = true)
public class VendorTypeLocal extends BaseEnumEntity<VendorType> {
public class VendorTypeLocal extends BaseEnumEntity<VendorType> implements Serializable {
private static final long serialVersionUID = 1L;
@Override
public final boolean equals(Object object) {

View File

@@ -3,12 +3,15 @@ package com.ecep.contract.model;
import jakarta.persistence.Embeddable;
import lombok.Data;
import java.io.Serializable;
/**
* 体积尺寸
*/
@Embeddable
@Data
public class VolumeSize {
public class VolumeSize implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 体积
*/

View File

@@ -1,12 +1,13 @@
package com.ecep.contract.msg;
import com.ecep.contract.constant.WebSocketConstant;
import lombok.Data;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import lombok.Data;
@Data
public class SimpleMessage {
@@ -16,6 +17,9 @@ public class SimpleMessage {
private String method;
private Object data;
private List<String> parameterTypes;
/**
* @see WebSocketConstant#ARGUMENTS_FIELD_NAME
*/
private List<Object> arguments;
public void setArguments(Object... arguments) {

View File

@@ -2,6 +2,8 @@ package com.ecep.contract.util;
import org.hibernate.proxy.HibernateProxy;
import java.util.Objects;
public class HibernateProxyUtils {
private static boolean useProxy = true;
@@ -19,14 +21,12 @@ public class HibernateProxyUtils {
Class<?> thisEffectiveClass = that instanceof HibernateProxy
? ((HibernateProxy) that).getHibernateLazyInitializer().getPersistentClass()
: that.getClass();
if (thisEffectiveClass != oEffectiveClass)
return false;
return true;
return thisEffectiveClass != oEffectiveClass;
}
public static int hashCode(Object that) {
if (!useProxy) {
return that.hashCode();
return that.getClass().hashCode();
}
return that instanceof HibernateProxy
? ((HibernateProxy) that).getHibernateLazyInitializer().getPersistentClass().hashCode()

Some files were not shown because too many files have changed in this diff Show More