refactor: 重构供应商文件类型枚举及相关服务

feat: 为多个服务添加缓存支持
fix: 修复WebSocket任务管理和远程调用异常处理
refactor: 重命名CompanyVendorFileType为VendorFileType
refactor: 优化项目成本导入任务实现
fix: 修复ContractTabSkinBase中的空指针问题
refactor: 统一WebSocket客户端任务调用接口
This commit is contained in:
2025-09-17 22:28:17 +08:00
parent 7560250036
commit c0e4916474
43 changed files with 624 additions and 260 deletions

View File

@@ -134,7 +134,7 @@ public class WebSocketClientService {
@Override @Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) { public void onFailure(WebSocket webSocket, Throwable t, Response response) {
logger.error("WebSocket连接失败: " + t.getMessage()); logger.error("WebSocket连接失败: " + t.getMessage() + ", response=" + response, t);
Platform.runLater(() -> { Platform.runLater(() -> {
online.setValue(false); online.setValue(false);
message.set("连接失败: " + t.getMessage()); message.set("连接失败: " + t.getMessage());
@@ -179,13 +179,19 @@ public class WebSocketClientService {
if (webSocket == null) { if (webSocket == null) {
throw new IllegalStateException("WebSocket is not initialized"); throw new IllegalStateException("WebSocket is not initialized");
} }
if (!online.get()) {
throw new IllegalStateException("WebSocket is not online");
}
String json = objectMapper.writeValueAsString(msg); String json = objectMapper.writeValueAsString(msg);
callbacks.put(msg.getMessageId(), future); callbacks.put(msg.getMessageId(), future);
if (webSocket.send(json)) { if (webSocket.send(json)) {
logger.debug("send message success:{}", json); logger.debug("send message success:{}", json);
} else { } else {
if (isActive) {
future.completeExceptionally(new RuntimeException("Failed to send WebSocket message")); future.completeExceptionally(new RuntimeException("Failed to send WebSocket message"));
} else {
future.completeExceptionally(new RuntimeException("WebSocket is not active"));
}
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Failed to send WebSocket message: {}", e.getMessage()); logger.error("Failed to send WebSocket message: {}", e.getMessage());
@@ -321,14 +327,14 @@ public class WebSocketClientService {
} }
} }
private void closeSession(WebSocketClientSession session) { public void closeSession(WebSocketClientSession session) {
if (session != null) { if (session != null) {
sessions.remove(session.getSessionId()); sessions.remove(session.getSessionId());
session.close(); session.close();
} }
} }
private WebSocketClientSession createSession() { public WebSocketClientSession createSession() {
WebSocketClientSession session = new WebSocketClientSession(this); WebSocketClientSession session = new WebSocketClientSession(this);
sessions.put(session.getSessionId(), session); sessions.put(session.getSessionId(), session);
return session; return session;

View File

@@ -7,6 +7,7 @@ import lombok.Getter;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
@@ -24,15 +25,12 @@ public class WebSocketClientSession {
} }
public void close() { public void close() {
webSocketService.closeSession(this);
} }
public void submitTask(WebSocketClientTasker tasker, Object... args) throws JsonProcessingException { public void submitTask(WebSocketClientTasker tasker, Locale locale, Object... args) throws JsonProcessingException {
this.tasker = tasker; this.tasker = tasker;
// 将 tasker.getTaskName() 和 args 合并到一个数组参数中 send("createTask", tasker.getTaskName(), locale.toLanguageTag(), 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 { public void send(String type, Object... args) throws JsonProcessingException {
@@ -49,13 +47,41 @@ public class WebSocketClientSession {
String type = node.get("type").asText(); String type = node.get("type").asText();
JsonNode args = node.get(WebSocketConstant.ARGUMENTS_FIELD_NAME); JsonNode args = node.get(WebSocketConstant.ARGUMENTS_FIELD_NAME);
if (type.equals("message")) { if (type.equals("message")) {
String message = args.get(1).asText(); handleAsMessage(args);
String level = args.get(0).asText();
updateMessage(java.util.logging.Level.parse(level), message);
} else if (type.equals("title")) { } else if (type.equals("title")) {
String message = args.get(0).asText(); handleAsTitle(args);
tasker.updateTitle(message);
} else if (type.equals("property")) { } else if (type.equals("property")) {
handleAsProperty(args);
} else if (type.equals("progress")) {
handleAsProgress(args);
} else if (type.equals("start")) {
handleAsStart(args);
} else if (type.equals("done")) {
handleAsDone(args);
} else {
tasker.updateMessage(java.util.logging.Level.INFO, "未知的消息类型: " + node.toString());
}
} else {
tasker.updateMessage(java.util.logging.Level.INFO, "未知的消息: " + node.toString());
}
}
private void handleAsDone(JsonNode args) {
tasker.updateMessage(java.util.logging.Level.INFO, "任务完成");
close();
}
private void handleAsStart(JsonNode args) {
tasker.updateMessage(java.util.logging.Level.INFO, "任务开始");
}
private void handleAsProgress(JsonNode args) {
long current = args.get(0).asLong();
long total = args.get(1).asLong();
tasker.updateProgress(current, total);
}
private void handleAsProperty(JsonNode args) {
String name = args.get(0).asText(); String name = args.get(0).asText();
Object value = args.get(1); Object value = args.get(1);
try { try {
@@ -70,16 +96,17 @@ public class WebSocketClientSession {
} catch (Exception e) { } catch (Exception e) {
tasker.updateMessage(java.util.logging.Level.SEVERE, "属性设置失败: " + name + " = " + value); 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()); private void handleAsTitle(JsonNode args) {
String message = args.get(0).asText();
tasker.updateTitle(message);
} }
private void handleAsMessage(JsonNode args) {
String level = args.get(0).asText();
String message = args.get(1).asText();
updateMessage(java.util.logging.Level.parse(level), message);
} }
public void updateMessage(Level level, String message) { public void updateMessage(Level level, String message) {

View File

@@ -1,5 +1,8 @@
package com.ecep.contract; package com.ecep.contract;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.util.Locale;
import java.util.logging.Level; import java.util.logging.Level;
public interface WebSocketClientTasker { public interface WebSocketClientTasker {
@@ -10,4 +13,17 @@ public interface WebSocketClientTasker {
void updateTitle(String title); void updateTitle(String title);
void updateProgress(long current, long total); void updateProgress(long current, long total);
default Object callRemoteTask(MessageHolder holder, Locale locale, Object... args) {
WebSocketClientService webSocketService = SpringApp.getBean(WebSocketClientService.class);
webSocketService.withSession(session -> {
try {
session.submitTask(this, locale, args);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
});
return null;
}
} }

View File

@@ -1,19 +1,31 @@
package com.ecep.contract.controller.project.cost; package com.ecep.contract.controller.project.cost;
import com.ecep.contract.MessageHolder; import com.ecep.contract.MessageHolder;
import com.ecep.contract.WebSocketClientTasker;
import com.ecep.contract.model.ProjectCost; import com.ecep.contract.model.ProjectCost;
import com.ecep.contract.task.Tasker; import com.ecep.contract.task.Tasker;
import lombok.Setter; import lombok.Setter;
public class ProjectCostImportItemsFromContractsTasker extends Tasker<Object> { /**
* 从相关合同中导入成本项
*/
public class ProjectCostImportItemsFromContractsTasker extends Tasker<Object> implements WebSocketClientTasker {
@Setter @Setter
private ProjectCost cost; private ProjectCost cost;
@Override @Override
protected Object execute(MessageHolder holder) throws Exception { protected Object execute(MessageHolder holder) throws Exception {
// TODO Auto-generated method stub updateTitle("修复项目成本 " + cost.getId());
throw new UnsupportedOperationException("Unimplemented method 'execute'"); return callRemoteTask(holder, getLocale(), cost.getId());
} }
@Override
public String getTaskName() {
return "ProjectCostImportItemsFromContractsTasker";
}
@Override
public void updateProgress(long current, long total) {
super.updateProgress(current, total);
}
} }

View File

@@ -8,10 +8,14 @@ import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import javafx.beans.value.ObservableValue;
import org.controlsfx.control.textfield.TextFields; import org.controlsfx.control.textfield.TextFields;
import org.controlsfx.glyphfont.Glyph; import org.controlsfx.glyphfont.Glyph;
import com.ecep.contract.util.ProxyUtils; import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.ContractPayWay; import com.ecep.contract.ContractPayWay;
@@ -285,7 +289,7 @@ public class ContractTabSkinBase extends AbstContractBasedTabSkin {
// 设置项目的开始创建时间,从合同的创建时间、提交日期、开始日期中取最早的日期 // 设置项目的开始创建时间,从合同的创建时间、提交日期、开始日期中取最早的日期
List<LocalDate> dates = new ArrayList<>(); List<LocalDate> dates = new ArrayList<>();
if (viewModel.getCreated().get() != null) { if (viewModel.getCreated().getValue() != null) {
dates.add(viewModel.getCreated().get().toLocalDate()); dates.add(viewModel.getCreated().get().toLocalDate());
} }
if (viewModel.getSetupDate().get() != null) { if (viewModel.getSetupDate().get() != null) {

View File

@@ -120,10 +120,11 @@ public class AsyncUpdateTableCell<V, T extends IdentityEntity> extends javafx.sc
return; return;
} }
if (getService() instanceof QueryService<T, ?> queryService) { // if (getService() instanceof QueryService<T, ?> queryService) {
queryService.asyncFindById(getItem().getId()).thenAccept(this::_updateEntity); // queryService.findById(getItem().getId());
return; // queryService.asyncFindById(getItem().getId()).thenAccept(this::_updateEntity);
} // return;
// }
T entity = initialize(); T entity = initialize();
_updateEntity(entity); _updateEntity(entity);

View File

@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.ecep.contract.service.VendorTypeService;
import com.ecep.contract.util.ProxyUtils; import com.ecep.contract.util.ProxyUtils;
import com.ecep.contract.MyDateTimeUtils; import com.ecep.contract.MyDateTimeUtils;
@@ -61,6 +62,8 @@ public class CompanyVendorManagerSkin
@Override @Override
public void initializeTable() { public void initializeTable() {
getBean(VendorTypeService.class);
List<VendorTypeLocal> vendorTypeLocals = getCompanyVendorService() List<VendorTypeLocal> vendorTypeLocals = getCompanyVendorService()
.findAllTypes(controller.getLocale()); .findAllTypes(controller.getLocale());
ComboBoxUtils.initialComboBox(controller.typeSelector, vendorTypeLocals, true); ComboBoxUtils.initialComboBox(controller.typeSelector, vendorTypeLocals, true);

View File

@@ -9,7 +9,7 @@ import java.util.concurrent.CompletableFuture;
import com.ecep.contract.util.ProxyUtils; import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.DesktopUtils; import com.ecep.contract.DesktopUtils;
import com.ecep.contract.MyDateTimeUtils; import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp; import com.ecep.contract.SpringApp;
@@ -19,7 +19,7 @@ import com.ecep.contract.model.BaseEnumEntity;
import com.ecep.contract.model.Company; import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyVendor; import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.CompanyVendorFile; import com.ecep.contract.model.CompanyVendorFile;
import com.ecep.contract.model.CompanyVendorFileTypeLocal; import com.ecep.contract.model.VendorFileTypeLocal;
import com.ecep.contract.service.CompanyVendorFileService; import com.ecep.contract.service.CompanyVendorFileService;
import com.ecep.contract.task.CompanyVendorEvaluationFormUpdateTask; import com.ecep.contract.task.CompanyVendorEvaluationFormUpdateTask;
import com.ecep.contract.util.FxmlPath; import com.ecep.contract.util.FxmlPath;
@@ -91,7 +91,7 @@ public class VendorTabSkinFile
table.disableProperty().bind(viewModel.getPath().isEmpty()); table.disableProperty().bind(viewModel.getPath().isEmpty());
fileTable_idColumn.setCellValueFactory(param -> param.getValue().getId()); fileTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
ObservableMap<CompanyVendorFileType, CompanyVendorFileTypeLocal> observableMapByLocal = FXCollections ObservableMap<VendorFileType, VendorFileTypeLocal> observableMapByLocal = FXCollections
.observableMap(companyVendorFileService.getFileTypeLocalMap(getLocale())); .observableMap(companyVendorFileService.getFileTypeLocalMap(getLocale()));
fileTable_typeColumn.setCellValueFactory(param -> Bindings.valueAt(observableMapByLocal, fileTable_typeColumn.setCellValueFactory(param -> Bindings.valueAt(observableMapByLocal,
param.getValue().getType()).map(BaseEnumEntity::getValue)); param.getValue().getType()).map(BaseEnumEntity::getValue));
@@ -151,7 +151,7 @@ public class VendorTabSkinFile
if (file.renameTo(dest)) { if (file.renameTo(dest)) {
CompanyVendorFile ccf = new CompanyVendorFile(); CompanyVendorFile ccf = new CompanyVendorFile();
ccf.setVendor(companyVendor); ccf.setVendor(companyVendor);
ccf.setType(CompanyVendorFileType.EvaluationForm); ccf.setType(VendorFileType.EvaluationForm);
ccf.setFilePath(dest.getAbsolutePath()); ccf.setFilePath(dest.getAbsolutePath());
ccf.setSignDate(nextSignDate); ccf.setSignDate(nextSignDate);
ccf.setValid(true); ccf.setValid(true);
@@ -172,7 +172,7 @@ public class VendorTabSkinFile
if (file.renameTo(dest)) { if (file.renameTo(dest)) {
CompanyVendorFile ccf = new CompanyVendorFile(); CompanyVendorFile ccf = new CompanyVendorFile();
ccf.setVendor(companyVendor); ccf.setVendor(companyVendor);
ccf.setType(CompanyVendorFileType.General); ccf.setType(VendorFileType.General);
ccf.setFilePath(dest.getAbsolutePath()); ccf.setFilePath(dest.getAbsolutePath());
ccf.setValid(false); ccf.setValid(false);
companyVendorFiles.add(ccf); companyVendorFiles.add(ccf);

View File

@@ -16,7 +16,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.MessageHolder; import com.ecep.contract.MessageHolder;
import com.ecep.contract.VendorType; import com.ecep.contract.VendorType;
import com.ecep.contract.model.Company; import com.ecep.contract.model.Company;
@@ -574,7 +574,7 @@ public class CompanyVendorApprovedListVendorImportTask extends Tasker<Object> {
CompanyVendorFileService fileService = getCompanyVendorFileService(); CompanyVendorFileService fileService = getCompanyVendorFileService();
LocalDate miniDate = publishDate.minusYears(vendorFileMinusYear); LocalDate miniDate = publishDate.minusYears(vendorFileMinusYear);
return fileService.findAll(ParamUtils.builder().equals("vendor", vendor.getId()).equals("valid", true) return fileService.findAll(ParamUtils.builder().equals("vendor", vendor.getId()).equals("valid", true)
.equals("type", CompanyVendorFileType.EvaluationForm).between("signDate", miniDate, publishDate) .equals("type", VendorFileType.EvaluationForm).between("signDate", miniDate, publishDate)
.build(), Pageable.unpaged()).getContent(); .build(), Pageable.unpaged()).getContent();
} }
} }

View File

@@ -12,10 +12,10 @@ import com.ecep.contract.MyDateTimeUtils;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.model.CompanyVendor; import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.CompanyVendorFile; import com.ecep.contract.model.CompanyVendorFile;
import com.ecep.contract.model.CompanyVendorFileTypeLocal; import com.ecep.contract.model.VendorFileTypeLocal;
import com.ecep.contract.vm.CompanyVendorFileViewModel; import com.ecep.contract.vm.CompanyVendorFileViewModel;
@Service @Service
@@ -30,14 +30,14 @@ public class CompanyVendorFileService extends QueryService<CompanyVendorFile, Co
throw new UnsupportedOperationException("Unimplemented method 'saveAll'"); throw new UnsupportedOperationException("Unimplemented method 'saveAll'");
} }
public Map<CompanyVendorFileType, CompanyVendorFileTypeLocal> getFileTypeLocalMap(Locale locale) { public Map<VendorFileType, VendorFileTypeLocal> getFileTypeLocalMap(Locale locale) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getFileTypeLocalMap'"); throw new UnsupportedOperationException("Unimplemented method 'getFileTypeLocalMap'");
} }
public void verify(CompanyVendor companyVendor, LocalDate verifyDate, MessageHolder holder) { public void verify(CompanyVendor companyVendor, LocalDate verifyDate, MessageHolder holder) {
// 查询所有评价表 // 查询所有评价表
List<CompanyVendorFile> files = findAllByVendorAndType(companyVendor, CompanyVendorFileType.EvaluationForm); List<CompanyVendorFile> files = findAllByVendorAndType(companyVendor, VendorFileType.EvaluationForm);
if (files == null || files.isEmpty()) { if (files == null || files.isEmpty()) {
holder.error("未见供应商评价"); holder.error("未见供应商评价");
return; return;
@@ -65,7 +65,7 @@ public class CompanyVendorFileService extends QueryService<CompanyVendorFile, Co
} }
} }
public List<CompanyVendorFile> findAllByVendorAndType(CompanyVendor vendor, CompanyVendorFileType type) { public List<CompanyVendorFile> findAllByVendorAndType(CompanyVendor vendor, VendorFileType type) {
return findAll(Map.of("vendor", vendor.getId(), "type", type.name()), Pageable.unpaged()).getContent(); return findAll(Map.of("vendor", vendor.getId(), "type", type.name()), Pageable.unpaged()).getContent();
} }
} }

View File

@@ -1,15 +1,60 @@
package com.ecep.contract.service; package com.ecep.contract.service;
import com.ecep.contract.model.ContractKind;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ecep.contract.model.ContractGroup; import com.ecep.contract.model.ContractGroup;
import com.ecep.contract.vm.ContractGroupViewModel; import com.ecep.contract.vm.ContractGroupViewModel;
import java.util.List;
@Service @Service
@CacheConfig(cacheNames = "contract-group")
public class ContractGroupService extends QueryService<ContractGroup, ContractGroupViewModel> { public class ContractGroupService extends QueryService<ContractGroup, ContractGroupViewModel> {
public ContractGroup findByCode(String groupCode) { @Override
// TODO Auto-generated method stub @Cacheable(key = "#p0")
throw new UnsupportedOperationException("Unimplemented method 'findByCode'"); public ContractGroup findById(Integer id) {
return super.findById(id);
}
public ContractGroup findByCode(String code) {
try {
return async("findByCode", code, String.class).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+findByCode+调用失败", ex);
}
ContractGroup newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败" + code, e);
}
}
@Cacheable(key = "'groups'")
@Override
public List<ContractGroup> findAll() {
return super.findAll();
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'groups'")
})
@Override
public ContractGroup save(ContractGroup entity) {
return super.save(entity);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'groups'")
})
@Override
public void delete(ContractGroup entity) {
super.delete(entity);
} }
} }

View File

@@ -1,19 +1,73 @@
package com.ecep.contract.service; package com.ecep.contract.service;
import com.ecep.contract.model.ContractType;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ecep.contract.model.ContractKind; import com.ecep.contract.model.ContractKind;
import com.ecep.contract.vm.ContractKindViewModel; import com.ecep.contract.vm.ContractKindViewModel;
import java.util.List;
@Service @Service
@CacheConfig(cacheNames = "contract-kind")
public class ContractKindService extends QueryService<ContractKind, ContractKindViewModel> { public class ContractKindService extends QueryService<ContractKind, ContractKindViewModel> {
@Cacheable(key = "#p0")
@Override
public ContractKind findById(Integer id) {
return super.findById(id);
}
public ContractKind findByName(String name) { public ContractKind findByName(String name) {
throw new UnsupportedOperationException("Unimplemented method 'findByName'"); try {
return async("findByName", name, String.class).handle((response, ex) -> {
ContractKind newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败" + name, e);
}
} }
public ContractKind findByCode(String code) { public ContractKind findByCode(String code) {
throw new UnsupportedOperationException("Unimplemented method 'findByCode'"); try {
return async("findByCode", code, String.class).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+findByCode+调用失败", ex);
}
ContractKind newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败" + code, e);
} }
} }
@Cacheable(key = "'kinds'")
@Override
public List<ContractKind> findAll() {
return super.findAll();
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'kinds'"),
})
@Override
public ContractKind save(ContractKind entity) {
return super.save(entity);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'kinds'"),
})
@Override
public void delete(ContractKind entity) {
super.delete(entity);
}
}

View File

@@ -75,6 +75,9 @@ public class ContractService extends QueryService<Contract, ContractViewModel> {
public Contract findByCode(String code) { public Contract findByCode(String code) {
try { try {
return async("findByCode", code, String.class).handle((response, ex) -> { return async("findByCode", code, String.class).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+findByCode+调用失败", ex);
}
if (response != null) { if (response != null) {
return updateValue(new Contract(), response); return updateValue(new Contract(), response);
} }

View File

@@ -1,20 +1,69 @@
package com.ecep.contract.service; package com.ecep.contract.service;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ecep.contract.model.ContractType; import com.ecep.contract.model.ContractType;
import com.ecep.contract.vm.ContractTypeViewModel; import com.ecep.contract.vm.ContractTypeViewModel;
import java.util.List;
@Service @Service
@CacheConfig(cacheNames = "contract-type")
public class ContractTypeService extends QueryService<ContractType, ContractTypeViewModel> { public class ContractTypeService extends QueryService<ContractType, ContractTypeViewModel> {
@Cacheable(key = "#p0")
@Override
public ContractType findById(Integer id) {
return super.findById(id);
}
public ContractType findByName(String name) { public ContractType findByName(String name) {
throw new UnsupportedOperationException("Unimplemented method 'findByName'"); try {
return async("findByName", name, String.class).handle((response, ex) -> {
ContractType newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败" + name, e);
}
} }
public ContractType findByCode(String typeCode) { public ContractType findByCode(String code) {
// TODO Auto-generated method stub try {
throw new UnsupportedOperationException("Unimplemented method 'findByCode'"); return async("findByCode", code, String.class).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+findByCode+调用失败", ex);
}
ContractType newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败" + code, e);
}
} }
@Cacheable(key = "'types'")
@Override
public List<ContractType> findAll() {
return super.findAll();
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'types'"),
})
@Override
public void delete(ContractType entity) {
super.delete(entity);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'types'"),
})
@Override
public ContractType save(ContractType entity) {
return super.save(entity);
}
} }

View File

@@ -5,6 +5,10 @@ import com.ecep.contract.model.Employee;
import com.ecep.contract.model.EmployeeRole; import com.ecep.contract.model.EmployeeRole;
import com.ecep.contract.vm.EmployeeViewModel; import com.ecep.contract.vm.EmployeeViewModel;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
@@ -12,15 +16,43 @@ import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@Service @Service
@CacheConfig(cacheNames = "employee")
public class EmployeeService extends QueryService<Employee, EmployeeViewModel> { public class EmployeeService extends QueryService<Employee, EmployeeViewModel> {
public static final int DEFAULT_SYSTEM_EMPLOYEE_ID = 26; public static final int DEFAULT_SYSTEM_EMPLOYEE_ID = 26;
public Employee findByName(String name) { @Cacheable(key = "#p0")
// TODO Auto-generated method stub @Override
throw new UnsupportedOperationException("Unimplemented method 'findByName'"); public Employee findById(Integer id) {
return super.findById(id);
} }
public Employee findByName(String name) {
try {
return async("findByName", name, String.class).handle((response, ex) -> {
Employee newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败:" + name, e);
}
}
public Employee findByCode(String code) {
try {
return async("findByCode", code, String.class).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+findByCode+调用失败", ex);
}
Employee newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败:" + code, e);
}
}
public List<EmployeeRole> getRolesByEmployeeId(Integer id) { public List<EmployeeRole> getRolesByEmployeeId(Integer id) {
try { try {
return async("getRolesByEmployeeId", List.of(id), List.of(Integer.class)).handle((response, ex) -> { return async("getRolesByEmployeeId", List.of(id), List.of(Integer.class)).handle((response, ex) -> {
@@ -44,15 +76,20 @@ public class EmployeeService extends QueryService<Employee, EmployeeViewModel> {
} }
} }
public void updateActive(int sessionId) {
// TODO Auto-generated method stub @Caching(evict = {
throw new UnsupportedOperationException("Unimplemented method 'updateActive'"); @CacheEvict(key = "#p0.id"),
})
@Override
public Employee save(Employee entity) {
return super.save(entity);
} }
public Employee findByCode(String personCode) { @Caching(evict = {
// TODO Auto-generated method stub @CacheEvict(key = "#p0.id"),
throw new UnsupportedOperationException("Unimplemented method 'findByCode'"); })
@Override
public void delete(Employee entity) {
super.delete(entity);
} }
} }

View File

@@ -1,16 +1,56 @@
package com.ecep.contract.service; package com.ecep.contract.service;
import com.ecep.contract.model.ContractType;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ecep.contract.model.ProductType; import com.ecep.contract.model.ProductType;
import com.ecep.contract.vm.ProductTypeViewModel; import com.ecep.contract.vm.ProductTypeViewModel;
import java.util.List;
@Service @Service
@CacheConfig(cacheNames = "product-type")
public class ProductTypeService extends QueryService<ProductType, ProductTypeViewModel> { public class ProductTypeService extends QueryService<ProductType, ProductTypeViewModel> {
@Cacheable(key = "#p0")
@Override
public ProductType findById(Integer id) {
return super.findById(id);
}
public ProductType findByName(String name) { public ProductType findByName(String name) {
// TODO Auto-generated method stub try {
throw new UnsupportedOperationException("Unimplemented method 'findByName'"); return async("findByName", name, String.class).handle((response, ex) -> {
ProductType newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败" + name, e);
}
} }
@Cacheable(key = "'types'")
@Override
public List<ProductType> findAll() {
return super.findAll();
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'types'"),
})
@Override
public ProductType save(ProductType entity) {
return super.save(entity);
}
@Caching(evict = {
@CacheEvict(key = "#p0.id"), @CacheEvict(key = "'types'"),
})
@Override
public void delete(ProductType entity) {
super.delete(entity);
}
} }

View File

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

View File

@@ -43,11 +43,6 @@ public class ProjectCostService extends QueryService<ProjectCost, ProjectCostVie
return page.getContent().getFirst(); return page.getContent().getFirst();
} }
public void updateAutoCost(Project project, MessageHolder holder) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'updateAutoCost'");
}
public List<ProjectCost> findAllByProject(Project project) { public List<ProjectCost> findAllByProject(Project project) {
return findAll(ParamUtils.builder().equals("project", project.getId()).build(), Pageable.unpaged()).getContent(); return findAll(ParamUtils.builder().equals("project", project.getId()).build(), Pageable.unpaged()).getContent();
} }

View File

@@ -1,13 +1,19 @@
package com.ecep.contract.service; package com.ecep.contract.service;
import com.ecep.contract.SpringApp;
import com.ecep.contract.model.Employee;
import com.ecep.contract.util.ProxyUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ecep.contract.model.Contract; import com.ecep.contract.model.Contract;
import com.ecep.contract.model.Project; import com.ecep.contract.model.Project;
import com.ecep.contract.model.ProjectSaleType; import com.ecep.contract.model.ProjectSaleType;
import com.ecep.contract.vm.ProjectViewModel; import com.ecep.contract.vm.ProjectViewModel;
import org.springframework.util.StringUtils;
import java.io.File; import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@Service @Service
@@ -15,11 +21,25 @@ public class ProjectService extends QueryService<Project, ProjectViewModel> {
public Project findByName(String name) { public Project findByName(String name) {
throw new UnsupportedOperationException(); try {
return async("findByName", name, String.class).handle((response, ex) -> {
Project newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败:" + name, e);
}
} }
public Project findByCode(String code) { public Project findByCode(String code) {
throw new UnsupportedOperationException(); try {
return async("findByCode", code, String.class).handle((response, ex) -> {
Project newEntity = createNewEntity();
return updateValue(newEntity, response);
}).get();
} catch (Exception e) {
throw new RuntimeException("查询实体失败:" + code, e);
}
} }
public void applyCode(Project project, String code) { public void applyCode(Project project, String code) {
@@ -27,13 +47,63 @@ public class ProjectService extends QueryService<Project, ProjectViewModel> {
} }
public Project newInstanceByContract(Contract contract) { public Project newInstanceByContract(Contract contract) {
// TODO Auto-generated method stub Project project = new Project();
throw new UnsupportedOperationException("Unimplemented method 'newInstanceByContract'"); project.setName(contract.getName());
applyCode(project, contract.getCode());
contract.setCreated(LocalDateTime.now());
LocalDateTime created = contract.getCreated();
if (created != null) {
project.setCreated(created.toLocalDate());
} else {
project.setCreated(LocalDate.now());
}
project.setCustomer(contract.getCompany());
project.setApplicant(contract.getEmployee());
return project;
} }
public File searchPath(Project project) { public File searchPath(Project project) {
// TODO Auto-generated method stub ProjectSaleType saleType = project.getSaleType();
throw new UnsupportedOperationException("Unimplemented method 'searchPath'"); if (saleType == null) {
return null;
}
if (!ProxyUtils.isInitialized(saleType)) {
saleType = SpringApp.getBean(ProjectSaleTypeService.class).findById(saleType.getId());
project.setSaleType(saleType);
}
if (!StringUtils.hasText(saleType.getPath())) {
return null;
}
File path = new File(saleType.getPath());
if (saleType.isStoreByYear()) {
path = new File(path, "20" + project.getCodeYear());
if (!path.exists()) {
path.mkdir();// 创建目录
}
}
String projectCode = makeProjectCode(project);
// 检索目录
File[] files = path.listFiles(f -> f.isDirectory() && f.getName().contains(projectCode));
if (files != null && files.length > 0) {
path = files[0];
}
return path;
}
public String makeProjectCode(Project project) {
StringBuilder sb = new StringBuilder();
sb.append(project.getSaleType().getCode());
sb.append(project.getCodeYear());
if (project.getCodeSequenceNumber() < 10) {
sb.append("0");
}
if (project.getCodeSequenceNumber() < 100) {
sb.append("0");
}
sb.append(project.getCodeSequenceNumber());
return sb.toString();
} }
public int getNextCodeSequenceNumber(ProjectSaleType newValue, int i) { public int getNextCodeSequenceNumber(ProjectSaleType newValue, int i) {

View File

@@ -66,6 +66,9 @@ public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel
public T save(T entity) { public T save(T entity) {
try { try {
return async("save", entity, entity.getClass().getName()).handle((response, ex) -> { return async("save", entity, entity.getClass().getName()).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("保存实体失败", ex);
}
if (response != null) { if (response != null) {
try { try {
objectMapper.updateValue(entity, response); objectMapper.updateValue(entity, response);
@@ -84,6 +87,9 @@ public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel
public void delete(T entity) { public void delete(T entity) {
try { try {
async("delete", entity, entity.getClass().getName()).handle((response, ex) -> { async("delete", entity, entity.getClass().getName()).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("删除实体失败", ex);
}
if (response != null) { if (response != null) {
return updateValue(entity, response); return updateValue(entity, response);
} }
@@ -116,6 +122,9 @@ public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel
public CompletableFuture<T> asyncFindById(Integer id) { public CompletableFuture<T> asyncFindById(Integer id) {
return async("findById", id, Integer.class).handle((response, ex) -> { return async("findById", id, Integer.class).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("查询实体失败", ex);
}
T newEntity = createNewEntity(); T newEntity = createNewEntity();
return updateValue(newEntity, response); return updateValue(newEntity, response);
}); });
@@ -145,6 +154,9 @@ public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel
public CompletableFuture<Page<T>> asyncFindAll(Map<String, Object> params, Pageable pageable) { public CompletableFuture<Page<T>> asyncFindAll(Map<String, Object> params, Pageable pageable) {
// 调用async方法发送WebSocket请求获取异步响应结果 // 调用async方法发送WebSocket请求获取异步响应结果
return async("findAll", params, PageArgument.of(pageable)).handle((response, ex) -> { return async("findAll", params, PageArgument.of(pageable)).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+findAll+调用失败", ex);
}
try { try {
// 将响应结果转换为PageContent对象使用当前类的createNewEntity方法创建实体实例 // 将响应结果转换为PageContent对象使用当前类的createNewEntity方法创建实体实例
PageContent<T> pageContent = of(response, objectMapper, this::createNewEntity); PageContent<T> pageContent = of(response, objectMapper, this::createNewEntity);
@@ -186,6 +198,9 @@ public class QueryService<T extends IdentityEntity, TV extends IdentityViewModel
// 调用async方法执行名为"count"的异步操作传入参数params // 调用async方法执行名为"count"的异步操作传入参数params
// 使用handle方法处理异步操作的结果或异常 // 使用handle方法处理异步操作的结果或异常
return async("count", params).handle((response, ex) -> { return async("count", params).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+count+调用失败", ex);
}
// 将响应结果转换为Long类型并返回 // 将响应结果转换为Long类型并返回
return response.asLong(); return response.asLong();
}); });

View File

@@ -1,7 +1,7 @@
package com.ecep.contract.service; package com.ecep.contract.service;
import com.ecep.contract.model.CompanyVendorFileTypeLocal; import com.ecep.contract.model.VendorFileTypeLocal;
import com.ecep.contract.vm.CompanyVendorFileTypeLocalViewModel; import com.ecep.contract.vm.VendorFileTypeLocalViewModel;
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
@@ -12,28 +12,28 @@ import java.util.List;
@Service @Service
@CacheConfig(cacheNames = "vendor-file-type") @CacheConfig(cacheNames = "vendor-file-type")
public class CompanyVendorFileTypeService extends QueryService<CompanyVendorFileTypeLocal, CompanyVendorFileTypeLocalViewModel> { public class VendorFileTypeService extends QueryService<VendorFileTypeLocal, VendorFileTypeLocalViewModel> {
@Cacheable(key = "#p0") @Cacheable(key = "#p0")
@Override @Override
public CompanyVendorFileTypeLocal findById(Integer id) { public VendorFileTypeLocal findById(Integer id) {
return super.findById(id); return super.findById(id);
} }
@Cacheable(key = "'all'") @Cacheable(key = "'all'")
@Override @Override
public List<CompanyVendorFileTypeLocal> findAll() { public List<VendorFileTypeLocal> findAll() {
return super.findAll(); return super.findAll();
} }
@Caching(put = {@CachePut(key = "#p0.id"), @CachePut(key = "'all'")}) @Caching(put = {@CachePut(key = "#p0.id"), @CachePut(key = "'all'")})
@Override @Override
public CompanyVendorFileTypeLocal save(CompanyVendorFileTypeLocal entity) { public VendorFileTypeLocal save(VendorFileTypeLocal entity) {
return super.save(entity); return super.save(entity);
} }
@Caching(put = {@CachePut(key = "#p0.id"), @CachePut(key = "'all'")}) @Caching(put = {@CachePut(key = "#p0.id"), @CachePut(key = "'all'")})
@Override @Override
public void delete(CompanyVendorFileTypeLocal entity) { public void delete(VendorFileTypeLocal entity) {
super.delete(entity); super.delete(entity);
} }
} }

View File

@@ -23,6 +23,9 @@ public class VendorGroupService extends QueryService<VendorGroup, VendorGroupVie
public VendorGroup findByCode(String code) { public VendorGroup findByCode(String code) {
try { try {
return async("findByCode", code, String.class).handle((response, ex) -> { return async("findByCode", code, String.class).handle((response, ex) -> {
if (ex != null) {
throw new RuntimeException("远程方法+findByCode+调用失败", ex);
}
VendorGroup newEntity = newInstance(); VendorGroup newEntity = newInstance();
return updateValue(newEntity, response); return updateValue(newEntity, response);
}).get(); }).get();

View File

@@ -1,12 +1,39 @@
package com.ecep.contract.service; package com.ecep.contract.service;
import com.ecep.contract.model.CompanyVendorFileTypeLocal; import com.ecep.contract.model.VendorTypeLocal;
import com.ecep.contract.vm.CompanyVendorFileTypeLocalViewModel; import com.ecep.contract.vm.VendorTypeLocalViewModel;
import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service import java.util.List;
@CacheConfig(cacheNames = "vendor-file-type")
public class CompanyVendorFileTypeService extends QueryService<CompanyVendorFileTypeLocal, CompanyVendorFileTypeLocalViewModel> {
@Service
@CacheConfig(cacheNames = "vendor-type")
public class VendorTypeService extends QueryService<VendorTypeLocal, VendorTypeLocalViewModel> {
@Cacheable(key = "#p0")
@Override
public VendorTypeLocal findById(Integer id) {
return super.findById(id);
}
@Cacheable(key = "'all'")
@Override
public List<VendorTypeLocal> findAll() {
return super.findAll();
}
@Caching(put = {@CachePut(key = "#p0.id"), @CachePut(key = "'all'")})
@Override
public VendorTypeLocal save(VendorTypeLocal entity) {
return super.save(entity);
}
@Caching(put = {@CachePut(key = "#p0.id"), @CachePut(key = "'all'")})
@Override
public void delete(VendorTypeLocal entity) {
super.delete(entity);
}
} }

View File

@@ -46,21 +46,7 @@ public class ContractRepairTask extends Tasker<Object> implements WebSocketClien
@Override @Override
protected Object execute(MessageHolder holder) throws Exception { protected Object execute(MessageHolder holder) throws Exception {
updateTitle("修复合同 " + contract.toPrettyString()); updateTitle("修复合同 " + contract.toPrettyString());
return callRemoteTask(holder); return callRemoteTask(holder, getLocale(), contract.getId());
} }
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

@@ -37,20 +37,7 @@ public class ContractSyncTask extends Tasker<Object> implements WebSocketClientT
protected Object execute(MessageHolder holder) throws Exception { protected Object execute(MessageHolder holder) throws Exception {
updateTitle("用友U8系统-同步合同"); updateTitle("用友U8系统-同步合同");
return callRemoteTask(holder); return callRemoteTask(holder, getLocale());
}
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.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.ecep.contract.controller.project.cost.ProjectCostImportItemsFromContractsTasker;
import com.ecep.contract.util.ProxyUtils; import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -731,15 +732,16 @@ public class ContractVerifyComm {
// //
boolean needImport = false; boolean needImport = false;
ProjectCost autoCost = getProjectCostService().findAutoCostByProject(project); ProjectCostService projectCostService = getProjectCostService();
ProjectCost autoCost = projectCostService.findAutoCostByProject(project);
if (autoCost == null) { if (autoCost == null) {
// 创建 V0 项目成本 // 创建 V0 项目成本
ProjectCost cost = getProjectCostService().newInstanceByProject(project); ProjectCost cost = projectCostService.newInstanceByProject(project);
cost.setVersion(0); cost.setVersion(0);
cost.setApplicant(getEmployeeService().findById(EmployeeService.DEFAULT_SYSTEM_EMPLOYEE_ID)); cost.setApplicant(getEmployeeService().findById(EmployeeService.DEFAULT_SYSTEM_EMPLOYEE_ID));
cost.setApplyTime(LocalDateTime.now()); cost.setApplyTime(LocalDateTime.now());
cost.setDescription("自动导入"); cost.setDescription("自动导入");
autoCost = getProjectCostService().save(cost); autoCost = projectCostService.save(cost);
needImport = true; needImport = true;
} else { } else {
// 检查 V0 项目成本 // 检查 V0 项目成本
@@ -754,13 +756,21 @@ public class ContractVerifyComm {
if (needImport && !autoCost.isImportLock()) { if (needImport && !autoCost.isImportLock()) {
holder.debug("更新V0项目成本"); holder.debug("更新V0项目成本");
getProjectCostService().updateAutoCost(project, holder); ProjectCost cost = projectCostService.findAutoCostByProject(project);
if (cost == null) {
cost = projectCostService.newInstanceByProject(project);
cost.setVersion(0);
cost = projectCostService.save(cost);
}
ProjectCostImportItemsFromContractsTasker tasker = new ProjectCostImportItemsFromContractsTasker();
tasker.setCost(cost);
} }
// 检查最新的项目成本,默认 V1 // 检查最新的项目成本,默认 V1
ProjectCost latestCost = getProjectCostService().findLatestByProject(project); ProjectCost latestCost = projectCostService.findLatestByProject(project);
if (latestCost == null) { if (latestCost == null) {
ProjectCost cost = getProjectCostService().newInstanceByProject(project); ProjectCost cost = projectCostService.newInstanceByProject(project);
cost.setVersion(1); cost.setVersion(1);
Employee applicant = project.getApplicant(); Employee applicant = project.getApplicant();
if (applicant == null) { if (applicant == null) {
@@ -768,7 +778,7 @@ public class ContractVerifyComm {
} }
cost.setApplicant(applicant); cost.setApplicant(applicant);
cost.setApplyTime(project.getCreated().atTime(LocalTime.now())); cost.setApplyTime(project.getCreated().atTime(LocalTime.now()));
latestCost = getProjectCostService().save(cost); latestCost = projectCostService.save(cost);
} else { } else {
// //
if (latestCost.getGrossProfitMargin() <= 0) { if (latestCost.getGrossProfitMargin() <= 0) {

View File

@@ -3,7 +3,7 @@ package com.ecep.contract.vm;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.model.CompanyVendor; import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.CompanyVendorFile; import com.ecep.contract.model.CompanyVendorFile;
@@ -21,7 +21,7 @@ public class CompanyVendorFileViewModel extends IdentityViewModel<CompanyVendorF
@ToString.Exclude @ToString.Exclude
private SimpleObjectProperty<CompanyVendor> vendor = new SimpleObjectProperty<>(); private SimpleObjectProperty<CompanyVendor> vendor = new SimpleObjectProperty<>();
private SimpleObjectProperty<CompanyVendorFileType> type = new SimpleObjectProperty<>(); private SimpleObjectProperty<VendorFileType> type = new SimpleObjectProperty<>();
private SimpleStringProperty filePath = new SimpleStringProperty(); private SimpleStringProperty filePath = new SimpleStringProperty();

View File

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

View File

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

View File

@@ -1,12 +1,19 @@
package com.ecep.contract; package com.ecep.contract;
public enum CompanyVendorFileType { /**
* 枚举类 VendorFileType用于表示不同类型的供应商文件
* 该枚举定义了两种文件类型:普通文件和评价表
*/
public enum VendorFileType {
/** /**
* 普通文件,一般文件 * 普通文件,一般文件
* 表示常规的供应商文件类型,不包含特殊用途或格式
*/ */
General, General,
/** /**
* 评价表; 评估表 * 评价表; 评估表
* 用于供应商评估或评价的特定表格文件
* 包含对供应商各方面表现的评估指标和内容
*/ */
EvaluationForm; EvaluationForm;
} }

View File

@@ -4,7 +4,7 @@ import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.util.HibernateProxyUtils; import com.ecep.contract.util.HibernateProxyUtils;
import jakarta.persistence.Column; import jakarta.persistence.Column;
@@ -30,7 +30,7 @@ import lombok.ToString;
@Entity @Entity
@Table(name = "COMPANY_VENDOR_FILE") @Table(name = "COMPANY_VENDOR_FILE")
@ToString @ToString
public class CompanyVendorFile implements CompanyBasicFile<CompanyVendorFileType>, Serializable { public class CompanyVendorFile implements CompanyBasicFile<VendorFileType>, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -44,7 +44,7 @@ public class CompanyVendorFile implements CompanyBasicFile<CompanyVendorFileType
@Column(name = "TYPE") @Column(name = "TYPE")
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private CompanyVendorFileType type; private VendorFileType type;
/** /**
* 文件路径 * 文件路径

View File

@@ -3,7 +3,7 @@ package com.ecep.contract.model;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.util.HibernateProxyUtils; import com.ecep.contract.util.HibernateProxyUtils;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
@@ -20,7 +20,7 @@ import lombok.ToString;
@Entity @Entity
@Table(name = "COMPANY_VENDOR_FILE_TYPE_LOCAL") @Table(name = "COMPANY_VENDOR_FILE_TYPE_LOCAL")
@ToString @ToString
public class CompanyVendorFileTypeLocal extends BaseEnumEntity<CompanyVendorFileType> implements Serializable { public class VendorFileTypeLocal extends BaseEnumEntity<VendorFileType> implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override
public final boolean equals(Object object) { public final boolean equals(Object object) {
@@ -31,7 +31,7 @@ public class CompanyVendorFileTypeLocal extends BaseEnumEntity<CompanyVendorFile
if (HibernateProxyUtils.isNotEffectiveClassEquals(object, this)) { if (HibernateProxyUtils.isNotEffectiveClassEquals(object, this)) {
return false; return false;
} }
CompanyVendorFileTypeLocal that = (CompanyVendorFileTypeLocal) object; VendorFileTypeLocal that = (VendorFileTypeLocal) object;
return getId() != null && Objects.equals(getId(), that.getId()); return getId() != null && Objects.equals(getId(), that.getId());
} }

View File

@@ -18,7 +18,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.ecep.contract.CompanyCustomerFileType; import com.ecep.contract.CompanyCustomerFileType;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.SpringApp; import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.company.CompanyFileUtils; import com.ecep.contract.ds.company.CompanyFileUtils;
import com.ecep.contract.ds.other.repository.HolidayTableRepository; import com.ecep.contract.ds.other.repository.HolidayTableRepository;
@@ -162,7 +162,7 @@ public abstract class CompanyBasicService {
* @param <F> 文件类 * @param <F> 文件类
* @return 是否修改了 * @return 是否修改了
* @see CompanyVendorFile * @see CompanyVendorFile
* @see CompanyVendorFileType * @see VendorFileType
* @see CompanyCustomerFile * @see CompanyCustomerFile
* @see CompanyCustomerFileType * @see CompanyCustomerFileType
*/ */

View File

@@ -46,7 +46,7 @@ public class ContractFileTypeService
@Cacheable(key = "'all-'+#p0.getLanguage()") @Cacheable(key = "'all-'+#p0.getLanguage()")
public Map<ContractFileType, ContractFileTypeLocal> findAll(Locale locale) { public Map<ContractFileType, ContractFileTypeLocal> findAll(Locale locale) {
return repository.getCompleteMapByLocal(locale.getLanguage()); return repository.getCompleteMapByLocal(locale.toLanguageTag());
} }
@Cacheable(key = "#p0") @Cacheable(key = "#p0")

View File

@@ -31,10 +31,8 @@ public class ContractRepairTask extends AbstContractRepairTasker implements WebS
} }
public void init(JsonNode argsNode) { public void init(JsonNode argsNode) {
int contractId = argsNode.get(1).asInt(); int contractId = argsNode.get(0).asInt();
contract = getCachedBean(ContractService.class).findById(contractId); contract = getCachedBean(ContractService.class).findById(contractId);
String lang = argsNode.get(2).asText();
setLocale(Locale.forLanguageTag(lang));
} }
@Override @Override

View File

@@ -16,7 +16,6 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
public class ContractVerifyTasker extends Tasker<Object> implements WebSocketServerTasker { public class ContractVerifyTasker extends Tasker<Object> implements WebSocketServerTasker {
@Getter @Getter
@Setter @Setter
private Contract contract; private Contract contract;
@@ -64,7 +63,7 @@ public class ContractVerifyTasker extends Tasker<Object> implements WebSocketSer
@Override @Override
public void init(JsonNode argsNode) { public void init(JsonNode argsNode) {
int contractId = argsNode.get(1).asInt(); int contractId = argsNode.get(0).asInt();
contract = getCachedBean(ContractService.class).findById(contractId); contract = getCachedBean(ContractService.class).findById(contractId);
} }

View File

@@ -8,9 +8,14 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.ecep.contract.service.WebSocketServerTasker;
import com.ecep.contract.ui.MessageHolderImpl;
import com.fasterxml.jackson.databind.JsonNode;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import com.ecep.contract.MessageHolder; import com.ecep.contract.MessageHolder;
@@ -32,22 +37,18 @@ import com.ecep.contract.util.TaxRateUtils;
import lombok.Setter; import lombok.Setter;
public class ProjectCostImportItemsFromContractsTasker extends Tasker<Void> { public class ProjectCostImportItemsFromContractsTasker extends Tasker<Object> implements WebSocketServerTasker {
@Setter
private ProjectCostService costService;
@Setter
private ContractService contractService;
@Setter
private ProjectCostItemService itemService;
@Setter
private ContractItemService contractItemService;
@Setter @Setter
private Supplier<Employee> currentUser; private Supplier<Employee> currentUser;
@Setter
private InventoryService inventoryService;
@Setter @Setter
ProjectCost cost; ProjectCost cost;
AtomicBoolean verified = new AtomicBoolean(true);
@Override
public void init(JsonNode argsNode) {
int contractId = argsNode.get(0).asInt();
cost = getCachedBean(ProjectCostService.class).findById(contractId);
}
@Override @Override
protected Void execute(MessageHolder holder) throws Exception { protected Void execute(MessageHolder holder) throws Exception {
@@ -336,42 +337,28 @@ public class ProjectCostImportItemsFromContractsTasker extends Tasker<Void> {
} }
ProjectCostService getCostService() { ProjectCostService getCostService() {
if (costService == null) { return getCachedBean(ProjectCostService.class);
costService = getBean(ProjectCostService.class);
}
return costService;
} }
public ProjectCostItemService getItemService() { public ProjectCostItemService getItemService() {
if (itemService == null) { return getCachedBean(ProjectCostItemService.class);
itemService = getBean(ProjectCostItemService.class);
}
return itemService;
} }
ContractService getContractService() { ContractService getContractService() {
if (contractService == null) { return getCachedBean(ContractService.class);
contractService = getBean(ContractService.class);
}
return contractService;
} }
ContractItemService getContractItemService() { ContractItemService getContractItemService() {
if (contractItemService == null) { return getCachedBean(ContractItemService.class);
contractItemService = getBean(ContractItemService.class);
}
return contractItemService;
} }
InventoryService getInventoryService() { InventoryService getInventoryService() {
if (inventoryService == null) { return getCachedBean(InventoryService.class);
inventoryService = getBean(InventoryService.class);
}
return inventoryService;
} }
public ProjectCostItem save(ProjectCostItem entity) { public ProjectCostItem save(ProjectCostItem entity) {
return getItemService().save(entity); return getItemService().save(entity);
} }
} }

View File

@@ -298,46 +298,6 @@ public class ProjectService implements IEntityService<Project>, QueryService<Pro
return project; return project;
} }
public String makeProjectCode(Project project) {
StringBuilder sb = new StringBuilder();
sb.append(project.getSaleType().getCode());
sb.append(project.getCodeYear());
if (project.getCodeSequenceNumber() < 10) {
sb.append("0");
}
if (project.getCodeSequenceNumber() < 100) {
sb.append("0");
}
sb.append(project.getCodeSequenceNumber());
return sb.toString();
}
public File searchPath(Project project) {
ProjectSaleType saleType = project.getSaleType();
if (saleType == null) {
return null;
}
if (!Hibernate.isInitialized(saleType)) {
saleType = projectSaleTypeService.findById(saleType.getId());
project.setSaleType(saleType);
}
if (!StringUtils.hasText(saleType.getPath())) {
return null;
}
File path = new File(saleType.getPath());
if (saleType.isStoreByYear()) {
path = new File(path, "20" + project.getCodeYear());
if (!path.exists()) {
path.mkdir();// 创建目录
}
}
String projectCode = makeProjectCode(project);
// 检索目录
File[] files = path.listFiles(f -> f.isDirectory() && f.getName().contains(projectCode));
if (files != null && files.length > 0) {
path = files[0];
}
return path;
}
} }

View File

@@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.model.CompanyVendor; import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.CompanyVendorFile; import com.ecep.contract.model.CompanyVendorFile;
@@ -16,7 +16,7 @@ public interface CompanyVendorFileRepository
List<CompanyVendorFile> findAllByVendorId(int vendorId); List<CompanyVendorFile> findAllByVendorId(int vendorId);
List<CompanyVendorFile> findAllByVendorAndType(CompanyVendor vendor, CompanyVendorFileType type); List<CompanyVendorFile> findAllByVendorAndType(CompanyVendor vendor, VendorFileType type);
List<CompanyVendorFile> findByVendorId(int vendorId); List<CompanyVendorFile> findByVendorId(int vendorId);
} }

View File

@@ -2,21 +2,21 @@ package com.ecep.contract.ds.vendor.repository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.ecep.contract.CompanyVendorFileType; import com.ecep.contract.VendorFileType;
import com.ecep.contract.ds.other.repository.BaseEnumEntityRepository; import com.ecep.contract.ds.other.repository.BaseEnumEntityRepository;
import com.ecep.contract.model.CompanyVendorFileTypeLocal; import com.ecep.contract.model.VendorFileTypeLocal;
@Repository @Repository
public interface CompanyVendorFileTypeLocalRepository public interface CompanyVendorFileTypeLocalRepository
extends BaseEnumEntityRepository<CompanyVendorFileType, CompanyVendorFileTypeLocal, Integer> { extends BaseEnumEntityRepository<VendorFileType, VendorFileTypeLocal, Integer> {
@Override @Override
default CompanyVendorFileType[] getEnumConstants() { default VendorFileType[] getEnumConstants() {
return CompanyVendorFileType.values(); return VendorFileType.values();
} }
@Override @Override
default CompanyVendorFileTypeLocal newEntity() { default VendorFileTypeLocal newEntity() {
return new CompanyVendorFileTypeLocal(); return new VendorFileTypeLocal();
} }
} }

View File

@@ -7,7 +7,6 @@ import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import com.ecep.contract.*; import com.ecep.contract.*;
import com.ecep.contract.model.CompanyVendorApprovedList;
import com.ecep.contract.util.SpecificationUtils; import com.ecep.contract.util.SpecificationUtils;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -65,7 +64,7 @@ public class CompanyVendorFileService implements IEntityService<CompanyVendorFil
} }
// 添加额外的参数过滤 // 添加额外的参数过滤
if (paramsNode.has("type")) { if (paramsNode.has("type")) {
CompanyVendorFileType type = CompanyVendorFileType.valueOf(paramsNode.get("type").asText()); VendorFileType type = VendorFileType.valueOf(paramsNode.get("type").asText());
spec = SpecificationUtils.and(spec, (root, query, builder) -> builder.equal(root.get("type"), type)); spec = SpecificationUtils.and(spec, (root, query, builder) -> builder.equal(root.get("type"), type));
} }
spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "valid"); spec = SpecificationUtils.andFieldEqualParam(spec, paramsNode, "valid");
@@ -97,7 +96,7 @@ public class CompanyVendorFileService implements IEntityService<CompanyVendorFil
return repository.findAll(spec, sort); return repository.findAll(spec, sort);
} }
public List<CompanyVendorFile> findAllByVendorAndType(CompanyVendor vendor, CompanyVendorFileType type) { public List<CompanyVendorFile> findAllByVendorAndType(CompanyVendor vendor, VendorFileType type) {
return repository.findAllByVendorAndType(vendor, type); return repository.findAllByVendorAndType(vendor, type);
} }
@@ -116,7 +115,7 @@ public class CompanyVendorFileService implements IEntityService<CompanyVendorFil
} }
// 查询所有评价表 // 查询所有评价表
List<CompanyVendorFile> files = findAllByVendorAndType(companyVendor, CompanyVendorFileType.EvaluationForm); List<CompanyVendorFile> files = findAllByVendorAndType(companyVendor, VendorFileType.EvaluationForm);
if (files == null || files.isEmpty()) { if (files == null || files.isEmpty()) {
holder.error("未见供应商评价"); holder.error("未见供应商评价");
return; return;
@@ -161,7 +160,7 @@ public class CompanyVendorFileService implements IEntityService<CompanyVendorFil
return null; return null;
} }
// 检索评价表 // 检索评价表
List<CompanyVendorFile> files = findAllByVendorAndType(companyVendor, CompanyVendorFileType.EvaluationForm); List<CompanyVendorFile> files = findAllByVendorAndType(companyVendor, VendorFileType.EvaluationForm);
CompanyVendorFile latestFile = files.stream() CompanyVendorFile latestFile = files.stream()
.filter(v -> v.getSignDate() != null && v.isValid()) .filter(v -> v.getSignDate() != null && v.isValid())
.max(Comparator.comparing(CompanyVendorFile::getSignDate)) .max(Comparator.comparing(CompanyVendorFile::getSignDate))

View File

@@ -190,7 +190,7 @@ public class CompanyVendorService extends CompanyBasicService implements IEntity
@Override @Override
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file, Consumer<String> status) { protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file, Consumer<String> status) {
dbFile.setType((T) CompanyVendorFileType.General); dbFile.setType((T) VendorFileType.General);
fillFile(dbFile, file, null, status); fillFile(dbFile, file, null, status);
companyVendorFileService.save((CompanyVendorFile) dbFile); companyVendorFileService.save((CompanyVendorFile) dbFile);
return true; return true;
@@ -199,7 +199,7 @@ public class CompanyVendorService extends CompanyBasicService implements IEntity
@Override @Override
protected <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList, Consumer<String> status) { protected <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList, Consumer<String> status) {
CompanyVendorFile vendorFile = new CompanyVendorFile(); CompanyVendorFile vendorFile = new CompanyVendorFile();
vendorFile.setType(CompanyVendorFileType.General); vendorFile.setType(VendorFileType.General);
vendorFile.setFilePath(file.getAbsolutePath()); vendorFile.setFilePath(file.getAbsolutePath());
fillFile(vendorFile, file, fileList, status); fillFile(vendorFile, file, fileList, status);
return (F) vendorFile; return (F) vendorFile;
@@ -208,8 +208,8 @@ public class CompanyVendorService extends CompanyBasicService implements IEntity
@Override @Override
protected <T, F extends CompanyBasicFile<T>> boolean setFileTypeAsEvaluationForm(F file) { protected <T, F extends CompanyBasicFile<T>> boolean setFileTypeAsEvaluationForm(F file) {
T type = file.getType(); T type = file.getType();
if (type != CompanyVendorFileType.EvaluationForm) { if (type != VendorFileType.EvaluationForm) {
file.setType((T) CompanyVendorFileType.EvaluationForm); file.setType((T) VendorFileType.EvaluationForm);
return true; return true;
} }
return false; return false;

View File

@@ -2,6 +2,7 @@ package com.ecep.contract.service;
import com.ecep.contract.Message; import com.ecep.contract.Message;
import com.ecep.contract.constant.WebSocketConstant; import com.ecep.contract.constant.WebSocketConstant;
import com.ecep.contract.ui.Tasker;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -13,7 +14,11 @@ import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@Service @Service
@@ -29,7 +34,9 @@ public class WebSocketServerTaskManager implements InitializingBean {
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
taskClzMap = Map.of( taskClzMap = Map.of(
"ContractSyncTask", "com.ecep.contract.cloud.u8.ContractSyncTask", "ContractSyncTask", "com.ecep.contract.cloud.u8.ContractSyncTask",
"ContractRepairTask", "com.ecep.contract.ds.contract.tasker.ContractRepairTask" "ContractRepairTask", "com.ecep.contract.ds.contract.tasker.ContractRepairTask",
"ContractVerifyTask", "com.ecep.contract.ds.contract.tasker.ContractVerifyTask",
"ProjectCostImportItemsFromContractsTasker", "com.ecep.contract.ds.project.ProjectCostImportItemsFromContractsTasker"
); );
} }
@@ -62,7 +69,6 @@ public class WebSocketServerTaskManager implements InitializingBean {
JsonNode argsNode = jsonNode.get(WebSocketConstant.ARGUMENTS_FIELD_NAME); JsonNode argsNode = jsonNode.get(WebSocketConstant.ARGUMENTS_FIELD_NAME);
String taskName = argsNode.get(0).asText(); String taskName = argsNode.get(0).asText();
String clzName = taskClzMap.get(taskName); String clzName = taskClzMap.get(taskName);
if (clzName == null) { if (clzName == null) {
throw new IllegalArgumentException("未知的任务类型: " + taskName); throw new IllegalArgumentException("未知的任务类型: " + taskName);
@@ -77,15 +83,32 @@ public class WebSocketServerTaskManager implements InitializingBean {
throw new IllegalArgumentException("任务类型: " + taskName + ", class: " + clzName + " 实例化失败"); throw new IllegalArgumentException("任务类型: " + taskName + ", class: " + clzName + " 实例化失败");
} }
if (tasker instanceof Tasker<?> t) {
String locale = argsNode.get(1).asText();
t.setLocale(Locale.forLanguageTag(locale));
}
if (tasker instanceof WebSocketServerTasker t) { if (tasker instanceof WebSocketServerTasker t) {
t.setTitleHandler(title -> sendToSession(session, sessionId, "title", title)); t.setTitleHandler(title -> sendToSession(session, sessionId, "title", title));
t.setMessageHandler(msg -> sendMessageToSession(session, sessionId, msg)); t.setMessageHandler(msg -> sendMessageToSession(session, sessionId, msg));
t.setPropertyHandler((name, value) -> sendToSession(session, sessionId, "property", name, value)); t.setPropertyHandler((name, value) -> sendToSession(session, sessionId, "property", name, value));
t.setProgressHandler((current, total) -> sendToSession(session, sessionId, "progress", current, total)); t.setProgressHandler((current, total) -> sendToSession(session, sessionId, "progress", current, total));
t.init(argsNode); t.init(argsNode.get(2));
scheduledExecutorService.submit(t);
} }
if (tasker instanceof Callable<?> callable) {
Thread.ofVirtual().start(() -> {
try {
sendToSession(session, sessionId, "start");
callable.call();
sendToSession(session, sessionId, "done");
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
} }
private boolean sendMessageToSession(WebSocketSession session, String sessionId, Message msg) { private boolean sendMessageToSession(WebSocketSession session, String sessionId, Message msg) {