重新初始化项目

This commit is contained in:
2025-08-22 19:55:19 +08:00
commit 65bc67460b
805 changed files with 83402 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
package com.ecep.contract.manager.ds;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.config.BootstrapMode;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import static com.ecep.contract.manager.AppV2.*;
@Configuration
@EnableJpaRepositories(bootstrapMode = BootstrapMode.LAZY)
public class DsRepositoriesConfig {
private static final Logger logger = LoggerFactory.getLogger(DsRepositoriesConfig.class);
@Bean
// @ConfigurationProperties(prefix = "spring.datasource")
@Primary
public DataSource dataSource(Environment env) {
if (logger.isDebugEnabled()) {
logger.debug("SpringApp.dataSource, env:{}", env);
}
String host = env.getProperty("db.server.host", DEFAULT_DB_HOST);
String port = env.getProperty("db.server.port", DEFAULT_DB_PORT);
String database = env.getProperty("db.server.database", DEFAULT_DB_DATABASE);
String username = env.getProperty("db.server.username", DEFAULT_DB_USERNAME);
String password = env.getProperty("db.server.password", DEFAULT_DB_PASSWORD);
String url = "jdbc:mysql://" + host + ":" + port + "/" + database;
if (logger.isDebugEnabled()) {
logger.debug("db server url:{},user:{}", url, username);
}
return DataSourceBuilder.create()
.type(HikariDataSource.class)
.url(url)
.username(username)
.password(password)
.driverClassName("com.mysql.cj.jdbc.Driver")
.build();
}
@Primary
@Bean
public JdbcTemplate jdbcTemplate(@Qualifier("dataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}

View File

@@ -0,0 +1,26 @@
package com.ecep.contract.manager.ds;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.time.MonthDay;
import java.time.format.DateTimeFormatter;
@Converter(autoApply = true)
public class MonthDayConverter implements AttributeConverter<MonthDay, String> {
// 定义日期格式(月-日,两位数)
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("MM-dd");
@Override
public String convertToDatabaseColumn(MonthDay attribute) {
// 将 MonthDay 转换为数据库存储的字符串MM-dd
return attribute != null ? attribute.format(FORMATTER) : null;
}
@Override
public MonthDay convertToEntityAttribute(String dbData) {
// 将数据库字符串MM-dd转换为 MonthDay
return dbData != null ? MonthDay.parse(dbData, FORMATTER) : null;
}
}

View File

@@ -0,0 +1,9 @@
package com.ecep.contract.manager.ds;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.ListCrudRepository;
public interface MyRepository<T, ID> extends ListCrudRepository<T, ID>, JpaSpecificationExecutor<T> {
}

View File

@@ -0,0 +1,15 @@
package com.ecep.contract.manager.ds.company;
/**
* Date : 2024/2/3
*/
public enum BlackReasonType {
/**
* 黑名单
*/
BLACK,
/**
* 警示名单
*/
GRAY
}

View File

@@ -0,0 +1,19 @@
package com.ecep.contract.manager.ds.company;
import com.ecep.contract.manager.ds.company.model.CompanyContact;
import com.ecep.contract.manager.ds.company.service.CompanyContactService;
import com.ecep.contract.manager.ds.other.EntityStringConverter;
public class CompanyContactStringConverter extends EntityStringConverter<CompanyContact> {
public CompanyContactStringConverter() {
}
public CompanyContactStringConverter(CompanyContactService service) {
setInitialized(employee -> service.findById(employee.getId()));
// setFromString(service::findByName);
}
}

View File

@@ -0,0 +1,35 @@
package com.ecep.contract.manager.ds.company;
/**
* 公司文件类型(资质文件)
*/
public enum CompanyFileType {
/**
* 普通文件,一般文件
*/
General,
/**
* 资信评估
*/
CreditReport,
/**
* 营业执照
*/
BusinessLicense,
/**
* 资质证书
*/
QualificationCertificate,
/**
* 企业信用信息公示报告
*/
CreditInfoPublicityReport,
/**
* 操作证
*/
OperationCertificate,
/**
* 框架协议
*/
FrameworkAgreement;
}

View File

@@ -0,0 +1,212 @@
package com.ecep.contract.manager.ds.company;
import com.ecep.contract.manager.cloud.tyc.CloudTycService;
import com.ecep.contract.manager.ds.company.model.CompanyFile;
import com.ecep.contract.manager.ds.company.service.CompanyFileService;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.ecep.contract.manager.ds.company.CompanyFileType.CreditReport;
public class CompanyFileUtils {
public final static String PDF = ".pdf";
public final static String DOC = ".doc";
public final static String DOCX = ".docx";
public final static String XLS = ".xls";
public final static String XLSX = ".xlsx";
public final static String PNG = ".png";
public final static String JPG = ".jpg";
public final static String JPEG = ".jpeg";
public final static String JSON = ".json";
public final static String FILE_DB_THUMBS = "Thumbs.db";
public final static String FILE_DB_JSON = "db.json";
public final static String FILE_BLACK_LIST_JSON = "black_list.json";
public final static String FILE_B1001_JSON = "b1001.json";
public static CompanyFile fillType(String fileName, String companyName, File destDir) {
CompanyFile companyFile = new CompanyFile();
if (isTycReport(fileName, companyName)) {
File dest = new File(destDir, fileName);
companyFile.setType(CreditReport);
companyFile.setFilePath(dest.getAbsolutePath());
return companyFile;
}
// 包含公司名称 和 天眼查 的文件
if (fileName.contains(companyName) && fileName.contains(CloudTycService.NAME)) {
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm");
int idx = fileName.indexOf("报告");
String destName = (idx > 0 ? fileName.substring(0, fileName.indexOf("报告") + 2) + "_" : "") +
companyName + "_天眼查_" + dateTime.format(fmt) + "." + StringUtils.getFilenameExtension(fileName);
}
for (CompanyFileType value : CompanyFileType.values()) {
}
return null;
}
/**
* 检查文件是否符合后缀要求
*
* @param name 文件名
* @param fileExtensions 后缀
*/
public static boolean withExtensions(String name, String... fileExtensions) {
for (String fn : fileExtensions) {
if (name.endsWith(fn)) {
return true;
}
}
return false;
}
/**
* 从文件名判断是否是天眼查的报告文件
*/
public static boolean isTycReport(String fileName, String companyName) {
// 文件名中必须包含 天眼查 字样
if (!fileName.contains(CloudTycService.NAME)) {
return false;
}
// 文件名中必须包含 公司名称
if (!fileName.contains(companyName)) {
return false;
}
// 文件名后缀需符合要求
return withExtensions(fileName, PDF, DOC, DOCX);
}
public static boolean isCompanyFile(File file) {
String fileName = file.getName();
if (fileName.equals(FILE_DB_JSON)) {
return true;
}
if (fileName.equals(FILE_B1001_JSON)) {
return true;
}
if (fileName.equals(FILE_BLACK_LIST_JSON)) {
return true;
}
if (fileName.equals("合同列表.json")) {
return true;
}
//营业执照
if (fileName.contains(CompanyFileService.BUSINESS_LICENSE)) {
return true;
}
// 操作证
if (fileName.contains(CompanyFileService.OPERATION_CERTIFICATE)) {
return true;
}
// 许可证
if (fileName.contains(CompanyFileService.PERMIT_CERTIFICATE)) {
return true;
}
// 登记证
if (fileName.contains(CompanyFileService.REGISTRATION_CERTIFICATE)) {
return true;
}
// 组织机构代码证
if (fileName.contains(CompanyFileService.ORGANIZATION_CODE_CERTIFICATE)) {
return true;
}
return false;
}
/**
* 根据文件名中提取的日期信息更新对象的日期,如果文件名称中没有可识别的日期,则不进行任何更新
* 日期提取方法参考 {@link MyDateTimeUtils#pickLocalDate(String)}
*
* @param file 日期来源文件对象
* @param vendorFile 要更新的对象
* @param getter 对象的日期获取方法
* @param setter 对象的日期设置方法
* @param <T> 对象泛型
* @return 是否更新了日期
*/
public static <T> boolean fillApplyDateAbsent(File file, T vendorFile, Function<T, LocalDate> getter, BiConsumer<T, LocalDate> setter) {
LocalDate applyDate = getter.apply(vendorFile);
if (applyDate != null) {
return false;
}
boolean modified = false;
String fileName = file.getName();
// 从文件的名称中提取日期
LocalDate picked = MyDateTimeUtils.pickLocalDate(fileName);
if (picked != null) {
// 如果提取出的日期不为空则通过setter函数将这个日期设置到vendorFile中并将modified标志设置为true。
setter.accept(vendorFile, picked);
modified = true;
}
return modified;
}
public static boolean isHiddenFile(File file) {
String fileName = file.getName();
if (fileName.equals(FILE_DB_THUMBS)) {
return true;
}
return fileName.startsWith("~$");
}
public static String escapeFileName(String fileName) {
String patternStr = "[\\\\/:*?\"<>|]";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(fileName);
return matcher.replaceAll("_");
}
/**
* 返回 district 中关于省份的部门zi
*
* @param district 地区
* @return 省份名称
*/
public static String getParentPrefixByDistrict(String district) {
int indexOf = district.indexOf("");
if (indexOf != -1) {
return district.substring(0, indexOf);
}
indexOf = district.indexOf("自治区");
if (indexOf != -1) {
return district.substring(0, 2);
}
indexOf = district.indexOf("");
if (indexOf != -1) {
return district.substring(0, indexOf);
}
return null;
}
public static boolean exists(String path) {
if (!StringUtils.hasText(path)) {
return false;
}
File file = new File(path);
return file.exists();
}
}

View File

@@ -0,0 +1,28 @@
package com.ecep.contract.manager.ds.company;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.other.EntityStringConverter;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Lazy
@Component
public class CompanyStringConverter extends EntityStringConverter<Company> {
@Lazy
@Autowired
CompanyService service;
public CompanyStringConverter() {
}
@PostConstruct
private void init() {
setInitialized(project -> service.findById(project.getId()));
setSuggestion(service::search);
setFromString(service::findByName);
}
}

View File

@@ -0,0 +1,21 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.vo.CompanyViewModel;
import com.ecep.contract.manager.ui.AbstEntityBasedTabSkin;
import com.ecep.contract.manager.ui.TabSkin;
import lombok.Setter;
public abstract class AbstCompanyBasedTabSkin
extends AbstEntityBasedTabSkin<CompanyWindowController, Company, CompanyViewModel>
implements TabSkin {
public AbstCompanyBasedTabSkin(CompanyWindowController controller) {
super(controller);
}
protected CompanyService getCompanyService() {
return controller.getViewModelService();
}
}

View File

@@ -0,0 +1,56 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.vo.CompanyBasedViewModel;
import com.ecep.contract.manager.ds.company.vo.CompanyViewModel;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import com.ecep.contract.manager.ui.AbstEntityTableTabSkin;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.TableOfTabSkin;
import com.ecep.contract.manager.util.SpecificationUtils;
import lombok.Setter;
import org.springframework.data.jpa.domain.Specification;
public abstract class AbstCompanyTableTabSkin<T extends IdentityEntity, TV extends IdentityViewModel<T>>
extends AbstEntityTableTabSkin<CompanyWindowController, Company, CompanyViewModel, T, TV>
implements TabSkin, TableOfTabSkin<Company, T, TV> {
@Setter
private CompanyService companyService;
public AbstCompanyTableTabSkin(CompanyWindowController controller) {
super(controller);
viewModel = controller.getViewModel();
}
@Override
protected TV createNewViewModel() {
TV model = super.createNewViewModel();
if (model instanceof CompanyBasedViewModel m) {
m.getCompany().set(getEntity());
}
return model;
}
protected CompanyService getCompanyService(){
return getParentService();
}
protected CompanyService getParentService() {
if (companyService == null) {
companyService = getBean(CompanyService.class);
}
return companyService;
}
@Override
public Specification<T> getSpecification(Company parent) {
return SpecificationUtils.and(getSpecification(), (root, query, builder) -> {
return builder.equal(root.get("company"), parent);
});
}
}

View File

@@ -0,0 +1,83 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyOldNameService;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.vo.CompanyViewModel;
import com.ecep.contract.manager.ui.AbstEntityManagerSkin;
import com.ecep.contract.manager.ui.ManagerSkin;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.Alert;
import javafx.scene.control.TextInputDialog;
import lombok.Setter;
import java.util.List;
import java.util.Optional;
public class CompanyManagerSkin
extends AbstEntityManagerSkin<Company, CompanyViewModel, CompanyManagerSkin, CompanyManagerWindowController>
implements ManagerSkin {
@Setter
private CompanyOldNameService companyOldNameService;
public CompanyManagerSkin(CompanyManagerWindowController controller) {
super(controller);
}
public CompanyService getCompanyService() {
return controller.getViewModelService();
}
public CompanyOldNameService getCompanyOldNameService() {
if (companyOldNameService == null) {
companyOldNameService = getBean(CompanyOldNameService.class);
}
return companyOldNameService;
}
@Override
public void initializeTable() {
controller.idColumn.setCellValueFactory(param -> param.getValue().getId());
controller.nameColumn.setCellValueFactory(param -> param.getValue().getName());
controller.uniscidColumn.setCellValueFactory(param -> param.getValue().getUid());
controller.entStatusColumn.setCellValueFactory(param -> param.getValue().getEntStatus());
controller.createdColumn.setCellValueFactory(param -> param.getValue().getCreated());
controller.memoColumn.setCellValueFactory(param -> param.getValue().getMemo());
Platform.runLater(() -> {
getTableView().getSortOrder().add(controller.createdColumn);
});
}
@Override
protected void onTableRowDoubleClickedAction(CompanyViewModel item) {
showInOwner(CompanyWindowController.class, item);
}
@Override
protected void onTableCreateNewAction(ActionEvent event) {
Platform.runLater(() -> {
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("新建公司");
dialog.setHeaderText("请输入新建的公司名称,请输入公司名字全称");
Optional<String> optional = dialog.showAndWait();
if (optional.isPresent()) {
CompanyService companyService = getCompanyService();
String newCompanyName = optional.get();
List<Company> list = companyService.findAllByName(newCompanyName);
if (list == null || list.isEmpty()) {
// 未登记过
Company company = companyService.createNewCompany(newCompanyName);
Company saved = companyService.save(company);
CompanyWindowController.show(saved, getTableView().getScene().getWindow());
} else {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("新建公司");
alert.setHeaderText("公司名称 " + newCompanyName + " 已经存在,是否打开公司页面");
}
}
});
}
}

View File

@@ -0,0 +1,75 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.tasker.CompanyFilesRebuildTasker;
import com.ecep.contract.manager.ds.company.vo.CompanyViewModel;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ui.AbstManagerWindowController;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.UITools;
import javafx.event.ActionEvent;
import javafx.scene.control.TableColumn;
import javafx.stage.Stage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/company/company-manager.fxml")
public class CompanyManagerWindowController
extends AbstManagerWindowController<Company, CompanyViewModel, CompanyManagerSkin> {
// columns
public TableColumn<CompanyViewModel, Number> idColumn;
public TableColumn<CompanyViewModel, String> nameColumn;
public TableColumn<CompanyViewModel, String> uniscidColumn;
public TableColumn<CompanyViewModel, String> entStatusColumn;
public TableColumn<CompanyViewModel, LocalDate> createdColumn;
public TableColumn<CompanyViewModel, String> memoColumn;
@Autowired
private CompanyService companyService;
@Override
public CompanyService getViewModelService() {
return companyService;
}
@Override
public void show(Stage stage) {
super.show(stage);
getTitle().set("公司管理");
}
@Override
protected CompanyManagerSkin createDefaultSkin() {
return new CompanyManagerSkin(this);
}
public void onCompanyCreateNewAction(ActionEvent event) {
getSkin().onTableCreateNewAction(event);
}
/**
* 对所有公司的文件进行重置
* <p>
* 弹出对话框模式,对话框中有进度条和重置的消息
*
* @param event 事件
*/
public void onReBuildFilesAction(ActionEvent event) {
CompanyFilesRebuildTasker task = new CompanyFilesRebuildTasker();
UITools.showTaskDialogAndWait("公司文件重置", task, null);
}
public void onVerifyAction(ActionEvent event) {
show(CompanyVerifyWindowController.class, null);
}
}

View File

@@ -0,0 +1,113 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.controller.bank_account.BankAccountWindowController;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBankAccount;
import com.ecep.contract.manager.ds.company.service.CompanyBankAccountService;
import com.ecep.contract.manager.ds.company.vo.CompanyBankAccountViewModel;
import com.ecep.contract.manager.ds.other.model.Bank;
import com.ecep.contract.manager.ds.other.service.BankService;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import org.hibernate.Hibernate;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* 子合同
*/
@FxmlPath("/ui/company/company-tab-bank-account.fxml")
public class CompanyTabSkinBankAccount
extends AbstCompanyTableTabSkin<CompanyBankAccount, CompanyBankAccountViewModel>
implements TabSkin, EditableEntityTableTabSkin<CompanyBankAccount, CompanyBankAccountViewModel> {
/**
* 银行账户
*/
public TableColumn<CompanyBankAccountViewModel, Number> bankAccountTable_idColumn;
public TableColumn<CompanyBankAccountViewModel, Bank> bankAccountTable_bankColumn;
public TableColumn<CompanyBankAccountViewModel, String> bankAccountTable_openingBankColumn;
public TableColumn<CompanyBankAccountViewModel, String> bankAccountTable_accountColumn;
public TextField bankAccountSearchKeyField;
public Button bankAccountSearchBtn;
public MenuItem bankAccountTable_menu_refresh;
public MenuItem bankAccountTable_menu_add;
public MenuItem bankAccountTable_menu_del;
@Setter
private CompanyBankAccountService bankAccountService;
@Setter
private BankService bankService;
public CompanyTabSkinBankAccount(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.bankAccountTab;
}
@Override
public void initializeTab() {
bankAccountSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
bankAccountSearchBtn.fire();
}
});
bankAccountSearchBtn.setOnAction(this::onTableRefreshAction);
bankAccountTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
bankAccountTable_bankColumn.setCellValueFactory(param -> param.getValue().getBank());
bankAccountTable_bankColumn.setCellFactory(param -> new TableCell<>() {
@Override
protected void updateItem(Bank item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
return;
}
if (!Hibernate.isInitialized(item)) {
item = getBankService().findById(item.getId());
setItem(item);
}
setText(item.getName());
}
});
bankAccountTable_openingBankColumn.setCellValueFactory(param -> param.getValue().getOpeningBank());
bankAccountTable_accountColumn.setCellValueFactory(param -> param.getValue().getAccount());
bankAccountTable_menu_refresh.setOnAction(this::onTableRefreshAction);
bankAccountTable_menu_add.setOnAction(this::onTableAddAction);
bankAccountTable_menu_del.setOnAction(this::onTableDeleteAction);
super.initializeTab();
}
@Override
protected void onTableRowDoubleClickedAction(CompanyBankAccountViewModel item) {
BankAccountWindowController.show(item, controller.root.getScene().getWindow());
}
public CompanyBankAccountService getViewModelService() {
if (bankAccountService == null) {
bankAccountService = getBean(CompanyBankAccountService.class);
}
return bankAccountService;
}
public BankService getBankService() {
if (bankService == null) {
bankService = getBean(BankService.class);
}
return bankService;
}
}

View File

@@ -0,0 +1,204 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.service.CompanyOldNameService;
import com.ecep.contract.manager.ui.TabSkin;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.util.converter.LocalDateStringConverter;
import lombok.Setter;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
*
*/
public class CompanyTabSkinBase
extends AbstCompanyBasedTabSkin
implements TabSkin {
@Setter
private CompanyOldNameService companyOldNameService;
public CompanyTabSkinBase(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.baseInfoTab;
}
@Override
public void initializeTab() {
LocalDateStringConverter localDateStringConverter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
controller.nameField.textProperty().bind(viewModel.getName());
controller.shortNameField.textProperty().bindBidirectional(viewModel.getShortName());
controller.entStatusField.textProperty().bindBidirectional(viewModel.getEntStatus());
controller.uidField.textProperty().bindBidirectional(viewModel.getUid());
controller.setupDateField.setConverter(localDateStringConverter);
controller.setupDateField.valueProperty().bindBidirectional(viewModel.getSetupDate());
controller.entTypeField.textProperty().bindBidirectional(viewModel.getEntType());
controller.industryField.textProperty().bindBidirectional(viewModel.getIndustry());
controller.districtField.textProperty().bindBidirectional(viewModel.getDistrict());
controller.pathExistField.selectedProperty().bind(viewModel.getPathExist());
controller.pathField.textProperty().bind(viewModel.getPath());
controller.createdDateField.setConverter(localDateStringConverter);
controller.createdDateField.valueProperty().bindBidirectional(viewModel.getCreated());
controller.telephoneField.textProperty().bindBidirectional(viewModel.getTelephone());
controller.regAddressField.textProperty().bindBidirectional(viewModel.getRegAddress());
controller.addressField.textProperty().bindBidirectional(viewModel.getAddress());
controller.registeredCapitalField.textProperty().bindBidirectional(viewModel.getRegisteredCapital());
controller.registeredCapitalCurrencyField.textProperty().bindBidirectional(viewModel.getRegisteredCapitalCurrency());
controller.legalRepresentativeField.textProperty().bindBidirectional(viewModel.getLegalRepresentative());
controller.operationPeriodBeginField.setConverter(localDateStringConverter);
controller.operationPeriodBeginField.valueProperty().bindBidirectional(viewModel.getOperationPeriodBegin());
controller.operationPeriodEndField.setConverter(localDateStringConverter);
controller.operationPeriodEndField.valueProperty().bindBidirectional(viewModel.getOperationPeriodEnd());
controller.memoField.textProperty().bindBidirectional(viewModel.getMemo());
controller.versionLabel.textProperty().bind(viewModel.getVersion().asString());
controller.companyRenameBtn.setOnAction(this::onCompanyRenameAction);
controller.companyPathCreateBtn.setOnAction(this::onCompanyPathCreatePathAction);
controller.companyPathChangeBtn.setOnAction(this::onCompanyPathChangePathAction);
controller.companyPathSameAsNameBtn.setOnAction(this::onCompanyPathSameAsNameAction);
}
private void onCompanyPathCreatePathAction(ActionEvent event) {
Company company = getEntity();
if (getCompanyService().makePathAbsent(company)) {
save(company);
} else {
setStatus("目录存在或创建失败");
}
}
private void onCompanyPathChangePathAction(ActionEvent event) {
}
private void onCompanyPathSameAsNameAction(ActionEvent event) {
Company company = getEntity();
String path = company.getPath();
if (!StringUtils.hasText(path)) {
return;
}
File file = new File(path);
if (!file.exists()) {
return;
}
if (file.getName().equals(company.getName())) {
return;
}
File dest = new File(file.getParent(), company.getName());
if (file.renameTo(dest)) {
company.setPath(dest.getAbsolutePath());
save(company);
setStatus("目录变更为" + dest.getName());
}
}
private void onCompanyRenameAction(ActionEvent event) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.initOwner(controller.root.getScene().getWindow());
alert.initModality(Modality.WINDOW_MODAL);
VBox layout = new VBox();
TextField nameField = new TextField();
Label nameLabel = new Label("");
CheckBox saveAsOldName = new CheckBox();
CheckBox ambiguity = new CheckBox();
Label ambiguityLabel = new Label("当曾用名不是工商注册过的名字时,请勾选 歧义 标记");
layout.setPadding(new Insets(12));
layout.setSpacing(8);
nameField.setPromptText("新的公司名称");
nameField.setText(viewModel.getName().get());
nameField.setEditable(true);
nameLabel.setTextFill(Color.GRAY);
saveAsOldName.setText("旧名称是否设置为曾用名");
ambiguity.setText("是否标记为歧义");
ambiguity.visibleProperty().bind(saveAsOldName.selectedProperty());
ambiguityLabel.setTextFill(Color.GRAY);
ambiguityLabel.visibleProperty().bind(saveAsOldName.selectedProperty());
layout.getChildren().addAll(nameField, nameLabel, saveAsOldName, ambiguity, ambiguityLabel);
alert.setContentText("context");
alert.setHeaderText(null);
alert.setTitle("企业更名");
alert.getDialogPane().setContent(layout);
// alert.setResultConverter(param -> {
//
// return null;
// });
alert.setOnCloseRequest(dialogEvent -> {
ButtonType buttonType = alert.getResult();
if (buttonType != ButtonType.OK) {
return;
}
String newName = nameField.getText();
String oldName = viewModel.getName().get();
if (oldName.equals(newName)) {
nameLabel.setText("名称没有修改");
nameLabel.setTextFill(Color.PERU);
dialogEvent.consume();
return;
}
viewModel.getName().set(newName);
save();
// TODO 修改文件夹
if (!saveAsOldName.isSelected()) {
return;
}
Company company = getEntity();
List<CompanyOldName> oldNames = getCompanyOldNameService().findAllByCompanyAndName(company, oldName);
if (oldNames.isEmpty()) {
CompanyOldName companyOldName = new CompanyOldName();
companyOldName.setCompanyId(company.getId());
companyOldName.setName(oldName);
companyOldName.setAmbiguity(ambiguity.isSelected());
companyOldName.setMemo("名称更名 " + oldName + " -> " + newName);
getCompanyOldNameService().save(companyOldName);
CompanyTabSkinOldName tabSkin = controller.getTabSkin(CompanyTabSkinOldName.class);
if (tabSkin != null) {
tabSkin.loadTableDataSet();
}
}
});
alert.showAndWait();
}
private CompanyOldNameService getCompanyOldNameService() {
if (companyOldNameService == null) {
companyOldNameService = getBean(CompanyOldNameService.class);
}
return companyOldNameService;
}
}

View File

@@ -0,0 +1,145 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.cloud.rk.BlackListUpdateContext;
import com.ecep.contract.manager.cloud.rk.CloudRk;
import com.ecep.contract.manager.cloud.rk.CloudRkService;
import com.ecep.contract.manager.ds.company.BlackReasonType;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBlackReason;
import com.ecep.contract.manager.ds.company.service.CompanyBlackReasonService;
import com.ecep.contract.manager.ds.company.vo.CompanyBlackReasonViewModel;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.util.UITools;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.util.List;
/**
* 子合同
*/
@FxmlPath("/ui/company/company-tab-black-list.fxml")
public class CompanyTabSkinBlackReason
extends AbstCompanyTableTabSkin<CompanyBlackReason, CompanyBlackReasonViewModel>
implements TabSkin, EditableEntityTableTabSkin<CompanyBlackReason, CompanyBlackReasonViewModel> {
/**
* 以下是黑名单列定义
*/
public TableColumn<CompanyBlackReasonViewModel, Number> blackReasonTable_idColumn;
public TableColumn<CompanyBlackReasonViewModel, BlackReasonType> blackReasonTable_typeColumn;
public TableColumn<CompanyBlackReasonViewModel, String> blackReasonTable_applyNameColumn;
public TableColumn<CompanyBlackReasonViewModel, String> blackReasonTable_blackReasonColumn;
public TableColumn<CompanyBlackReasonViewModel, String> blackReasonTable_descriptionColumn;
public TableColumn<CompanyBlackReasonViewModel, LocalDate> blackReasonTable_applyDateColumn;
public TableColumn<CompanyBlackReasonViewModel, LocalDate> blackReasonTable_updateTimeColumn;
public TableColumn<CompanyBlackReasonViewModel, LocalDate> blackReasonTable_createTimeColumn;
public TableColumn<CompanyBlackReasonViewModel, LocalDate> blackReasonTable_includeDateColumn;
public TableColumn<CompanyBlackReasonViewModel, String> blackReasonTable_keyColumn;
public TextField blackListSearchKeyField;
public Button blackListSearchBtn;
public MenuItem blackReasonTable_menu_refresh;
public MenuItem blackReasonTable_menu_update;
@Setter
private CompanyBlackReasonService companyBlackReasonService;
@Setter
private CloudRkService cloudRkService;
public CompanyTabSkinBlackReason(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.blackReasonTab;
}
@Override
public void initializeTab() {
blackListSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
blackListSearchBtn.fire();
}
});
blackListSearchBtn.setOnAction(this::onTableRefreshAction);
blackReasonTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
blackReasonTable_typeColumn.setCellValueFactory(param -> param.getValue().getType());
blackReasonTable_applyNameColumn.setCellValueFactory(param -> param.getValue().getApplyName());
blackReasonTable_blackReasonColumn.setCellValueFactory(param -> param.getValue().getBlackReason());
blackReasonTable_descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
blackReasonTable_applyDateColumn.setCellValueFactory(param -> param.getValue().getApplyDate());
blackReasonTable_updateTimeColumn.setCellValueFactory(param -> param.getValue().getUpdateTime());
blackReasonTable_createTimeColumn.setCellValueFactory(param -> param.getValue().getUpdateTime());
blackReasonTable_includeDateColumn.setCellValueFactory(param -> param.getValue().getCreateTime());
blackReasonTable_keyColumn.setCellValueFactory(param -> param.getValue().getKey());
blackReasonTable_menu_refresh.setOnAction(this::onTableRefreshAction);
blackReasonTable_menu_update.setOnAction(this::onTableUpdateAction);
super.initializeTab();
}
private void onTableUpdateAction(ActionEvent event) {
Company company = getParent();
CloudRkService cloudRkService = getCloudRkService();
CloudRk cloudRk = cloudRkService.getOrCreateCloudRk(company);
BlackListUpdateContext context = cloudRkService.createBlackListUpdateContext().join();
if (cloudRkService.checkBlackListUpdateElapse(company, cloudRk, context)) {
try {
cloudRkService.updateBlackList(company, cloudRk, context);
} catch (Exception e) {
UITools.showExceptionAndWait("更新黑名单时发生错误", e);
}
}
}
@Override
protected void onTableRowDoubleClickedAction(CompanyBlackReasonViewModel item) {
// ContractWindowController.show(item, controller.root.getScene().getWindow());
}
@Override
public CompanyBlackReason loadRowData(CompanyBlackReasonViewModel row) {
return getViewModelService().findById(row.getId().get());
}
@Override
public CompanyBlackReason saveRowData(CompanyBlackReason entity) {
return getViewModelService().save(entity);
}
@Override
public void deleteRowData(CompanyBlackReason entity) {
getViewModelService().delete(entity);
}
protected CompanyBlackReasonService getViewModelService() {
if (companyBlackReasonService == null) {
companyBlackReasonService = getBean(CompanyBlackReasonService.class);
}
return companyBlackReasonService;
}
public CloudRkService getCloudRkService() {
if (cloudRkService == null) {
cloudRkService = getBean(CloudRkService.class);
}
return cloudRkService;
}
}

View File

@@ -0,0 +1,106 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.controller.contact.CompanyContactWindowController;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyContact;
import com.ecep.contract.manager.ds.company.service.CompanyContactService;
import com.ecep.contract.manager.ds.company.vo.CompanyContactViewModel;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.ViewModelService;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.util.List;
/**
* 子合同
*/
@FxmlPath("/ui/company/company-tab-contact.fxml")
public class CompanyTabSkinContact
extends AbstCompanyTableTabSkin<CompanyContact, CompanyContactViewModel>
implements TabSkin, EditableEntityTableTabSkin<CompanyContact, CompanyContactViewModel> {
/**
* 以下是联系人列定义
*/
public TableColumn<CompanyContactViewModel, Number> contactTable_idColumn;
public TableColumn<CompanyContactViewModel, String> contactTable_nameColumn;
public TableColumn<CompanyContactViewModel, String> contactTable_positionColumn;
public TableColumn<CompanyContactViewModel, String> contactTable_phoneColumn;
public TableColumn<CompanyContactViewModel, String> contactTable_emailColumn;
public TableColumn<CompanyContactViewModel, String> contactTable_addressColumn;
public TableColumn<CompanyContactViewModel, String> contactTable_u8CodeColumn;
public TableColumn<CompanyContactViewModel, LocalDate> contactTable_createdColumn;
public TextField contactSearchKeyField;
public Button contactSearchBtn;
public MenuItem contactTable_menu_refresh;
public MenuItem contactTable_menu_add;
public MenuItem contactTable_menu_del;
@Setter
private CompanyContactService contactService;
public CompanyTabSkinContact(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.contactTab;
}
@Override
public void initializeTab() {
contactSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
contactSearchBtn.fire();
}
});
contactSearchBtn.setOnAction(this::onTableRefreshAction);
contactTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
contactTable_nameColumn.setCellValueFactory(param -> param.getValue().getName());
contactTable_positionColumn.setCellValueFactory(param -> param.getValue().getPosition());
contactTable_phoneColumn.setCellValueFactory(param -> param.getValue().getPhone());
contactTable_emailColumn.setCellValueFactory(param -> param.getValue().getEmail());
contactTable_addressColumn.setCellValueFactory(param -> param.getValue().getAddress());
contactTable_u8CodeColumn.setCellValueFactory(param -> param.getValue().getU8Code());
contactTable_createdColumn.setCellValueFactory(param -> param.getValue().getCreated());
contactTable_menu_refresh.setOnAction(this::onTableRefreshAction);
contactTable_menu_add.setOnAction(this::onTableAddAction);
contactTable_menu_del.setOnAction(this::onTableDeleteAction);
super.initializeTab();
}
@Override
protected void onTableAddAction(ActionEvent event) {
CompanyContact contact = new CompanyContact();
contact.setCompany(getParent());
contact.setCreated(LocalDate.now());
getViewModelService().save(contact);
loadTableDataSet();
}
@Override
protected void onTableRowDoubleClickedAction(CompanyContactViewModel item) {
CompanyContactWindowController.show(item, controller.root.getScene().getWindow());
}
public CompanyContactService getViewModelService() {
if (contactService == null) {
contactService = getBean(CompanyContactService.class);
}
return contactService;
}
}

View File

@@ -0,0 +1,266 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.Desktop;
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.contract.controller.ContractGroupTableCell;
import com.ecep.contract.manager.ds.contract.controller.ContractKindTableCell;
import com.ecep.contract.manager.ds.contract.controller.ContractTypeTableCell;
import com.ecep.contract.manager.ds.contract.controller.ContractWindowController;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractGroup;
import com.ecep.contract.manager.ds.contract.model.ContractKind;
import com.ecep.contract.manager.ds.contract.model.ContractType;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.tasker.ContractRepairByCompanyTask;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.util.ContractGroupStringConverter;
import com.ecep.contract.manager.ui.util.LocalDateTimeTableCell;
import com.ecep.contract.manager.util.SpecificationUtils;
import com.ecep.contract.manager.util.UITools;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import org.springframework.beans.BeansException;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.NoSuchElementException;
import java.util.concurrent.CompletableFuture;
/**
* 子合同
*/
@FxmlPath("/ui/company/company-tab-contract.fxml")
public class CompanyTabSkinContract
extends AbstCompanyTableTabSkin<Contract, ContractViewModel>
implements TabSkin, EditableEntityTableTabSkin<Contract, ContractViewModel> {
public TableColumn<ContractViewModel, Number> contractTable_idColumn;
public TableColumn<ContractViewModel, String> contractTable_codeColumn;
public TableColumn<ContractViewModel, String> contractTable_nameColumn;
public TableColumn<ContractViewModel, String> contractTable_stateColumn;
public TableColumn<ContractViewModel, ContractGroup> contractTable_groupColumn;
public TableColumn<ContractViewModel, ContractType> contractTable_typeColumn;
public TableColumn<ContractViewModel, ContractKind> contractTable_kindColumn;
public TableColumn<ContractViewModel, String> contractTable_parentCodeColumn;
public TableColumn<ContractViewModel, LocalDate> contractTable_orderDateColumn;
public TableColumn<ContractViewModel, LocalDate> contractTable_startDateColumn;
public TableColumn<ContractViewModel, LocalDate> contractTable_endDateColumn;
public TableColumn<ContractViewModel, Employee> contractTable_setupPersonColumn;
public TableColumn<ContractViewModel, LocalDate> contractTable_setupDateColumn;
public TableColumn<ContractViewModel, Employee> contractTable_inurePersonColumn;
public TableColumn<ContractViewModel, LocalDate> contractTable_inureDateColumn;
public TableColumn<ContractViewModel, Employee> contractTable_varyPersonColumn;
public TableColumn<ContractViewModel, LocalDate> contractTable_varyDateColumn;
public TableColumn<ContractViewModel, LocalDateTime> contractTable_createdColumn;
public ComboBox<ContractGroup> contractGroupSelector;
public TextField contractSearchKeyField;
public Button contractSearchBtn;
public Button contractTabToolBtn1;
public MenuItem contractTable_menu_refresh;
public MenuItem contractTable_menu_add;
public MenuItem contractTable_menu_open_in_explorer;
public MenuItem contractTable_menu_update;
public MenuItem contractTable_menu_del;
@Setter
private ContractService contractService;
@Setter
private YongYouU8Service u8Service;
@Setter
private EmployeeStringConverter employeeStringConverter;
public CompanyTabSkinContract(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.contractTab;
}
@Override
public Specification<Contract> getSpecification(Company parent) {
Specification<Contract> spec = super.getSpecification(parent);
ContractGroup selectedGroup = contractGroupSelector.getValue();
if (selectedGroup != null) {
spec = SpecificationUtils.and(spec, (root, query, builder) -> {
return builder.equal(root.get("group"), selectedGroup);
});
}
return spec;
}
@Override
public void initializeTab() {
if (u8Service == null) {
try {
u8Service = getBean(YongYouU8Service.class);
} catch (BeansException ignored) {
}
}
contractSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
contractSearchBtn.fire();
}
});
contractSearchBtn.setOnAction(this::onTableRefreshAction);
ObservableList<ContractGroup> contractGroups = FXCollections.observableArrayList();
contractGroups.add(null);
contractGroups.addAll(contractService.findAllGroups());
contractGroupSelector.setItems(contractGroups);
contractGroupSelector.setConverter(new ContractGroupStringConverter(contractGroups));
contractSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
contractSearchBtn.fire();
}
});
contractTabToolBtn1.setOnAction(event -> {
CompletableFuture.runAsync(() -> {
// 计算主合同编号
for (ContractViewModel model : dataSet) {
Contract contract = contractService.findById(model.getId().get());
if (contract == null) {
continue;
}
try {
if (contractService.updateParentCode(contract)) {
Contract updated = contractService.save(contract);
model.update(updated);
}
} catch (NoSuchElementException e) {
model.getParentCode().set(e.getMessage());
}
}
});
});
contractTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
contractTable_codeColumn.setCellValueFactory(param -> param.getValue().getCode());
contractTable_nameColumn.setCellValueFactory(param -> param.getValue().getName());
contractTable_stateColumn.setCellValueFactory(param -> param.getValue().getState());
contractTable_groupColumn.setCellValueFactory(param -> param.getValue().getGroup());
contractTable_groupColumn.setCellFactory(param -> new ContractGroupTableCell(getViewModelService()));
contractTable_typeColumn.setCellValueFactory(param -> param.getValue().getType());
contractTable_typeColumn.setCellFactory(param -> new ContractTypeTableCell(getViewModelService()));
contractTable_kindColumn.setCellValueFactory(param -> param.getValue().getKind());
contractTable_kindColumn.setCellFactory(param -> new ContractKindTableCell(getViewModelService()));
contractTable_parentCodeColumn.setCellValueFactory(param -> param.getValue().getParentCode());
contractTable_orderDateColumn.setCellValueFactory(param -> param.getValue().getOrderDate());
contractTable_startDateColumn.setCellValueFactory(param -> param.getValue().getStartDate());
contractTable_endDateColumn.setCellValueFactory(param -> param.getValue().getEndDate());
contractTable_setupPersonColumn.setCellValueFactory(param -> param.getValue().getSetupPerson());
contractTable_setupPersonColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
contractTable_setupDateColumn.setCellValueFactory(param -> param.getValue().getSetupDate());
// contractTable_setupDateColumn.setSortable(true);
// contractTable_setupDateColumn.setSortType(TableColumn.SortType.DESCENDING);
contractTable_inurePersonColumn.setCellValueFactory(param -> param.getValue().getInurePerson());
contractTable_inurePersonColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
contractTable_inureDateColumn.setCellValueFactory(param -> param.getValue().getInureDate());
contractTable_varyPersonColumn.setCellValueFactory(param -> param.getValue().getVaryPerson());
contractTable_varyPersonColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
contractTable_varyDateColumn.setCellValueFactory(param -> param.getValue().getVaryDate());
contractTable_createdColumn.setCellValueFactory(param -> param.getValue().getCreated());
contractTable_createdColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
contractTable_menu_refresh.setOnAction(this::onTableRefreshAction);
// contractTable_menu_add.setOnAction(this::onTableAddAction);
contractTable_menu_del.setOnAction(this::onTableDeleteAction);
contractTable_menu_open_in_explorer.setOnAction(this::onTableOpenInExplorerAction);
contractTable_menu_update.setOnAction(this::onTableUpdateAction);
super.initializeTab();
}
private void onTableUpdateAction(ActionEvent event) {
ContractRepairByCompanyTask task = new ContractRepairByCompanyTask();
task.setContractService(contractService);
task.setCompany(getParent());
UITools.showTaskDialogAndWait("同步合同", task, null);
if (task.isRepaired()) {
loadTableDataSet();
}
}
private void onTableOpenInExplorerAction(ActionEvent event) {
ContractViewModel selectedItem = getSelectedItem();
if (selectedItem != null) {
showInExplorer(selectedItem.getPath().get());
}
}
private void showInExplorer(String path) {
if (!StringUtils.hasText(path)) {
setStatus("文件/目录为空,无法打开");
return;
}
File file = new File(path);
if (!file.exists()) {
if (file.isFile()) {
setStatus("文件 " + file.getAbsolutePath() + " 不存在,请确认");
} else {
setStatus("目录 " + file.getAbsolutePath() + " 不存在,请确认");
}
return;
}
try {
Desktop.showInExplorer(file);
setStatus("打开文件/目录 " + path);
} catch (Exception e) {
setStatus("打开文件错误:" + e.getMessage());
}
}
@Override
protected void onTableRowDoubleClickedAction(ContractViewModel item) {
ContractWindowController.show(item, controller.root.getScene().getWindow());
}
protected ContractService getViewModelService() {
if (contractService == null) {
contractService = getBean(ContractService.class);
}
return contractService;
}
private EmployeeStringConverter getEmployeeStringConverter() {
if (employeeStringConverter == null) {
employeeStringConverter = getBean(EmployeeStringConverter.class);
}
return employeeStringConverter;
}
}

View File

@@ -0,0 +1,378 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.Desktop;
import com.ecep.contract.manager.MyProperties;
import com.ecep.contract.manager.cloud.tyc.CloudTycService;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyFile;
import com.ecep.contract.manager.ds.company.model.CompanyFileTypeLocal;
import com.ecep.contract.manager.ds.company.service.CompanyFileService;
import com.ecep.contract.manager.ds.company.vo.CompanyFileViewModel;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import com.ecep.contract.manager.util.UITools;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.scene.control.*;
import lombok.Setter;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import java.util.function.Consumer;
/**
*
*/
@FxmlPath("/ui/company/company-tab-file.fxml")
public class CompanyTabSkinFile
extends AbstCompanyTableTabSkin<CompanyFile, CompanyFileViewModel>
implements TabSkin, EditableEntityTableTabSkin<CompanyFile, CompanyFileViewModel> {
public TableColumn<CompanyFileViewModel, Number> idColumn;
public TableColumn<CompanyFileViewModel, String> typeColumn;
public TableColumn<CompanyFileViewModel, String> filePathColumn;
public TableColumn<CompanyFileViewModel, LocalDate> applyDateColumn;
public TableColumn<CompanyFileViewModel, LocalDate> expiringDateColumn;
public Button fileTable_file_move_btn;
public Button fileTable_file_retrieve_from_download_dir_btn;
public Button fileTable_file_reset_btn;
public MenuItem fileTable_menu_refresh;
public MenuItem fileTable_menu_del;
public MenuItem fileTable_menu_copy_as_matched_by_contract;
@Setter
private CompanyFileService companyFileService;
@Setter
private MyProperties myProperties;
private final ObservableMap<CompanyFileType, CompanyFileTypeLocal> fileTypeLocalMap = FXCollections.observableHashMap();
public CompanyTabSkinFile(CompanyWindowController controller) {
super(controller);
setDragAndDrop(true);
setDragAndDropFileHandler(this::moveFileToCompany);
}
CompanyFileService getCompanyFileService() {
if (companyFileService == null) {
companyFileService = getBean(CompanyFileService.class);
}
return companyFileService;
}
@Override
public Tab getTab() {
return controller.fileTab;
}
@Override
public void initializeTable() {
super.initializeTable();
fileTable_file_move_btn.setOnAction(this::onTableMoveFileAction);
fileTable_file_retrieve_from_download_dir_btn.setOnAction(this::onTableRetrieveFromDownloadDirAction);
fileTable_file_reset_btn.setOnAction(this::onTableResetAction);
idColumn.setCellValueFactory(param -> param.getValue().getId());
typeColumn.setCellValueFactory(param -> Bindings.valueAt(fileTypeLocalMap, param.getValue().getType()).map(CompanyFileTypeLocal::getValue));
filePathColumn.setCellValueFactory(param -> param.getValue().getFilePath());
filePathColumn.setCellFactory(param -> new FileTableFilePathTableCell());
applyDateColumn.setCellValueFactory(param -> param.getValue().getApplyDate());
expiringDateColumn.setCellValueFactory(param -> param.getValue().getExpiringDate());
fileTable_menu_refresh.setOnAction(this::onTableRefreshAction);
fileTable_menu_del.setOnAction(this::onTableDeleteAction);
fileTable_menu_copy_as_matched_by_contract.setOnAction(this::onTableCopyAsMatchedByContractAction);
fileTable_menu_copy_as_matched_by_contract.setOnMenuValidation(this::onTableCopyAsMatchedMenuValidation);
fileTypeLocalMap.putAll(getCompanyFileService().findAllFileTypes(getLocale().toLanguageTag()));
}
private void onTableResetAction(ActionEvent event) {
runAsync(() -> {
if (getViewModelService().reBuildingFiles(getParent(), this::setStatus)) {
loadTableDataSet();
}
});
}
/**
* 从 下载目录 中查找相关的资质文件
*/
private void onTableRetrieveFromDownloadDirAction(ActionEvent event) {
Company company = getParent();
MyProperties myProperties = getMyProperties();
File dir = myProperties.getDownloadDirectory();
if (!dir.exists()) {
setStatus("下载目录 " + dir.getAbsolutePath() + " 不存在,请检查");
return;
}
setStatus("开始检索 下载 文件夹:" + dir.getAbsolutePath() + "...");
File[] files = dir.listFiles(File::isFile);
if (files == null) {
setStatus("检索 下载 文件夹失败");
return;
}
if (files.length == 0) {
setStatus("下载 文件夹没有文件");
return;
}
setStatus("下载 文件夹中共有文件 " + files.length + " 个文件");
if (getParentService().retrieveFromDownloadFiles(company, files, this::setStatus)) {
// fixed if update
viewModel.update(company);
loadTableDataSet();
}
}
/**
* 把文件从 老系统中移到 \\10.84.209.8\项目信息\相关方信息 目录中
*/
private void onTableMoveFileAction(ActionEvent event) {
CompanyFileService companyFileService = getViewModelService();
Company company = getParent();
List<CompanyFile> list = companyFileService.findByCompany(company);
if (list.isEmpty()) {
return;
}
if (getParentService().makePathAbsent(company)) {
save(company);
}
String path = company.getPath();
if (!StringUtils.hasText(path)) {
setStatus("异常, 企业目录未设置");
return;
}
File companyPath = new File(path);
for (CompanyFile companyFile : list) {
String filePath = companyFile.getFilePath();
if (StringUtils.hasText(filePath)) {
File file = new File(filePath);
if (file.exists()) {
if (file.getParentFile().equals(companyPath)) {
continue;
}
File dest = new File(companyPath, file.getName());
if (file.renameTo(dest)) {
companyFile.setFilePath(dest.getAbsolutePath());
companyFileService.save(companyFile);
setStatus(file.getName() + " 移动到 " + companyPath.getName());
}
}
}
}
}
/**
*
*/
private void onTableCopyAsMatchedByContractAction(ActionEvent event) {
UITools.showDialogAndWait("复制资信评估报告", "按当前评估报告复制一个合同中最匹配的", list -> {
onTableCopyAsMatchedAction_(msg -> {
Platform.runLater(() -> {
list.add(msg);
});
});
});
}
private void onTableCopyAsMatchedAction_(Consumer<String> state) {
Company company = getParent();
CompanyFileViewModel selectedItem = getSelectedItem();
if (selectedItem == null) {
state.accept("未选择行");
return;
}
if (selectedItem.getApplyDate().get() == null) {
state.accept("有效日期不能未空");
return;
}
LocalDate nextCreditReportDate = null;
try {
nextCreditReportDate = getViewModelService().getNextCreditReportDate(company, state);
if (nextCreditReportDate == null) {
state.accept("没有找到下一个咨询评估日期");
return;
}
} catch (Exception e) {
state.accept("获取下一个咨询评估日期失败:" + e.getMessage());
return;
}
state.accept("下一个咨询评估日期:" + nextCreditReportDate);
if (!nextCreditReportDate.isBefore(selectedItem.getApplyDate().get())) {
state.accept("咨询评估日期晚于下一个咨询评估日期");
return;
}
File src = new File(selectedItem.getFilePath().get());
if (!src.exists()) {
state.accept("当前选择行的文件不存在");
return;
}
String srcDate = MyDateTimeUtils.format(selectedItem.getApplyDate().get());
String destDate = MyDateTimeUtils.format(nextCreditReportDate);
String srcFileName = src.getName();
String destFileName;
// 天眼查的报告
if (CloudTycService.isTycReport(srcFileName)) {
state.accept("天眼查的报告按标准格式命名");
String name = company.getName() + "_" + CloudTycService.NAME;
if (srcFileName.contains(CloudTycService.TYC_ENTERPRISE_BASIC_REPORT)) {
name = name + "_" + CloudTycService.TYC_ENTERPRISE_BASIC_REPORT;
} else if (srcFileName.contains(CloudTycService.TYC_ENTERPRISE_MAJOR_REPORT)) {
name = name + "_" + CloudTycService.TYC_ENTERPRISE_MAJOR_REPORT;
} else if (srcFileName.contains(CloudTycService.TYC_ENTERPRISE_ANALYSIS_REPORT)) {
name = name + "_" + CloudTycService.TYC_ENTERPRISE_ANALYSIS_REPORT;
}
destFileName = name + "_" + destDate + "_cp." + StringUtils.getFilenameExtension(srcFileName);
} else {
if (srcFileName.contains(srcDate)) {
// 如果文件名中包含日期,则替换为新日期
destFileName = srcFileName.replace(srcDate, destDate + "_cp");
} else {
// 如果文件名中不包含日期,则添加日期
destFileName = company.getName() + "_" + destDate + "_cp." + StringUtils.getFilenameExtension(srcFileName);
}
}
state.accept("新文件名:" + destFileName);
File dest = new File(src.getParent(), destFileName);
try {
FileSystemUtils.copyRecursively(src, dest);
state.accept("新文件复制成功");
} catch (IOException e) {
state.accept("新文件复制失败:" + e.getMessage());
}
CompanyFile companyFile = new CompanyFile();
companyFile.setFilePath(dest.getAbsolutePath());
companyFile.setApplyDate(nextCreditReportDate);
companyFile.setExpiringDate(nextCreditReportDate.plusYears(1));
companyFile.setType(CompanyFileType.CreditReport);
companyFile.setCompany(company);
saveRowData(companyFile);
state.accept("新文件已记录");
loadTableDataSet();
state.accept("文件表已刷新");
}
/**
* 当fileTable选中的行是咨询评估时可用
*
* @param event event
*/
public void onTableCopyAsMatchedMenuValidation(Event event) {
//当fileTable选中的行是咨询评估时可用
CompanyFileViewModel selectedItem = getSelectedItem();
if (selectedItem == null) {
event.consume();
return;
}
CompanyFileType type = selectedItem.getType().get();
if (type != CompanyFileType.CreditReport) {
event.consume();
return;
}
}
@Override
protected boolean deleteRow(CompanyFileViewModel row) {
String path = row.getFilePath().get();
if (super.deleteRow(row)) {
File file = new File(path);
if (file.exists()) {
UITools.showConfirmation("数据记录已经删除,请确认是否删除物理文件", path).thenAccept(buttonType -> {
if (buttonType == ButtonType.OK) {
if (file.delete()) {
setStatus("删除文件 " + path);
}
}
});
}
return true;
}
return false;
}
private void moveFileToCompany(List<File> files) {
String path = viewModel.getPath().get();
if (!StringUtils.hasText(path)) {
setStatus("未设置目录");
return;
}
File dir = new File(path);
if (!dir.exists()) {
setStatus("目录错误,不存在");
return;
}
}
@Override
protected void onTableRowDoubleClickedAction(CompanyFileViewModel item) {
String path = item.getFilePath().get();
if (StringUtils.hasText(path)) {
File file = new File(path);
if (!file.exists()) {
setStatus("文件不存在 " + file.getName());
return;
}
Desktop.showInExplorer(file);
}
}
class FileTableFilePathTableCell extends TableCell<CompanyFileViewModel, String> {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
return;
}
String path = viewModel.getPath().get();
if (StringUtils.hasText(path)) {
if (item.startsWith(path)) {
item = "~" + item.substring(path.length());
}
}
setText(item);
}
}
public MyProperties getMyProperties() {
if (myProperties == null) {
myProperties = getBean(MyProperties.class);
}
return myProperties;
}
protected CompanyFileService getViewModelService() {
return getCompanyFileService();
}
}

View File

@@ -0,0 +1,116 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
import com.ecep.contract.manager.ds.company.model.Invoice;
import com.ecep.contract.manager.ds.company.service.InvoiceService;
import com.ecep.contract.manager.ds.company.vo.InvoiceViewModel;
import com.ecep.contract.manager.ds.contract.service.PurchaseBillVoucherService;
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import org.springframework.beans.BeansException;
import java.time.LocalDate;
/**
* 子合同
*/
@FxmlPath("/ui/company/company-tab-invoice.fxml")
public class CompanyTabSkinInvoice
extends AbstCompanyTableTabSkin<Invoice, InvoiceViewModel>
implements TabSkin, EditableEntityTableTabSkin<Invoice, InvoiceViewModel> {
public TableColumn<InvoiceViewModel, Number> idColumn;
public TableColumn<InvoiceViewModel, String> codeColumn;
public TableColumn<InvoiceViewModel, LocalDate> dateColumn;
public TableColumn<InvoiceViewModel, String> descriptionColumn;
public TextField searchKeyField;
public Button searchBtn;
@Setter
private PurchaseBillVoucherService purchaseBillVoucherService;
@Setter
private InvoiceService invoiceService;
@Setter
private YongYouU8Service u8Service;
@Setter
private EmployeeStringConverter employeeStringConverter;
public CompanyTabSkinInvoice(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.invoiceTab;
}
@Override
protected InvoiceService getViewModelService() {
return getInvoiceService();
}
@Override
public void initializeTab() {
if (u8Service == null) {
try {
u8Service = getBean(YongYouU8Service.class);
} catch (BeansException ignored) {
}
}
searchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
searchBtn.fire();
}
});
searchBtn.setOnAction(this::onTableRefreshAction);
searchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
searchBtn.fire();
}
});
idColumn.setCellValueFactory(param -> param.getValue().getId());
codeColumn.setCellValueFactory(param -> param.getValue().getCode());
dateColumn.setCellValueFactory(param -> param.getValue().getInvoiceDate());
descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
super.initializeTab();
}
@Override
protected void onTableRowDoubleClickedAction(InvoiceViewModel item) {
// ContractWindowController.show(item, controller.root.getScene().getWindow());
}
private PurchaseBillVoucherService getPurchaseBillVoucherService() {
if (purchaseBillVoucherService == null) {
purchaseBillVoucherService = getBean(PurchaseBillVoucherService.class);
}
return purchaseBillVoucherService;
}
private EmployeeStringConverter getEmployeeStringConverter() {
if (employeeStringConverter == null) {
employeeStringConverter = getBean(EmployeeStringConverter.class);
}
return employeeStringConverter;
}
private InvoiceService getInvoiceService() {
if (invoiceService == null) {
invoiceService = getBean(InvoiceService.class);
}
return invoiceService;
}
}

View File

@@ -0,0 +1,208 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.controller.old_name.CompanyOldNameWindowController;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.service.CompanyOldNameService;
import com.ecep.contract.manager.ds.company.vo.CompanyOldNameViewModel;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.util.SpecificationUtils;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.util.*;
/**
*曾用名
*/
@FxmlPath("/ui/company/company-tab-oldname.fxml")
public class CompanyTabSkinOldName
extends AbstCompanyTableTabSkin<CompanyOldName, CompanyOldNameViewModel>
implements TabSkin {
/**
* 以下是曾用名列定义
*/
public TableColumn<CompanyOldNameViewModel, Number> oldNameTable_idColumn;
public TableColumn<CompanyOldNameViewModel, String> oldNameTable_nameColumn;
public TableColumn<CompanyOldNameViewModel, LocalDate> oldNameTable_beginDateColumn;
public TableColumn<CompanyOldNameViewModel, LocalDate> oldNameTable_endDateColumn;
public TableColumn<CompanyOldNameViewModel, Boolean> oldNameTable_ambiguityColumn;
public TableColumn<CompanyOldNameViewModel, String> oldNameTable_pathColumn;
public TableColumn<CompanyOldNameViewModel, String> oldNameTable_memoColumn;
public TextField oldNameSearchKeyField;
public Button oldNameSearchBtn;
public Button oldNameTable_create_btn;
public Button oldNameTable_merge_btn;
public MenuItem oldNameTable_menu_refresh;
public MenuItem oldNameTable_menu_del;
@Setter
private CompanyOldNameService companyOldNameService;
public CompanyTabSkinOldName(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.oldNameTab;
}
@Override
public Specification<CompanyOldName> getSpecification(Company parent) {
return SpecificationUtils.and(getSpecification(), (root, query, builder) -> {
return builder.equal(root.get("companyId"), parent.getId());
});
}
@Override
public void initializeTab() {
oldNameSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
oldNameSearchBtn.fire();
}
});
oldNameSearchBtn.setOnAction(this::onTableRefreshAction);
oldNameTable_create_btn.setOnAction(this::onTableAddAction);
oldNameTable_merge_btn.setOnAction(this::onTableMergeAction);
oldNameTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
oldNameTable_nameColumn.setCellValueFactory(param -> param.getValue().getName());
oldNameTable_pathColumn.setCellFactory(param -> new FileTableFilePathTableCell());
oldNameTable_ambiguityColumn.setCellValueFactory(param -> param.getValue().getAmbiguity());
oldNameTable_ambiguityColumn.setCellFactory(c -> new CheckBoxTableCell<>());
oldNameTable_beginDateColumn.setCellValueFactory(param -> param.getValue().getBeginDate());
oldNameTable_endDateColumn.setCellValueFactory(param -> param.getValue().getEndDate());
oldNameTable_memoColumn.setCellValueFactory(param -> param.getValue().getMemo());
oldNameTable_menu_refresh.setOnAction(this::onTableRefreshAction);
oldNameTable_menu_del.setOnAction(this::onTableDeleteAction);
super.initializeTab();
}
@Override
protected void onTableAddAction(ActionEvent event) {
//
TextInputDialog dialog = new TextInputDialog();
dialog.setHeaderText("请输入曾用名");
dialog.setTitle("新建曾用名");
Optional<String> optional = dialog.showAndWait();
if (optional.isEmpty()) {
return;
}
CompanyOldName oldName = new CompanyOldName();
oldName.setName(optional.get());
oldName.setCompanyId(viewModel.getId().get());
oldName.setAmbiguity(true);
getViewModelService().save(oldName);
loadTableDataSet();
}
@Override
protected boolean deleteRow(CompanyOldNameViewModel row) {
CompanyOldName entity = getViewModelService().findById(row.getId().get());
if (entity != null) {
getViewModelService().delete(entity);
}
return true;
}
private void onTableMergeAction(ActionEvent event) {
Company updater = getParent();
HashSet<String> nameSet = new HashSet<>();
nameSet.add(updater.getName());
List<CompanyOldNameViewModel> removes = new ArrayList<>();
for (CompanyOldNameViewModel viewModel : dataSet) {
if (!nameSet.add(viewModel.getName().get())) {
// fixed 曾用名中有重复时,删除重复的
getViewModelService().delete(viewModel);
removes.add(viewModel);
}
}
if (!removes.isEmpty()) {
Platform.runLater(() -> {
dataSet.removeAll(removes);
});
setStatus("移除重复的曾用名" + removes.size());
}
int size = nameSet.size();
int count = 1;
int merge = 0;
for (String name : nameSet) {
controller.setRightStatus(count + "/" + size);
if (StringUtils.hasText(name)) {
List<Company> list = getParentService().findAllByName(name);
for (Company company : list) {
// fixed 曾用名中有可能有 updater 的名字,会导致自己删除自己
if (Objects.equals(company.getId(), updater.getId())) {
continue;
}
try {
getCompanyService().merge(company, updater);
setStatus("并户 " + company.getName() + "[" + company.getId() + "] 到当前公司");
merge++;
} catch (Exception e) {
throw new RuntimeException("合并 " + company.getName() + " -> " + updater.getName() + " 失败", e);
}
}
}
count++;
}
if (merge == 0) {
setStatus("没有需要并户的公司");
}
controller.setRightStatus("");
}
@Override
protected void onTableRowDoubleClickedAction(CompanyOldNameViewModel item) {
CompanyOldNameWindowController.show(item, controller.root.getScene().getWindow());
}
class FileTableFilePathTableCell extends TableCell<CompanyOldNameViewModel, String> {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
return;
}
String path = viewModel.getPath().get();
if (StringUtils.hasText(path)) {
if (item.startsWith(path)) {
item = "~" + item.substring(path.length());
}
}
setText(item);
}
}
protected CompanyOldNameService getViewModelService() {
if (companyOldNameService == null) {
companyOldNameService = getBean(CompanyOldNameService.class);
}
return companyOldNameService;
}
}

View File

@@ -0,0 +1,647 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.Desktop;
import com.ecep.contract.manager.cloud.rk.CloudRk;
import com.ecep.contract.manager.cloud.rk.CloudRkInfoViewModel;
import com.ecep.contract.manager.cloud.rk.CloudRkService;
import com.ecep.contract.manager.cloud.rk.ctx.CloudRkCtx;
import com.ecep.contract.manager.cloud.tyc.CloudTyc;
import com.ecep.contract.manager.cloud.tyc.CloudTycInfoViewModel;
import com.ecep.contract.manager.cloud.tyc.CloudTycService;
import com.ecep.contract.manager.cloud.u8.CloudYu;
import com.ecep.contract.manager.cloud.u8.CloudYuInfoViewModel;
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyExtendInfo;
import com.ecep.contract.manager.ds.company.service.CompanyExtendInfoService;
import com.ecep.contract.manager.ds.company.vo.CompanyExtendInfoViewModel;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.MessageHolder;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.util.DelayOnceExecutor;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import com.ecep.contract.manager.util.UITools;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.Border;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.util.StringUtils;
import org.w3c.dom.html.HTMLDocument;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@FxmlPath("/ui/company/company-tab-other.fxml")
public class CompanyTabSkinOther
extends AbstCompanyBasedTabSkin
implements TabSkin {
private static final Logger logger = LoggerFactory.getLogger(CompanyTabSkinOther.class);
/**
* 以下是云平台数据
*/
public TitledPane rkCloudPane;
public TextField cloudRkIdField;
public TextField cloudRkCloudIdField;
public TextField cloudRkLatestField;
public TextField cloudRkCustomerGradeField;
public TextField cloudRkCustomerScoreField;
public TextField cloudRkCustomerDescriptionField;
public TextField cloudRkVendorGradeField;
public TextField cloudRkVendorScoreField;
public TextField cloudRkVendorDescriptionField;
public TextField cloudRkBlackListUpdatedField;
public TextField cloudRkCloudLatestField;
public TextField cloudRkEntUpdateField;
public TextField cloudRkCreditRankField;
public TextField cloudRkCreditRankDescriptionField;
public Label cloudRkVersionLabel;
public CheckBox cloudRkAutoUpdateField;
// Tyc //
public TitledPane tycCloudPane;
public TextField cloudTycIdField;
public TextField cloudTycCloudIdField;
public TextField cloudTycLatestField;
public Label cloudTycVersionLabel;
public TextField tycCloudPaneCloudScore;
// public Hyperlink tycCloudPaneHyperLink;
public Button tycCloudPaneSaveButton;
// Yu //
public TitledPane yuCloudPane;
public TextField cloudYuIdField;
public TextField cloudYuCloudIdField;
public TextField cloudYuLatestField;
public Label cloudYuVersionLabel;
public Button yuCloudPaneSaveButton;
// Extend Info //
public TitledPane extendInfoPane;
public TextField extendInfoIdField;
public TextField extendInfoLatestField;
public Label extendInfoVersionLabel;
public CheckBox extendInfoDisableVerifyField;
public Button extendInfoPaneSaveButton;
private final CloudRkInfoViewModel rkCloudInfoViewModel = new CloudRkInfoViewModel();
private final CloudTycInfoViewModel tycCloudInfoViewModel = new CloudTycInfoViewModel();
private final CloudYuInfoViewModel yuCloudInfoViewModel = new CloudYuInfoViewModel();
private final CompanyExtendInfoViewModel extendInfoViewModel = new CompanyExtendInfoViewModel();
@Setter
private CloudRkService cloudRkService;
@Setter
private CloudTycService cloudTycService;
@Setter
private YongYouU8Service yongYouU8Service;
@Setter
private CompanyExtendInfoService extendInfoService;
public CompanyTabSkinOther(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.otherTab;
}
@Override
public void initializeTab() {
initializeCloudRkPane();
initializeCloudTycPane();
initializeCloudYuPane();
initializeExtendInfoPane();
listenTabSelectionChanged();
}
@Override
public void onTabShown() {
Company parent = getEntity();
updateRKCloudPane(parent, rkCloudPane);
updateTYCCloudPane(parent, tycCloudPane);
updateYuCloudPane(parent, yuCloudPane);
updateExtendInfoPane(parent, extendInfoPane);
}
/**
* 初始化 相关方平台信息 Titled Pane
*/
private void initializeCloudRkPane() {
// 记录编号
cloudRkIdField.textProperty().bind(rkCloudInfoViewModel.getId().asString());
// 平台编号
cloudRkCloudIdField.textProperty().bindBidirectional(rkCloudInfoViewModel.getCloudId());
cloudRkLatestField.textProperty().bind(rkCloudInfoViewModel.getLatest().map(MyDateTimeUtils::format));
cloudRkVersionLabel.textProperty().bind(rkCloudInfoViewModel.getVersion().asString("Ver:%s"));
cloudRkAutoUpdateField.selectedProperty().bindBidirectional(rkCloudInfoViewModel.getAutoUpdate());
cloudRkCustomerGradeField.textProperty().bind(rkCloudInfoViewModel.getCustomerGrade());
cloudRkCustomerScoreField.textProperty().bind(rkCloudInfoViewModel.getCustomerScore().asString());
cloudRkCustomerDescriptionField.textProperty().bind(rkCloudInfoViewModel.getCustomerDescription());
cloudRkVendorGradeField.textProperty().bind(rkCloudInfoViewModel.getVendorGrade());
cloudRkVendorScoreField.textProperty().bind(rkCloudInfoViewModel.getVendorScore().asString());
cloudRkVendorDescriptionField.textProperty().bind(rkCloudInfoViewModel.getVendorDescription());
cloudRkCreditRankField.textProperty().bind(rkCloudInfoViewModel.getRank());
cloudRkCreditRankDescriptionField.textProperty().bind(rkCloudInfoViewModel.getRankDescription());
cloudRkCloudLatestField.textProperty().bind(rkCloudInfoViewModel.getCloudLatest().map(MyDateTimeUtils::format));
cloudRkEntUpdateField.textProperty().bind(rkCloudInfoViewModel.getCloudEntUpdate().map(MyDateTimeUtils::format));
cloudRkBlackListUpdatedField.textProperty().bind(rkCloudInfoViewModel.getCloudBlackListUpdated().map(MyDateTimeUtils::format));
DelayOnceExecutor saveExecutor = new DelayOnceExecutor(() -> {
save(rkCloudInfoViewModel);
cloudRkAutoUpdateField.setBorder(null);
}, 2, TimeUnit.SECONDS).exception(e -> logger.error(e.getMessage(), e));
cloudRkAutoUpdateField.setOnMouseClicked(event -> {
cloudRkAutoUpdateField.setBorder(Border.stroke(Color.RED));
saveExecutor.tick();
});
}
public void save(CloudRkInfoViewModel viewModel) {
int infoId = viewModel.getId().get();
CloudRkService service = getCloudRkService();
CloudRk cloudRk = service.findById(infoId);
if (cloudRk == null) {
throw new RuntimeException("CloudRk not found");
}
if (viewModel.copyTo(cloudRk)) {
CloudRk saved = service.save(cloudRk);
if (Platform.isFxApplicationThread()) {
viewModel.update(saved);
} else {
Platform.runLater(() -> {
viewModel.update(saved);
});
}
}
}
/**
* 杂项页中集团相关方panel中更新action
*/
public void onCloudRkUpdateButtonClickedAction(ActionEvent event) {
Button button = (Button) event.getSource();
button.setDisable(true);
CompletableFuture.runAsync(() -> {
try {
onCloudRkUpdateButtonClicked(event);
} catch (Exception e) {
UITools.showExceptionAndWait("", e);
}
}).whenComplete((v, e) -> {
button.setDisable(false);
});
}
/**
* 从集团相关方平台中更新公司信息
*
* @see #onCloudRkUpdateButtonClickedAction(ActionEvent)
*/
private void onCloudRkUpdateButtonClicked(ActionEvent actionEvent) throws IOException {
Button button = (Button) actionEvent.getSource();
Company company = getEntity();
CloudRkCtx cloudRkCtx = new CloudRkCtx();
cloudRkCtx.setCloudRkService(getCloudRkService());
CloudRk cloudRk = cloudRkCtx.getOrCreateCloudRk(company);
MessageHolder holder = (level, message) -> {
setStatus(message);
if (level == Level.WARNING) {
logger.warn("{} {}", getEntity().getName(), message);
}
if (level == Level.SEVERE) {
logger.error("{} {}", getEntity().getName(), message);
}
};
if (!StringUtils.hasText(rkCloudInfoViewModel.getCloudId().get())) {
holder.info("没有 " + CloudRkService.NAME + " 编号,准备使用模糊查询接口获取编号...");
// use fuzzy to find cloud id
try {
//
List<CloudRkService.EntInfo> entInfos = cloudRkCtx.queryEnterpriseWithFuzzy(company, cloudRk, holder);
if (entInfos.isEmpty()) {
cloudRk.setCloudId("-");
cloudRkCtx.save(cloudRk);
holder.error("没有查询到相关企业信息");
return;
}
String companyName = company.getName();
Optional<CloudRkService.EntInfo> optional = entInfos.stream()
.filter(n -> n.getName().equals(companyName)).findAny();
if (optional.isPresent()) {
// 查询接口中返回的结果中有跟公司名称相同的,则直接使用
cloudRk.setCloudId(optional.get().getId());
} else {
// 手动选择
CloudRkService.EntInfo selectedItem = showEnterpriseChooser(entInfos);
if (selectedItem != null) {
cloudRk.setCloudId(selectedItem.getId());
rkCloudInfoViewModel.update(cloudRkCtx.save(cloudRk));
// 重新发起
button.getOnAction().handle(actionEvent);
}
Platform.runLater(() -> {
});
return;
}
} catch (Exception e) {
// 异常
UITools.showExceptionAndWait(CloudRkService.NAME + " 中使用模糊查询接口获取企业平台编号发生错误", e);
return;
}
}
if (!StringUtils.hasText(cloudRk.getCloudId())) {
setStatus("没有平台编号, 无法更新");
return;
}
if (cloudRk.getCloudId().equals("-")) {
setStatus("更新已经屏蔽");
return;
}
try {
rkCloudInfoViewModel.getLatest().set(null);
setStatus("尝试从 " + CloudRkService.NAME + " 中更新企业信息...");
if (cloudRkCtx.updateEnterpriseInfo(company, cloudRk, holder)) {
company = save(company);
}
setStatus("尝试从 " + CloudRkService.NAME + " 中更新黑名单...");
if (cloudRkCtx.updateBlackList(company, cloudRk, holder)) {
CompanyTabSkinOldName tabSkin = controller.getTabSkin(CompanyTabSkinOldName.class);
if (tabSkin != null) {
tabSkin.loadTableDataSet();
}
}
setStatus("尝试从 " + CloudRkService.NAME + " 中更新企业评分...");
if (cloudRkCtx.updateEnterpriseCredit(company, cloudRk, holder)) {
// cloudRk modified
}
setStatus("尝试从 " + CloudRkService.NAME + " 中更新客户评级...");
if (cloudRkCtx.updateCustomerScore(company, cloudRk, holder)) {
// cloudRk modified
}
setStatus("尝试从 " + CloudRkService.NAME + " 中更新供应商评分...");
if (cloudRkCtx.updateVendorScore(company, cloudRk, holder)) {
// cloudRk modified
}
setStatus("");
} catch (Exception e) {
// 异常
logger.error("更新 {} 时发生错误", company.getName(), e);
UITools.showExceptionAndWait(CloudRkService.NAME + " 中使用报表接口更新企业基本注册信息时发生错误", e);
return;
} finally {
cloudRk.setLatestUpdate(Instant.now());
CloudRk cloudRk1 = cloudRkCtx.save(cloudRk);
Platform.runLater(() -> {
rkCloudInfoViewModel.update(cloudRk1);
});
}
}
private CloudRkService.EntInfo showEnterpriseChooser(List<CloudRkService.EntInfo> entInfos) {
// TODO 转换为 独立窗口类,通过 getResult() 返回操作
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setWidth(350);
alert.setHeaderText(CloudRkService.NAME + " 返回多个结果, 请选择确认");
ListView<CloudRkService.EntInfo> listView = new ListView<>();
listView.setCellFactory(param -> new ListCell<>() {
@Override
protected void updateItem(CloudRkService.EntInfo item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
// setBackground(Background.EMPTY);
} else {
setText((item.isNowName() ? "" : "") + " " + item.getName());
}
}
});
listView.getItems().addAll(entInfos);
alert.getDialogPane().setContent(listView);
if (alert.showAndWait().get() != ButtonType.OK) {
return null;
}
return listView.getSelectionModel().getSelectedItem();
}
public void onTycCloudPaneHyperLinkClickedAction(ActionEvent event) {
String cloudId = tycCloudInfoViewModel.getCloudId().get();
String url = null;
if (StringUtils.hasText(cloudId)) {
url = String.format(CloudTycService.URL_COMPANY, cloudId);
} else {
Company company = getEntity();
url = String.format(CloudTycService.URL_COMPANY_SEARCH, company.getName());
}
Desktop.showInBrowse(url);
}
public void onTycCloudPaneHyperLinkInnerViewClickedAction(ActionEvent event) {
Company company = getEntity();
String cloudId = tycCloudInfoViewModel.getCloudId().get();
String url = "https://www.tianyancha.com/search?key=" + company.getName();
Stage stage = new Stage();
WebView webView = new WebView();
webView.getEngine().locationProperty().addListener((ob, old, n) -> {
System.out.println("location " + old + " -> " + n);
});
webView.getEngine().getLoadWorker().exceptionProperty().addListener((ob, old, n) -> {
System.out.println("LoadWorker exception:" + n);
});
webView.getEngine().setCreatePopupHandler(p -> {
System.out.println("Popup = " + p);
return webView.getEngine();
});
webView.getEngine().setPromptHandler(p -> {
System.out.println("Prompt = " + p);
return null;
});
webView.getEngine().setConfirmHandler(p -> {
System.out.println("Confirm = " + p);
return null;
});
webView.getEngine().getLoadWorker().stateProperty().addListener((ob, old, n) -> {
System.out.println("LoadWorker state:" + n);
});
webView.getEngine().getLoadWorker().progressProperty().addListener((ob, old, n) -> {
System.out.println("LoadWorker progress:" + n);
});
File directory = new File(".");
System.out.println(". = " + directory.getAbsolutePath());
webView.getEngine().setUserDataDirectory(directory);
webView.getEngine().load(url);
webView.getEngine().documentProperty().addListener(((observable, oldValue, newValue) -> {
if (newValue == null) {
return;
}
HTMLDocument doc = (HTMLDocument) newValue;
setStatus("Open Url : " + doc.getURL());
stage.setTitle(doc.getTitle());
// updateByTycSearch(company, doc);
}));
StackPane root = new StackPane();
root.getChildren().add(webView);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* 杂项 天眼查页,更新按钮 action
*/
public void onCloudTycUpdateButtonClickedAction(ActionEvent event) {
Button button = (Button) event.getSource();
button.setDisable(true);
CompletableFuture.runAsync(() -> {
try {
onCloudTycUpdateButtonClicked(event);
} catch (Exception e) {
UITools.showExceptionAndWait("", e);
}
}).whenComplete((v, e) -> {
button.setDisable(false);
});
}
/**
* 更新 天眼查 资讯资信
*
* @see #onCloudTycUpdateButtonClickedAction(ActionEvent)
*/
private void onCloudTycUpdateButtonClicked(ActionEvent event) {
// TODO 待实现
setStatus("待实现");
// CompletableFuture.delayedExecutor(2, TimeUnit.SECONDS).execute(() -> {
// button.setDisable(false);
// });
}
/**
* 初始化 天眼查平台 Titled Pane
*/
private void initializeCloudTycPane() {
// 记录编号
cloudTycIdField.textProperty().bind(tycCloudInfoViewModel.getId().asString());
// 平台编号
cloudTycCloudIdField.textProperty().bindBidirectional(tycCloudInfoViewModel.getCloudId());
cloudTycLatestField.textProperty().bind(tycCloudInfoViewModel.getLatest().map(MyDateTimeUtils::format));
cloudTycVersionLabel.textProperty().bind(tycCloudInfoViewModel.getVersion().asString("Ver:%s"));
TextField cloudIdField = cloudTycCloudIdField;
TextField cloudScoreField = tycCloudPaneCloudScore;
DelayOnceExecutor saveExecutor = new DelayOnceExecutor(() -> {
cloudTycService.save(tycCloudInfoViewModel);
cloudIdField.setBorder(null);
cloudScoreField.setBorder(null);
tycCloudPaneSaveButton.setDisable(true);
setStatus("保存成功");
}, 2, TimeUnit.SECONDS).exception(e -> logger.error(e.getMessage(), e));
cloudIdField.setOnKeyPressed(event -> {
cloudIdField.setBorder(Border.stroke(Color.RED));
tycCloudPaneSaveButton.setDisable(false);
saveExecutor.tick();
});
cloudScoreField.setOnKeyPressed(event -> {
cloudScoreField.setBorder(Border.stroke(Color.RED));
tycCloudPaneSaveButton.setDisable(false);
saveExecutor.tick();
});
cloudScoreField.textProperty().bindBidirectional(tycCloudInfoViewModel.getScore(), new NumberStringConverter());
tycCloudPaneSaveButton.setOnAction(event -> {
saveExecutor.tickNow();
});
}
private void initializeCloudYuPane() {
try {
yongYouU8Service = getBean(YongYouU8Service.class);
} catch (BeansException e) {
yuCloudPane.setDisable(true);
}
cloudYuIdField.textProperty().bind(yuCloudInfoViewModel.getId().asString());
cloudYuCloudIdField.textProperty().bindBidirectional(yuCloudInfoViewModel.getCloudId());
cloudYuLatestField.textProperty().bind(yuCloudInfoViewModel.getLatest().map(MyDateTimeUtils::format));
cloudYuVersionLabel.textProperty().bind(yuCloudInfoViewModel.getVersion().asString("Ver:%s"));
Button button = yuCloudPaneSaveButton;
// 更新
button.setOnAction(event -> {
button.setDisable(true);
CompletableFuture.runAsync(() -> {
try {
onCloudYuUpdateButtonClicked(event);
} catch (Exception e) {
UITools.showExceptionAndWait("", e);
}
}).whenComplete((v, e) -> {
button.setDisable(false);
});
});
}
private void onCloudYuUpdateButtonClicked(ActionEvent event) {
Company company = getEntity();
// service.syncVendor(company);
}
private void initializeExtendInfoPane() {
// 记录编号
extendInfoIdField.textProperty().bind(extendInfoViewModel.getId().asString());
extendInfoDisableVerifyField.selectedProperty().bindBidirectional(extendInfoViewModel.getDisableVerify());
extendInfoVersionLabel.textProperty().bind(extendInfoViewModel.getVersion().asString("Ver:%s"));
DelayOnceExecutor saveExecutor = new DelayOnceExecutor(() -> {
save(extendInfoViewModel);
extendInfoDisableVerifyField.setBorder(null);
}, 2, TimeUnit.SECONDS).exception(e -> logger.error(e.getMessage(), e));
extendInfoDisableVerifyField.setOnMouseClicked(event -> {
extendInfoDisableVerifyField.setBorder(Border.stroke(Color.RED));
saveExecutor.tick();
});
extendInfoPaneSaveButton.setOnAction(event -> {
saveExecutor.tickNow();
});
}
public void save(CompanyExtendInfoViewModel viewModel) {
int infoId = viewModel.getId().get();
CompanyExtendInfoService service = getExtendInfoService();
CompanyExtendInfo cloudRk = service.findById(infoId);
if (cloudRk == null) {
throw new RuntimeException("CloudRk not found");
}
if (viewModel.copyTo(cloudRk)) {
CompanyExtendInfo saved = service.save(cloudRk);
if (Platform.isFxApplicationThread()) {
viewModel.update(saved);
} else {
Platform.runLater(() -> {
viewModel.update(saved);
});
}
}
}
private void updateRKCloudPane(Company company, TitledPane pane) {
CloudRkInfoViewModel viewModel = rkCloudInfoViewModel;
CloudRk cloudRk = getCloudRkService().getOrCreateCloudRk(company);
Platform.runLater(() -> {
viewModel.update(cloudRk);
});
}
private void updateTYCCloudPane(Company company, TitledPane pane) {
CloudTycInfoViewModel viewModel = tycCloudInfoViewModel;
CloudTyc cloudTyc = getCloudTycService().getOrCreateCloudTyc(company);
Platform.runLater(() -> {
viewModel.update(cloudTyc);
});
}
private void updateYuCloudPane(Company company, TitledPane pane) {
CloudYuInfoViewModel viewModel = yuCloudInfoViewModel;
if (yongYouU8Service == null) {
setStatus("未启用 " + YongYouU8Service.NAME + " 服务");
return;
}
CloudYu cloudYu = yongYouU8Service.getOrCreateCloudYu(company);
Platform.runLater(() -> {
viewModel.update(cloudYu);
});
}
private void updateExtendInfoPane(Company company, TitledPane pane) {
CompanyExtendInfoViewModel viewModel = extendInfoViewModel;
CompanyExtendInfoService service = getExtendInfoService();
CompanyExtendInfo extendInfo = service.findByCompany(company);
Platform.runLater(() -> {
viewModel.update(extendInfo);
});
}
CloudRkService getCloudRkService() {
if (cloudRkService == null) {
cloudRkService = getBean(CloudRkService.class);
}
return cloudRkService;
}
CloudTycService getCloudTycService() {
if (cloudTycService == null) {
cloudTycService = getBean(CloudTycService.class);
}
return cloudTycService;
}
CompanyExtendInfoService getExtendInfoService() {
if (extendInfoService == null) {
extendInfoService = getBean(CompanyExtendInfoService.class);
}
return extendInfoService;
}
YongYouU8Service getYongYouU8Service() {
return yongYouU8Service;
}
}

View File

@@ -0,0 +1,157 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.Invoice;
import com.ecep.contract.manager.ds.company.service.InvoiceService;
import com.ecep.contract.manager.ds.contract.model.PurchaseBillVoucher;
import com.ecep.contract.manager.ds.contract.service.PurchaseBillVoucherService;
import com.ecep.contract.manager.ds.contract.vo.PurchaseBillVoucherViewModel;
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.ui.util.LocalDateTimeTableCell;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import org.springframework.beans.BeansException;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
/**
* 子合同
*/
@FxmlPath("/ui/company/company-tab-purchase-bill-voucher.fxml")
public class CompanyTabSkinPurchaseBillVoucher
extends AbstCompanyTableTabSkin<PurchaseBillVoucher, PurchaseBillVoucherViewModel>
implements TabSkin {
public TableColumn<PurchaseBillVoucherViewModel, Number> contractTable_idColumn;
public TableColumn<PurchaseBillVoucherViewModel, Number> contractTable_refIdColumn;
public TableColumn<PurchaseBillVoucherViewModel, Invoice> invoiceColumn;
public TableColumn<PurchaseBillVoucherViewModel, String> contractTable_codeColumn;
public TableColumn<PurchaseBillVoucherViewModel, Employee> employeeColumn;
public TableColumn<PurchaseBillVoucherViewModel, Employee> makerColumn;
public TableColumn<PurchaseBillVoucherViewModel, LocalDateTime> makerDateColumn;
public TableColumn<PurchaseBillVoucherViewModel, LocalDateTime> modifyDateColumn;
public TableColumn<PurchaseBillVoucherViewModel, Employee> verifierColumn;
public TableColumn<PurchaseBillVoucherViewModel, LocalDateTime> verifierDateColumn;
public TableColumn<PurchaseBillVoucherViewModel, String> descriptionColumn;
public TextField searchKeyField;
public Button searchBtn;
public MenuItem contractTable_menu_refresh;
public MenuItem contractTable_menu_add;
public MenuItem contractTable_menu_del;
@Setter
private PurchaseBillVoucherService purchaseBillVoucherService;
@Setter
private InvoiceService invoiceService;
@Setter
private YongYouU8Service u8Service;
@Setter
private EmployeeStringConverter employeeStringConverter;
public CompanyTabSkinPurchaseBillVoucher(CompanyWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.purchaseBillVoucherTab;
}
@Override
public void initializeTab() {
if (u8Service == null) {
try {
u8Service = getBean(YongYouU8Service.class);
} catch (BeansException ignored) {
}
}
searchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
searchBtn.fire();
}
});
searchBtn.setOnAction(this::onTableRefreshAction);
searchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
searchBtn.fire();
}
});
contractTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
contractTable_refIdColumn.setCellValueFactory(param -> param.getValue().getRefId());
contractTable_codeColumn.setCellValueFactory(param -> param.getValue().getCode());
employeeColumn.setCellValueFactory(param -> param.getValue().getEmployee());
employeeColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
invoiceColumn.setCellValueFactory(param -> param.getValue().getInvoice());
invoiceColumn.setCellFactory(param -> new InvoiceTableCell<>(getInvoiceService()));
makerColumn.setCellValueFactory(param -> param.getValue().getMaker());
makerColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
makerDateColumn.setCellValueFactory(param -> param.getValue().getMakerDate());
makerDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
modifyDateColumn.setCellValueFactory(param -> param.getValue().getModifyDate());
modifyDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
verifierColumn.setCellValueFactory(param -> param.getValue().getVerifier());
verifierColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
verifierDateColumn.setCellValueFactory(param -> param.getValue().getVerifierDate());
verifierDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
contractTable_menu_refresh.setOnAction(this::onTableRefreshAction);
contractTable_menu_del.setOnAction(this::onTableDeleteAction);
super.initializeTab();
}
@Override
protected void onTableRowDoubleClickedAction(PurchaseBillVoucherViewModel item) {
// ContractWindowController.show(item, controller.root.getScene().getWindow());
}
@Override
protected PurchaseBillVoucherService getViewModelService() {
return getPurchaseBillVoucherService();
}
private PurchaseBillVoucherService getPurchaseBillVoucherService() {
if (purchaseBillVoucherService == null) {
purchaseBillVoucherService = getBean(PurchaseBillVoucherService.class);
}
return purchaseBillVoucherService;
}
private EmployeeStringConverter getEmployeeStringConverter() {
if (employeeStringConverter == null) {
employeeStringConverter = getBean(EmployeeStringConverter.class);
}
return employeeStringConverter;
}
private InvoiceService getInvoiceService() {
if (invoiceService == null) {
invoiceService = getBean(InvoiceService.class);
}
return invoiceService;
}
}

View File

@@ -0,0 +1,41 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import org.hibernate.Hibernate;
import static com.ecep.contract.manager.SpringApp.getBean;
public class CompanyTableCell<V> extends javafx.scene.control.TableCell<V, com.ecep.contract.manager.ds.company.model.Company> {
private CompanyService companyService;
public CompanyTableCell() {
}
public CompanyTableCell(CompanyService companyService) {
this.companyService = companyService;
}
private CompanyService getCompanyService() {
if (companyService == null) {
companyService = getBean(CompanyService.class);
}
return companyService;
}
@Override
protected void updateItem(Company item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
return;
}
if (!Hibernate.isInitialized(item)) {
item = getCompanyService().findById(item.getId());
}
setText(item.getName());
}
}

View File

@@ -0,0 +1,15 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ui.BaseController;
import com.ecep.contract.manager.ui.FxmlPath;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/company/company-verify.fxml")
public class CompanyVerifyWindowController extends BaseController {
}

View File

@@ -0,0 +1,314 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.Desktop;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyFileService;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.tasker.CompanyCompositeUpdateTasker;
import com.ecep.contract.manager.ds.company.tasker.CompanyVerifyTasker;
import com.ecep.contract.manager.ds.company.vo.CompanyViewModel;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.customer.controller.CompanyCustomerWindowController;
import com.ecep.contract.manager.ds.customer.model.CompanyCustomer;
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
import com.ecep.contract.manager.ds.vendor.controller.CompanyVendorWindowController;
import com.ecep.contract.manager.ds.vendor.model.CompanyVendor;
import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
import com.ecep.contract.manager.ui.AbstEntityBasedTabSkin;
import com.ecep.contract.manager.ui.AbstEntityController;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.util.UITools;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.hibernate.Hibernate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/company/company.fxml")
public class CompanyWindowController
extends AbstEntityController<Company, CompanyViewModel> {
private static final Logger logger = LoggerFactory.getLogger(CompanyWindowController.class);
public static void show(Company company, Window window) {
CompanyViewModel viewModel = new CompanyViewModel();
if (!Hibernate.isInitialized(company)) {
company = SpringApp.getBean(CompanyService.class).findById(company.getId());
}
viewModel.update(company);
show(viewModel, window);
}
/**
* 显示界面
*/
public static void show(CompanyViewModel viewModel, Window window) {
show(CompanyWindowController.class, viewModel, window);
}
@Autowired
private CompanyService companyService;
@Autowired
private CompanyFileService companyFileService;
@Autowired
private ContractService contractService;
@Autowired
private CompanyCustomerService companyCustomerService;
@Autowired
private CompanyVendorService companyVendorService;
public BorderPane root;
public TabPane tabPane;
public Tab baseInfoTab;
public Tab oldNameTab;
public Tab contactTab;
public Tab blackReasonTab;
public Tab customerTab;
public Tab vendorTab;
public Tab bankAccountTab;
public Tab contractTab;
public Tab fileTab;
public Tab invoiceTab;
public Tab purchaseBillVoucherTab;
public Tab otherTab;
/*
*/
public TextField nameField;
public TextField shortNameField;
public TextField uidField;
public TextField entStatusField;
public DatePicker setupDateField;
public TextField entTypeField;
public TextField industryField;
public TextField districtField;
public CheckBox pathExistField;
public TextField pathField;
public DatePicker createdDateField;
public TextField telephoneField;
public TextField regAddressField;
public TextField addressField;
public TextField registeredCapitalField;
public TextField registeredCapitalCurrencyField;
public TextField legalRepresentativeField;
public DatePicker operationPeriodBeginField;
public DatePicker operationPeriodEndField;
public TextArea memoField;
public Label versionLabel;
public Button companyRenameBtn;
public Button companyPathCreateBtn;
public Button companyPathChangeBtn;
public Button companyPathSameAsNameBtn;
// private final CompanyCustomerViewModel companyCustomerViewModel = new CompanyCustomerViewModel();
// private final CompanyVendorViewModel companyVendorViewModel = new CompanyVendorViewModel();
private final SimpleObjectProperty<CompanyCustomer> companyCustomerProperty = new SimpleObjectProperty<>();
private final SimpleObjectProperty<CompanyVendor> companyVendorProperty = new SimpleObjectProperty<>();
public Pane customerTab_pane1;
public Button customerTab_openBtn;
public Pane customerTab_pane2;
public Button customerTab_createBtn;
public Pane vendorTab_pane1;
public Button vendorTab_openBtn;
public Pane vendorTab_pane2;
public Button vendorTab_createBtn;
@Override
public void show(Stage stage) {
super.show(stage);
stage.minWidthProperty().set(600);
stage.minHeightProperty().set(450);
getTitle().set("[" + viewModel.getId().get() + "] " + viewModel.getName().getValue() + " 公司详情");
}
@Override
protected Company loadEntity() {
return companyService.findById(viewModel.getId().get());
}
@Override
protected Company saveEntity(Company entity) {
return companyService.save(entity);
}
@Override
protected void registerTabSkins() {
registerTabSkin(baseInfoTab, tab1 -> new CompanyTabSkinBase(this));
registerTabSkin(oldNameTab, tab1 -> new CompanyTabSkinOldName(this));
registerTabSkin(contactTab, tab1 -> new CompanyTabSkinContact(this));
registerTabSkin(blackReasonTab, tab1 -> new CompanyTabSkinBlackReason(this));
registerTabSkin(bankAccountTab, tab1 -> new CompanyTabSkinBankAccount(this));
registerTabSkin(contractTab, this::createContractTabSkin);
registerTabSkin(fileTab, this::createFileTabSkin);
registerTabSkin(invoiceTab, tab -> new CompanyTabSkinInvoice(this));
registerTabSkin(purchaseBillVoucherTab, tab -> new CompanyTabSkinPurchaseBillVoucher(this));
registerTabSkin(otherTab, tab -> new CompanyTabSkinOther(this));
initializeVendorTab();
initializeCustomerTab();
}
@Override
protected <K extends AbstEntityBasedTabSkin<?, ?, ?>> K registerTabSkin(Tab tab, Function<Tab, K> func) {
K skin = super.registerTabSkin(tab, func);
if (skin instanceof AbstCompanyBasedTabSkin b) {
b.setViewModel(viewModel);
}
return skin;
}
@Override
public CompanyService getViewModelService() {
return companyService;
}
private CompanyTabSkinContract createContractTabSkin(Tab tab) {
CompanyTabSkinContract skin = new CompanyTabSkinContract(this);
skin.setContractService(contractService);
return skin;
}
private CompanyTabSkinFile createFileTabSkin(Tab tab) {
CompanyTabSkinFile skin = new CompanyTabSkinFile(this);
skin.setCompanyFileService(companyFileService);
return skin;
}
private void initializeCustomerTab() {
customerTab.setOnSelectionChanged(event -> {
if (logger.isDebugEnabled()) {
logger.debug("customerTab OnSelectionChanged");
}
if (customerTab.isSelected()) {
onCustomerTabShown();
}
});
customerTab_pane1.visibleProperty().bind(customerTab_pane2.visibleProperty().not());
customerTab_pane2.visibleProperty().bind(companyCustomerProperty.isNull());
customerTab_createBtn.setOnAction(event -> {
// TODO 创建
});
customerTab_openBtn.setOnAction(event -> {
CompanyCustomerWindowController.show(companyCustomerProperty.get(), root.getScene().getWindow());
});
}
private void onCustomerTabShown() {
if (logger.isDebugEnabled()) {
logger.debug("onCustomerTabShown");
}
getLoadedFuture().thenAcceptAsync(company -> {
companyCustomerProperty.set(companyCustomerService.findByCompany(company));
}).exceptionally(ex -> {
UITools.showExceptionAndWait(ex.getMessage(), ex);
return null;
});
}
private void initializeVendorTab() {
vendorTab.setOnSelectionChanged(event -> {
if (logger.isDebugEnabled()) {
logger.debug("vendorTab OnSelectionChanged");
}
if (vendorTab.isSelected()) {
onVendorTabShown();
}
});
vendorTab_pane1.visibleProperty().bind(vendorTab_pane2.visibleProperty().not());
vendorTab_pane2.visibleProperty().bind(companyVendorProperty.isNull());
vendorTab_createBtn.setOnAction(event -> {
// TODO 创建
});
vendorTab_openBtn.setOnAction(event -> {
CompanyVendorWindowController.show(companyVendorProperty.get(), root.getScene().getWindow());
});
}
private void onVendorTabShown() {
if (logger.isDebugEnabled()) {
logger.debug("onVendorTabShown");
}
getLoadedFuture().thenAcceptAsync(company -> {
if (logger.isDebugEnabled()) {
logger.debug("onVendorTabShown company {}", company.getName());
}
companyVendorProperty.set(companyVendorService.findByCompany(company));
}).exceptionally(ex -> {
UITools.showExceptionAndWait(ex.getMessage(), ex);
return null;
});
}
/**
* 合并更新企业信息
*/
public void onCompanyCompositeUpdateAction(ActionEvent event) {
CompanyCompositeUpdateTasker task = new CompanyCompositeUpdateTasker();
task.setCompany(getEntity());
UITools.showTaskDialogAndWait("更新企业信息", task, null);
}
/**
* 企业合规检查
*/
public void onCompanyVerifyAction(ActionEvent event) {
Company company = getEntity();
CompanyVerifyTasker task = new CompanyVerifyTasker();
task.setCompanyService(companyService);
task.setCompany(company);
UITools.showTaskDialogAndWait("企业合规性验证", task, null);
}
public void onCompanyOpenInExplorerAction(ActionEvent event) {
Company company = getEntity();
String path = company.getPath();
CompletableFuture.runAsync(() -> {
if (!StringUtils.hasText(path)) {
ButtonType buttonType = UITools.showConfirmation("目录未设置", "是否创建目录").join();
if (buttonType == ButtonType.OK) {
if (companyService.makePathAbsent(company)) {
save(company);
}
} else {
setStatus("未设置目录");
return;
}
}
Desktop.checkAndShowInExplorer(company.getPath(), this::setStatus);
});
}
}

View File

@@ -0,0 +1,40 @@
package com.ecep.contract.manager.ds.company.controller;
import com.ecep.contract.manager.ds.company.model.Invoice;
import com.ecep.contract.manager.ds.company.service.InvoiceService;
import javafx.scene.control.TableCell;
import org.hibernate.Hibernate;
import static com.ecep.contract.manager.SpringApp.getBean;
class InvoiceTableCell<V> extends TableCell<V, Invoice> {
private InvoiceService invoiceService;
public InvoiceTableCell() {
}
public InvoiceTableCell(InvoiceService invoiceService) {
this.invoiceService = invoiceService;
}
private InvoiceService getInvoiceService() {
if (invoiceService == null) {
invoiceService = getBean(InvoiceService.class);
}
return invoiceService;
}
@Override
protected void updateItem(Invoice item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
} else {
if (!Hibernate.isInitialized(item)) {
item = getInvoiceService().findById(item.getId());
}
setText(item.getCode());
}
}
}

View File

@@ -0,0 +1,83 @@
package com.ecep.contract.manager.ds.company.controller.bank_account;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.company.CompanyStringConverter;
import com.ecep.contract.manager.ds.company.controller.CompanyWindowController;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBankAccount;
import com.ecep.contract.manager.ds.company.service.CompanyBankAccountService;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.vo.CompanyBankAccountViewModel;
import com.ecep.contract.manager.ds.other.BankStringConverter;
import com.ecep.contract.manager.ds.other.service.BankService;
import com.ecep.contract.manager.ui.AbstEntityBasedTabSkin;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.util.UITools;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import lombok.Setter;
public class BankAccountBaseTabSkin extends AbstEntityBasedTabSkin<BankAccountWindowController, CompanyBankAccount, CompanyBankAccountViewModel> implements TabSkin {
@Setter
private CompanyService companyService;
@Setter
private BankService bankService;
public BankAccountBaseTabSkin(BankAccountWindowController controller) {
super(controller);
viewModel = controller.getViewModel();
}
@Override
public Tab getTab() {
return controller.baseInfoTab;
}
@Override
public void initializeTab() {
initializeBaseTabCompanyFieldAutoCompletion(controller.companyField);
initializeBaseTabBankFieldAutoCompletion(controller.bankField);
controller.openingBankField.textProperty().bindBidirectional(viewModel.getOpeningBank());
controller.bankAccountField.textProperty().bindBidirectional(viewModel.getAccount());
// controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());
controller.createdField.textProperty().bind(viewModel.getCreated().asString());
controller.versionLabel.textProperty().bind(viewModel.getVersion().asString());
controller.relativeCompanyBtn.disableProperty().bind(viewModel.getCompany().isNull());
controller.relativeCompanyBtn.setOnAction(event -> {
Company company = viewModel.getCompany().get();
if (company != null) {
CompanyWindowController.show(company, controller.root.getScene().getWindow());
}
});
}
private void initializeBaseTabCompanyFieldAutoCompletion(TextField textField) {
CompanyStringConverter converter = SpringApp.getBean(CompanyStringConverter.class);
UITools.autoCompletion(textField, viewModel.getCompany(), converter::suggest, converter);
}
private void initializeBaseTabBankFieldAutoCompletion(TextField textField) {
BankStringConverter converter = SpringApp.getBean(BankStringConverter.class);
UITools.autoCompletion(textField, viewModel.getBank(), converter::suggest, converter);
}
public BankService getBankService() {
if (bankService == null) {
bankService = getBean(BankService.class);
}
return bankService;
}
public CompanyService getCompanyService() {
if (companyService == null) {
companyService = getBean(CompanyService.class);
}
return companyService;
}
}

View File

@@ -0,0 +1,61 @@
package com.ecep.contract.manager.ds.company.controller.bank_account;
import com.ecep.contract.manager.ds.company.model.CompanyBankAccount;
import com.ecep.contract.manager.ds.company.service.CompanyBankAccountService;
import com.ecep.contract.manager.ds.company.vo.CompanyBankAccountViewModel;
import com.ecep.contract.manager.ui.AbstEntityController;
import com.ecep.contract.manager.ui.FxmlPath;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/company/bank-account.fxml")
public class BankAccountWindowController extends AbstEntityController<CompanyBankAccount, CompanyBankAccountViewModel> {
public BorderPane root;
public TabPane tabPane;
public Tab baseInfoTab;
public TextField companyField;
public Button relativeCompanyBtn;
public TextField bankField;
public TextField openingBankField;
public TextField bankAccountField;
public TextField createdField;
public TextArea descriptionField;
public Label versionLabel;
public Tab entityTab;
public static void show(CompanyBankAccountViewModel viewModel, Window window) {
show(BankAccountWindowController.class, viewModel, window);
}
@Autowired
private CompanyBankAccountService bankAccountService;
@Override
public void onShown(WindowEvent event) {
super.onShown(event);
getTitle().set("[" + viewModel.getId().get() + "] 银行账户详情");
}
@Override
protected void registerTabSkins() {
registerTabSkin(baseInfoTab, tab -> new BankAccountBaseTabSkin(this));
}
@Override
public CompanyBankAccountService getViewModelService() {
return bankAccountService;
}
}

View File

@@ -0,0 +1,179 @@
package com.ecep.contract.manager.ds.company.controller.contact;
import com.ecep.contract.manager.ds.company.model.CompanyContact;
import com.ecep.contract.manager.ds.company.repository.CompanyContactRepository;
import com.ecep.contract.manager.ui.BaseController;
import com.ecep.contract.manager.ds.company.vo.CompanyContactViewModel;
import com.ecep.contract.manager.util.FxmlUtils;
import com.ecep.contract.manager.util.UITools;
import javafx.application.Platform;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
import javafx.util.converter.LocalDateStringConverter;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Lazy
@Scope("prototype")
@Component
public class CompanyContactWindowController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(CompanyContactWindowController.class);
/**
* 显示界面
*/
public static void show(CompanyContactViewModel viewModel, Window window) {
String key = toKey(viewModel);
// 一个合同一个界面
if (toFront(key)) {
return;
}
FxmlUtils.newLoaderAsyncWithRunLater("/ui/contact.fxml", null, loader -> {
CompanyContactWindowController controller = loader.getController();
controller.setViewModel(viewModel);
controller.show(loader, window, Modality.NONE, key);
});
}
private static String toKey(CompanyContactViewModel viewModel) {
return viewModel.getClass().getName() + "-" + viewModel.getId().get();
}
public Tab baseInfoTab;
public BorderPane root;
public TabPane tabPane;
@Getter
@Setter
private CompanyContactViewModel viewModel;
@Autowired
private CompanyContactRepository companyContactRepository;
public TextField nameField;
public TextField positionField;
public TextField phoneField;
public DatePicker createdField;
public TextField u8CodeField;
public TextField emailField;
public TextField addressField;
public TextArea descriptionField;
public Label versionLabel;
public Button saveBtn;
private CompletableFuture<CompanyContact> companyContactLoadedFuture;
@Override
public void show(Stage stage) {
super.show(stage);
getTitle().bind(viewModel.getName().map(v -> "[" + viewModel.getId().get() + "] " + viewModel.getName().getValue() + " 曾用名详情"));
}
@Override
public void onShown(WindowEvent windowEvent) {
super.onShown(windowEvent);
if (logger.isDebugEnabled()) {
logger.debug("onShown");
}
initializeBaseTab();
companyContactLoadedFuture = CompletableFuture.supplyAsync(() -> {
Optional<CompanyContact> optional = companyContactRepository.findById(viewModel.getId().get());
if (optional.isPresent()) {
CompanyContact oldName = optional.get();
Platform.runLater(() -> {
viewModel.update(oldName);
viewModel.bindListener();
if (logger.isDebugEnabled()) {
logger.debug("bind ViewModel({}) Listener", viewModel.getName().get());
}
tabPane.getSelectionModel().getSelectedItem().getOnSelectionChanged().handle(null);
});
return oldName;
}
return null;
});
}
private void initializeBaseTab() {
baseInfoTab.setOnSelectionChanged(event -> {
if (logger.isDebugEnabled()) {
logger.debug("baseInfoTab OnSelectionChanged");
}
if (baseInfoTab.isSelected()) {
onBaseTabShown();
}
});
saveBtn.disableProperty().bind(viewModel.getChanged().not());
saveBtn.setOnAction(event -> {
try {
CompanyContact contact = companyContactLoadedFuture.join();
viewModel.copyTo(contact);
CompanyContact saved = companyContactRepository.save(contact);
viewModel.update(saved);
companyContactLoadedFuture = CompletableFuture.completedFuture(saved);
} catch (Exception e) {
UITools.showExceptionAndWait("保存失败,请检查", e);
}
});
nameField.textProperty().bindBidirectional(viewModel.getName());
positionField.textProperty().bindBidirectional(viewModel.getPosition());
phoneField.textProperty().bindBidirectional(viewModel.getPhone());
emailField.textProperty().bindBidirectional(viewModel.getEmail());
addressField.textProperty().bindBidirectional(viewModel.getAddress());
LocalDateStringConverter converter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
createdField.setConverter(converter);
createdField.valueProperty().bindBidirectional(viewModel.getCreated());
u8CodeField.textProperty().bind(viewModel.getU8Code());
descriptionField.textProperty().bindBidirectional(viewModel.getMemo());
versionLabel.textProperty().bind(viewModel.getVersion().asString());
}
/**
* 基础页显示时回调函数
*/
private void onBaseTabShown() {
if (logger.isDebugEnabled()) {
logger.debug("onBaseTabShown");
}
companyContactLoadedFuture.thenAcceptAsync(contact -> {
if (logger.isDebugEnabled()) {
logger.debug("onBaseTabShown company contact {}", contact.getName());
}
// viewModel.update(contact);
}).exceptionally(ex -> {
UITools.showExceptionAndWait(ex.getMessage(), ex);
return null;
});
}
public void onHidden(WindowEvent windowEvent) {
if (viewModel != null) {
try {
viewModel.unBindListener();
if (logger.isDebugEnabled()) {
logger.debug("unbind ViewModel({}) Listener", viewModel.getName().get());
}
} catch (InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
super.onHidden(windowEvent);
}
}

View File

@@ -0,0 +1,65 @@
package com.ecep.contract.manager.ds.company.controller.old_name;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.service.CompanyOldNameService;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.vo.CompanyOldNameViewModel;
import com.ecep.contract.manager.ui.AbstEntityBasedTabSkin;
import com.ecep.contract.manager.ui.TabSkin;
import javafx.scene.control.Tab;
import javafx.util.converter.LocalDateStringConverter;
import lombok.Setter;
import java.time.format.DateTimeFormatter;
public class CompanyOldNameTabSkinBase
extends AbstEntityBasedTabSkin<CompanyOldNameWindowController, CompanyOldName, CompanyOldNameViewModel>
implements TabSkin {
@Setter
private CompanyService companyService;
@Setter
private CompanyOldNameService companyOldNameService;
public CompanyOldNameTabSkinBase(CompanyOldNameWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.baseInfoTab;
}
@Override
public void initializeTab() {
controller.nameField.textProperty().bind(viewModel.getName());
controller.ambiguityField.selectedProperty().bindBidirectional(viewModel.getAmbiguity());
LocalDateStringConverter converter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
controller.startDateField.setConverter(converter);
controller.startDateField.valueProperty().bindBidirectional(viewModel.getBeginDate());
controller.endDateField.setConverter(converter);
controller.endDateField.valueProperty().bindBidirectional(viewModel.getEndDate());
controller.pathField.textProperty().bind(viewModel.getPath());
controller.descriptionField.textProperty().bindBidirectional(viewModel.getMemo());
controller.versionLabel.textProperty().bind(viewModel.getVersion().asString());
controller.saveBtn.disableProperty().bind(viewModel.getChanged().not());
controller.saveBtn.setOnAction(this::onSaveAction);
}
public CompanyService getCompanyService() {
if (companyService == null) {
companyService = getBean(CompanyService.class);
}
return companyService;
}
public CompanyOldNameService getCompanyOldNameService() {
if (companyOldNameService == null) {
companyOldNameService = getBean(CompanyOldNameService.class);
}
return companyOldNameService;
}
}

View File

@@ -0,0 +1,363 @@
package com.ecep.contract.manager.ds.company.controller.old_name;
import com.ecep.contract.manager.Desktop;
import com.ecep.contract.manager.MyProperties;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.company.model.CompanyFile;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.service.CompanyFileService;
import com.ecep.contract.manager.ds.company.service.CompanyOldNameService;
import com.ecep.contract.manager.ds.company.vo.CompanyFileViewModel;
import com.ecep.contract.manager.ds.company.vo.CompanyOldNameViewModel;
import com.ecep.contract.manager.ui.AbstEntityTableTabSkin;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.util.SpecificationUtils;
import com.ecep.contract.manager.util.UITools;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.scene.control.Tab;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableView;
import lombok.Setter;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.io.File;
import java.util.List;
import java.util.function.Consumer;
/**
*
*/
public class CompanyOldNameTabSkinFile
extends AbstEntityTableTabSkin<CompanyOldNameWindowController, CompanyOldName, CompanyOldNameViewModel, CompanyFile, CompanyFileViewModel>
implements TabSkin {
@Setter
private CompanyOldNameService companyOldNameService;
@Setter
private CompanyFileService companyFileService;
@Setter
private MyProperties myProperties;
public CompanyOldNameTabSkinFile(CompanyOldNameWindowController controller) {
super(controller);
setDragAndDrop(true);
setDragAndDropFileHandler(this::moveFileToCompany);
}
@Override
public Tab getTab() {
return controller.fileTab;
}
@Override
public TableView<CompanyFileViewModel> getTableView() {
return controller.fileTable;
}
@Override
protected CompanyFileService getViewModelService() {
return companyFileService;
}
@Override
public Specification<CompanyFile> getSpecification(CompanyOldName parent) {
return SpecificationUtils.and(getSpecification(), (root, query, builder) -> {
return builder.equal(root.get("company").get("id"), parent.getCompanyId());
});
}
@Override
public void initializeTab() {
// controller.fileTable_file_move_btn.setOnAction(this::onTableMoveFileAction);
// controller.fileTable_file_retrieve_from_download_dir_btn.setOnAction(this::onTableRetrieveFromDownloadDirAction);
// controller.fileTable_file_reset_btn.setOnAction(this::onTableResetAction);
//
//
// controller.fileTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
// ObservableMap<CompanyFileType, CompanyFileTypeLocal> observableMapByLocal = getBean(CompanyFileTypeLocalRepository.class).getObservableMapByLocal();
// controller.fileTable_typeColumn.setCellValueFactory(param -> Bindings.valueAt(observableMapByLocal,
// param.getValue().getType()).map(CompanyFileTypeLocal::getValue));
// controller.fileTable_filePathColumn.setCellValueFactory(param -> param.getValue().getFilePath());
// controller.fileTable_filePathColumn.setCellFactory(param -> new FileTableFilePathTableCell());
// controller.fileTable_applyDateColumn.setCellValueFactory(param -> param.getValue().getApplyDate());
// controller.fileTable_expiringDateColumn.setCellValueFactory(param -> param.getValue().getExpiringDate());
//
//
// controller.fileTable_menu_refresh.setOnAction(this::onTableRefreshAction);
// controller.fileTable_menu_del.setOnAction(this::onTableDeleteAction);
// controller.fileTable_menu_copy_as_matched_by_contract.setOnAction(this::onTableCopyAsMatchedByContractAction);
// controller.fileTable_menu_copy_as_matched_by_contract.setOnMenuValidation(this::onTableCopyAsMatchedMenuValidation);
super.initializeTab();
}
private void onTableResetAction(ActionEvent event) {
CompanyOldName oldName = getParent();
// CompletableFuture.runAsync(() -> {
// if (getCompanyFileService().reBuildingFiles(oldName, this::setStatus)) {
// loadTableDataSet();
// }
// });
}
/**
* 从 下载目录 中查找相关的资质文件
*/
private void onTableRetrieveFromDownloadDirAction(ActionEvent event) {
// CompanyOldName oldName = getParent();
// MyProperties myProperties = getMyProperties();
// File dir = myProperties.getDownloadDirectory();
// if (!dir.exists()) {
// setStatus("下载目录 " + dir.getAbsolutePath() + " 不存在,请检查");
// return;
// }
//
// setStatus("开始检索 下载 文件夹:" + dir.getAbsolutePath() + "...");
// File[] files = dir.listFiles(File::isFile);
// if (files == null) {
// setStatus("检索 下载 文件夹失败");
// return;
// }
// if (files.length == 0) {
// setStatus("下载 文件夹没有文件");
// return;
// }
// setStatus("下载 文件夹中共有文件 " + files.length + " 个文件");
//
// if (getCompanyOldNameService().retrieveFromDownloadFiles(oldName, files, this::setStatus)) {
// // fixed if update
// viewModel.update(oldName);
// loadTableDataSet();
// }
}
/**
* 把文件从 老系统中移到 \\10.84.209.8\项目信息\相关方信息 目录中
*/
private void onTableMoveFileAction(ActionEvent event) {
// CompanyFileService companyFileService = getCompanyFileService();
// CompanyOldName oldName = getParent();
// List<CompanyFile> list = companyFileService.findByCompany(oldName);
// if (list.isEmpty()) {
// return;
// }
// if (getCompanyService().makePathAbsent(oldName)) {
// save(oldName);
// }
//
// String path = oldName.getPath();
// if (!StringUtils.hasText(path)) {
// setStatus("异常, 企业目录未设置");
// return;
// }
// File companyPath = new File(path);
// for (CompanyFile companyFile : list) {
// String filePath = companyFile.getFilePath();
// if (StringUtils.hasText(filePath)) {
// File file = new File(filePath);
// if (file.exists()) {
// if (file.getParentFile().equals(companyPath)) {
// continue;
// }
// File dest = new File(companyPath, file.getName());
// if (file.renameTo(dest)) {
// companyFile.setFilePath(dest.getAbsolutePath());
// companyFileService.save(companyFile);
// setStatus(file.getName() + " 移动到 " + companyPath.getName());
// }
// }
// }
// }
}
/**
*
*/
private void onTableCopyAsMatchedByContractAction(ActionEvent event) {
UITools.showDialogAndWait("复制资信评估报告", "按当前评估报告复制一个合同中最匹配的", list -> {
onTableCopyAsMatchedAction_(msg -> {
Platform.runLater(() -> {
list.add(msg);
});
});
});
}
private void onTableCopyAsMatchedAction_(Consumer<String> state) {
// CompanyOldName oldName = getParent();
//
// CompanyFileViewModel selectedItem = table.getSelectionModel().getSelectedItem();
// if (selectedItem == null) {
// state.accept("未选择行");
// return;
// }
// if (selectedItem.getApplyDate().get() == null) {
// state.accept("有效日期不能未空");
// return;
// }
//
// LocalDate nextCreditReportDate = null;
// try {
// nextCreditReportDate = companyFileService.getNextCreditReportDate(oldName, state);
// if (nextCreditReportDate == null) {
// state.accept("没有找到下一个咨询评估日期");
// return;
// }
// } catch (Exception e) {
// state.accept("获取下一个咨询评估日期失败:" + e.getMessage());
// return;
// }
//
// state.accept("下一个咨询评估日期:" + nextCreditReportDate);
//
// if (!nextCreditReportDate.isBefore(selectedItem.getApplyDate().get())) {
// state.accept("咨询评估日期晚于下一个咨询评估日期");
// return;
// }
//
//
// File src = new File(selectedItem.getFilePath().get());
// if (!src.exists()) {
// state.accept("当前选择行的文件不存在");
// return;
// }
//
// String srcDate = MyDateTimeUtils.format(selectedItem.getApplyDate().get());
// String destDate = MyDateTimeUtils.format(nextCreditReportDate);
// String srcFileName = src.getName();
// String destFileName;
//
// // 天眼查的报告
// if (CloudTycService.isTycReport(srcFileName)) {
// state.accept("天眼查的报告按标准格式命名");
// String name = oldName.getName() + "_" + CloudTycService.NAME;
// if (srcFileName.contains(CloudTycService.TYC_ENTERPRISE_BASIC_REPORT)) {
// name = name + "_" + CloudTycService.TYC_ENTERPRISE_BASIC_REPORT;
// } else if (srcFileName.contains(CloudTycService.TYC_ENTERPRISE_MAJOR_REPORT)) {
// name = name + "_" + CloudTycService.TYC_ENTERPRISE_MAJOR_REPORT;
// } else if (srcFileName.contains(CloudTycService.TYC_ENTERPRISE_ANALYSIS_REPORT)) {
// name = name + "_" + CloudTycService.TYC_ENTERPRISE_ANALYSIS_REPORT;
// }
// destFileName = name + "_" + destDate + "_cp." + StringUtils.getFilenameExtension(srcFileName);
// } else {
// if (srcFileName.contains(srcDate)) {
// // 如果文件名中包含日期,则替换为新日期
// destFileName = srcFileName.replace(srcDate, destDate + "_cp");
// } else {
// // 如果文件名中不包含日期,则添加日期
// destFileName = oldName.getName() + "_" + destDate + "_cp." + StringUtils.getFilenameExtension(srcFileName);
// }
// }
//
// state.accept("新文件名:" + destFileName);
//
// File dest = new File(src.getParent(), destFileName);
// try {
// FileSystemUtils.copyRecursively(src, dest);
// state.accept("新文件复制成功");
// } catch (IOException e) {
// state.accept("新文件复制失败:" + e.getMessage());
// }
//
// CompanyFile companyFile = new CompanyFile();
// companyFile.setFilePath(dest.getAbsolutePath());
// companyFile.setApplyDate(nextCreditReportDate);
// companyFile.setExpiringDate(nextCreditReportDate.plusYears(1));
// companyFile.setType(CompanyFileType.CreditReport);
// companyFile.setCompany(oldName);
// companyFileService.save(companyFile);
//
// state.accept("新文件已记录");
//
// loadTableDataSet();
// state.accept("文件表已刷新");
}
/**
* 当fileTable选中的行是咨询评估时可用
*
* @param event event
*/
public void onTableCopyAsMatchedMenuValidation(Event event) {
//当fileTable选中的行是咨询评估时可用
CompanyFileViewModel selectedItem = getSelectedItem();
if (selectedItem == null) {
event.consume();
return;
}
CompanyFileType type = selectedItem.getType().get();
if (type != CompanyFileType.CreditReport) {
event.consume();
return;
}
}
private void moveFileToCompany(List<File> files) {
String path = viewModel.getPath().get();
if (!StringUtils.hasText(path)) {
setStatus("未设置目录");
return;
}
File dir = new File(path);
if (!dir.exists()) {
setStatus("目录错误,不存在");
return;
}
}
@Override
protected void onTableRowDoubleClickedAction(CompanyFileViewModel item) {
String path = item.getFilePath().get();
if (StringUtils.hasText(path)) {
File file = new File(path);
if (!file.exists()) {
setStatus("文件不存在 " + file.getName());
return;
}
Desktop.showInExplorer(file);
}
}
class FileTableFilePathTableCell extends TableCell<CompanyFileViewModel, String> {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
return;
}
String path = viewModel.getPath().get();
if (StringUtils.hasText(path)) {
if (item.startsWith(path)) {
item = "~" + item.substring(path.length());
}
}
setText(item);
}
}
public MyProperties getMyProperties() {
if (myProperties == null) {
myProperties = getBean(MyProperties.class);
}
return myProperties;
}
private CompanyFileService getCompanyFileService() {
if (companyFileService == null) {
companyFileService = getBean(CompanyFileService.class);
}
return companyFileService;
}
public CompanyOldNameService getCompanyOldNameService() {
if (companyOldNameService == null) {
companyOldNameService = getBean(CompanyOldNameService.class);
}
return companyOldNameService;
}
}

View File

@@ -0,0 +1,132 @@
package com.ecep.contract.manager.ds.company.controller.old_name;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.service.CompanyOldNameService;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.vo.CompanyFileViewModel;
import com.ecep.contract.manager.ds.company.vo.CompanyOldNameViewModel;
import com.ecep.contract.manager.ui.AbstEntityController;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.UITools;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.File;
import java.util.concurrent.CompletableFuture;
import static com.ecep.contract.manager.Desktop.showInExplorer;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/company/company_old_name.fxml")
public class CompanyOldNameWindowController extends AbstEntityController<CompanyOldName, CompanyOldNameViewModel> {
private static final Logger logger = LoggerFactory.getLogger(CompanyOldNameWindowController.class);
/**
* 显示界面
*/
public static void show(CompanyOldNameViewModel viewModel, Window window) {
show(CompanyOldNameWindowController.class, viewModel, window);
}
public Tab baseInfoTab;
public BorderPane root;
public TabPane tabPane;
public Tab fileTab;
@Autowired
private CompanyOldNameService companyOldNameService;
@Autowired
private CompanyService companyService;
public TextField nameField;
public CheckBox ambiguityField;
public DatePicker startDateField;
public DatePicker endDateField;
public TextField pathField;
public TextArea descriptionField;
public Label versionLabel;
public Button saveBtn;
public Button saveBtn2;
public TableView<CompanyFileViewModel> fileTable;
@Override
public void onShown(WindowEvent windowEvent) {
super.onShown(windowEvent);
getTitle().set("[" + viewModel.getId().get() + "] " + viewModel.getName().getValue() + " 曾用名详情");
}
@Override
protected CompanyOldName loadEntity() {
return companyOldNameService.findById(viewModel.getId().get());
}
@Override
protected CompanyOldName saveEntity(CompanyOldName entity) {
return companyOldNameService.save(entity);
}
@Override
protected void registerTabSkins() {
registerTabSkin(baseInfoTab, this::createBaseTabSkin);
registerTabSkin(fileTab, this::createFileTabSkin);
}
@Override
public CompanyOldNameService getViewModelService() {
return companyOldNameService;
}
private CompanyOldNameTabSkinBase createBaseTabSkin(Tab tab) {
CompanyOldNameTabSkinBase skin = new CompanyOldNameTabSkinBase(this);
skin.setCompanyOldNameService(companyOldNameService);
return skin;
}
private CompanyOldNameTabSkinFile createFileTabSkin(Tab tab) {
CompanyOldNameTabSkinFile skin = new CompanyOldNameTabSkinFile(this);
skin.setCompanyOldNameService(companyOldNameService);
// skin.setCompanyFileService(companyFileService);
return skin;
}
public void onOldCompanyOpenInExplorerAction(ActionEvent event) {
CompanyOldName companyOldName = getEntity();
String path = companyOldName.getPath();
CompletableFuture.runAsync(() -> {
if (!StringUtils.hasText(path)) {
ButtonType buttonType = UITools.showConfirmation("目录未设置", "是否创建目录").join();
if (buttonType == ButtonType.OK) {
if (companyOldNameService.makePathAbsent(companyOldName)) {
save(companyOldName);
}
} else {
setStatus("未设置目录");
return;
}
}
File file = new File(companyOldName.getPath());
showInExplorer(file);
});
}
}

View File

@@ -0,0 +1,194 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import com.ecep.contract.manager.ds.other.model.NamedEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.proxy.HibernateProxy;
import java.time.LocalDate;
import java.util.Objects;
/**
* 公司信息类,保存企业信息
*/
@Getter
@Setter
@Entity
@Table(name = "COMPANY")
@ToString
public class Company implements IdentityEntity, NamedEntity, com.ecep.contract.manager.ds.other.model.Entity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 公司名称
*/
private String name;
/**
* 统一社会信用代码
* <p>
* 编码结构
* <pre>
* 1 | 1 | 6 | 9 | 1 <br>
* 登记管理部门代码|机构类别代码|登记管理机关行政区划码|主体标识码|校验码
* </pre>
* <ul>
* <li>登记管理部门代码(第 1 位):<br>
* 例如9 代表工商部门登记的企业等。</li>
* <li>机构类别代码(第 2 位):不同的数字表示不同类型的机构。如 1 表示企业2 表示个体工商户等。</li>
* <li>登记管理机关行政区划码(第 3 - 8 位):这 6 位数字代表了登记管理机关所在的行政区划,与身份证号码的前 6 位类似,可对应到具体的地区。</li>
* <li>主体标识码(组织机构代码,第 9 - 17 位):它是对中华人民共和国境内依法注册、依法登记的机关、企事业单位、社会团体和民办非企业单位等机构颁发的一个在全国范围内唯一的、始终不变的代码。</li>
* </ul>
* </p>
*/
@Column(name = "UNISCID", length = 30)
private String uniscid;
/**
* 简称
*/
@Column(name = "SHORT_NAME")
private String shortName;
/**
* 文件夹存在
*/
@Column(name = "PATH_EXIST")
private Boolean pathExist;
/**
* 文件夹路径
*/
@Column(name = "PATH")
private String path;
/**
* 记录创建日期
*/
@Column(name = "CREATED")
private LocalDate created;
/**
* 企业状态
*/
@Column(name = "ENT_STATUS")
private String entStatus;
/**
* 企业类型
*/
@Column(name = "ENT_TYPE")
private String entType;
/**
* 区域
*/
@Column(name = "DISTRICT")
private String district;
/**
* 行业
*/
@Column(name = "INDUSTRY")
private String industry;
/**
* 电话
*/
@Column(name = "TELEPHONE")
private String telephone;
/**
* 注册地址
*/
@Column(name = "REG_ADDR")
private String regAddr;
/**
* 通讯地址
*/
@ToString.Exclude
@Column(name = "ADDRESS")
private String address;
/**
* 成立日期
*/
@Column(name = "SETUP_DATE")
private LocalDate setupDate;
/**
* 营业期限起始
*/
@ToString.Exclude
@Column(name = "OPERATION_PERIOD_BEGIN")
private LocalDate operationPeriodBegin;
/**
* 营业期限截至
*/
@ToString.Exclude
@Column(name = "OPERATION_PERIOD_END")
private LocalDate operationPeriodEnd;
/**
* 注册资金
*/
@ToString.Exclude
@Column(name = "REGISTERED_CAPITAL")
private String registeredCapital;
/**
* 资本金币种
*/
@ToString.Exclude
@Column(name = "REGISTERED_CAPITAL_CURRENCY")
private String registeredCapitalCurrency;
/**
* 法人
*/
@ToString.Exclude
@Column(name = "LEGAL_REPRESENTATIVE")
private String legalRepresentative;
/**
* 备注
*/
@ToString.Exclude
@Column(name = "MEMO")
private String memo;
@Version
@ColumnDefault("0")
@Column(name = "VERSION", nullable = false)
@ToString.Exclude
private int version;
@Override
public String toPrettyString() {
return getName();
}
@Override
public final boolean equals(Object object) {
if (this == object) return true;
if (object == null) return false;
Class<?> oEffectiveClass = object instanceof HibernateProxy ? ((HibernateProxy) object).getHibernateLazyInitializer().getPersistentClass() : object.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
if (thisEffectiveClass != oEffectiveClass) return false;
Company company = (Company) object;
return getId() != null && Objects.equals(getId(), company.getId());
}
@Override
public final int hashCode() {
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
}
}

View File

@@ -0,0 +1,51 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.other.model.Bank;
import com.ecep.contract.manager.ds.other.model.Entity;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@jakarta.persistence.Entity
@Table(name = "COMPANY_BANK_ACCOUNT", schema = "supplier_ms")
public class CompanyBankAccount implements IdentityEntity, Entity, CompanyBasedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID")
@ToString.Exclude
private Company company;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "BANK_ID")
@ToString.Exclude
private Bank bank;
/**
* 开户行
*/
@Column(name = "OPENING_BANK")
private String openingBank;
/**
* 账号
*/
@Column(name = "ACCOUNT")
private String account;
@Column(name = "DESCRIPTION")
private String description;
@Override
public String toPrettyString() {
return account;
}
}

View File

@@ -0,0 +1,8 @@
package com.ecep.contract.manager.ds.company.model;
public interface CompanyBasedEntity {
Company getCompany();
void setCompany(Company company);
}

View File

@@ -0,0 +1,61 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.company.BlackReasonType;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import java.time.LocalDate;
@Getter
@Setter
@Entity
@Table(name = "COMPANY_BLACK_REASON", schema = "supplier_ms", indexes = {
@Index(name = "COMPANY_ID", columnList = "COMPANY_ID")
})
// @org.springframework.data.relational.core.mapping.Table("COMPANY_BLACK_REASON")
@JsonIgnoreProperties(ignoreUnknown = true)
public class CompanyBlackReason implements IdentityEntity, CompanyBasedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "COMPANY_ID")
private Company company;
@Column(name = "TYPE")
private BlackReasonType type;
@Column(name = "APPLY_NAME")
private String applyName;
@Column(name = "APPLY_DATE")
private LocalDate applyDate;
@Column(name = "UPDATE_TIME")
private LocalDate updateTime;
@Column(name = "CREATE_TIME")
private LocalDate createTime;
@Column(name = "INCLUDE_DATE")
private LocalDate includeDate;
@Column(name = "BLACK_REASON")
private String blackReason;
@Lob
@Column(name = "DESCRIPTION", columnDefinition = "TEXT")
private String description;
@Column(name = "`KEY`")
private String key;
}

View File

@@ -0,0 +1,91 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import com.ecep.contract.manager.ds.other.model.NamedEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.proxy.HibernateProxy;
import java.time.LocalDate;
import java.util.Objects;
@Getter
@Setter
@Entity
@Table(name = "COMPANY_CONTACT", schema = "supplier_ms", indexes = {
@Index(name = "CUSTOMER_ID", columnList = "COMPANY_ID")
})
@ToString
public class CompanyContact implements IdentityEntity, NamedEntity, com.ecep.contract.manager.ds.other.model.Entity, CompanyBasedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@Column(name = "NAME")
private String name;
@Column(name = "PHONE")
private String phone;
@Column(name = "EMAIL")
private String email;
/**
* 地址
*/
@Column(name = "ADDRESS")
private String address;
/**
* 职位
*/
@Column(name = "POSITION")
private String position;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID")
@ToString.Exclude
private Company company;
@Column(name = "U8_CODE")
private String u8Code;
@Column(name = "MEMO")
private String memo;
@Column(name = "CREATED")
private LocalDate created;
@Version
@ColumnDefault("0")
@Column(name = "VERSION", nullable = false)
private int version;
@Override
public String toPrettyString() {
return getName();
}
@Override
public final boolean equals(Object object) {
if (this == object) return true;
if (object == null) return false;
Class<?> oEffectiveClass = object instanceof HibernateProxy ? ((HibernateProxy) object).getHibernateLazyInitializer().getPersistentClass() : object.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
if (thisEffectiveClass != oEffectiveClass) return false;
CompanyContact that = (CompanyContact) object;
return getId() != null && Objects.equals(getId(), that.getId());
}
@Override
public final int hashCode() {
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
}
}

View File

@@ -0,0 +1,48 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.cloud.old.CompanyContactUtils;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.Map;
@Getter
@Setter
@Entity
@Table(name = "COMPANY_CONTRACT", schema = "supplier_ms", indexes = {
@Index(name = "RK_CONTRACT_ID", columnList = "CONTRACT_ID"),
@Index(name = "RK_COMPANY_ID", columnList = "COMPANY_ID")
}, uniqueConstraints = {
})
@ToString(exclude = {"company", "contract"})
public class CompanyContract implements IdentityEntity, CompanyBasedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID")
private Company company;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CONTRACT_ID")
private Contract contract;
/**
* 要和{@link CompanyContactUtils#getContactKey(Map)}一致
*/
public static String getContactKey(CompanyContact contact) {
if (contact == null) {
return null;
}
return contact.getName() +
contact.getPhone() +
contact.getEmail();
}
}

View File

@@ -0,0 +1,56 @@
package com.ecep.contract.manager.ds.company.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.proxy.HibernateProxy;
import java.util.Objects;
@Getter
@Setter
@Entity
@Table(name = "COMPANY_EXTEND_INFO", schema = "supplier_ms")
@ToString
public class CompanyExtendInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID")
@ToString.Exclude
private Company company;
/**
* 是否禁用核验
*/
@Column(name = "DISABLE_VERIFY")
private boolean disableVerify;
@Version
@ColumnDefault("0")
@Column(name = "VERSION", nullable = false)
@ToString.Exclude
private int version;
@Override
public final boolean equals(Object object) {
if (this == object) return true;
if (object == null) return false;
Class<?> oEffectiveClass = object instanceof HibernateProxy ? ((HibernateProxy) object).getHibernateLazyInitializer().getPersistentClass() : object.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
if (thisEffectiveClass != oEffectiveClass) return false;
CompanyExtendInfo that = (CompanyExtendInfo) object;
return getId() != null && Objects.equals(getId(), that.getId());
}
@Override
public final int hashCode() {
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
}
}

View File

@@ -0,0 +1,52 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDate;
/**
* 公司文件
*/
@Getter
@Setter
@Entity
@Table(name = "COMPANY_FILE")
@ToString
public class CompanyFile implements IdentityEntity, CompanyBasedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID")
@ToString.Exclude
private Company company;
@Column(name = "TYPE")
@Enumerated(EnumType.STRING)
private CompanyFileType type;
/**
* 生效日期(签署)
*/
@Column(name = "APPLY_DATE")
private LocalDate applyDate;
/**
* 有效期(签署)
*/
@Column(name = "EXP_DATE")
private LocalDate expiringDate;
/**
* 资质文件路径,全路径,网盘地址
*/
@Column(name = "FILE_PATH")
private String filePath;
}

View File

@@ -0,0 +1,17 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.other.model.BaseEnumEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@Entity
@Table(name = "COMPANY_FILE_TYPE_LOCAL")
@ToString
public class CompanyFileTypeLocal extends BaseEnumEntity<CompanyFileType> {
}

View File

@@ -0,0 +1,71 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import com.ecep.contract.manager.ds.other.model.NamedEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.proxy.HibernateProxy;
import java.util.Objects;
/**
* 公司发票信息
*/
@Getter
@Setter
@Entity
@Table(name = "COMPANY_INVOICE_INFO", schema = "supplier_ms")
@ToString
public class CompanyInvoiceInfo implements IdentityEntity, NamedEntity, com.ecep.contract.manager.ds.other.model.Entity, CompanyBasedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@Column(name = "NAME")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID")
@ToString.Exclude
private Company company;
@Column(name = "TAX")
private String taxId; // 税号(纳税人识别号)
@Column(name = "ADDR")
private String address; // 地址
@Column(name = "TEL")
private String phone; // 电话
@Column(name = "BANK")
private String bankName; // 开户行
@Column(name = "BANK_ACCOUNT")
private String bankAccount; // 银行账号
@Override
public String toPrettyString() {
return getName() + getTaxId();
}
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass() : o.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
if (thisEffectiveClass != oEffectiveClass) return false;
CompanyInvoiceInfo that = (CompanyInvoiceInfo) o;
return getId() != null && Objects.equals(getId(), that.getId());
}
@Override
public final int hashCode() {
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
}
}

View File

@@ -0,0 +1,72 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import com.ecep.contract.manager.ds.other.model.NamedEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.proxy.HibernateProxy;
import java.time.LocalDate;
import java.util.Objects;
@Getter
@Setter
@Entity
@Table(name = "COMPANY_OLDNAME")
@ToString
public class CompanyOldName implements IdentityEntity, NamedEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
@Column(name = "COMPANY_ID", nullable = false)
private Integer companyId;
@Column(name = "NAME")
private String name;
@Column(name = "BEGIN_DATE")
private LocalDate beginDate;
@Column(name = "END_DATE")
private LocalDate endDate;
/**
* 是否模糊的,当已录入的系统的名称有错误时,使用别名处理
*/
@Column(name = "AMBIGUITY")
private Boolean ambiguity;
@Column(name = "PATH")
private String path;
@Column(name = "MEMO")
@ToString.Exclude
private String memo;
@Version
@ColumnDefault("0")
@Column(name = "VERSION", nullable = false)
@ToString.Exclude
private int version;
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass() : o.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
if (thisEffectiveClass != oEffectiveClass) return false;
CompanyOldName that = (CompanyOldName) o;
return getId() != null && Objects.equals(getId(), that.getId());
}
@Override
public final int hashCode() {
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
}
}

View File

@@ -0,0 +1,78 @@
package com.ecep.contract.manager.ds.company.model;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.proxy.HibernateProxy;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.util.Objects;
/**
* 发票
*/
@Getter
@Setter
@Entity
@Table(name = "INVOICE", schema = "supplier_ms")
@ToString
public class Invoice implements IdentityEntity, com.ecep.contract.manager.ds.other.model.Entity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Integer id;
/**
* 发票号
*/
@Column(name = "CODE")
private String code;
/**
* 发票所属公司
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID")
@ToString.Exclude
private Company company;
/**
* 发票开票日期
*/
@Column(name = "INVOICE_DATE")
private LocalDate invoiceDate;
/**
* 备注
*/
@Column(name = "DESCRIPTION", columnDefinition = "TEXT")
private String description;
@Override
public String toPrettyString() {
if (StringUtils.hasText(getCode())) {
return getCode();
}
return "#" + getId();
}
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass() : o.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
if (thisEffectiveClass != oEffectiveClass) return false;
Invoice invoice = (Invoice) o;
return getId() != null && Objects.equals(getId(), invoice.getId());
}
@Override
public final int hashCode() {
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
}
}

View File

@@ -0,0 +1,11 @@
CREATE TABLE supplier_ms.COMPANY_BANK_ACCOUNT
(
ID INT AUTO_INCREMENT NOT NULL,
BANK_ID INT NULL,
OPENING_BANK VARCHAR(255) NULL,
ACCOUNT VARCHAR(255) NULL,
CONSTRAINT pk_company_bank_account PRIMARY KEY (ID)
);
ALTER TABLE supplier_ms.COMPANY_BANK_ACCOUNT
ADD CONSTRAINT FK_COMPANY_BANK_ACCOUNT_ON_BANK FOREIGN KEY (BANK_ID) REFERENCES supplier_ms.BANK (ID);

View File

@@ -0,0 +1,14 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBankAccount;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.Optional;
public interface CompanyBankAccountRepository
extends JpaRepository<CompanyBankAccount, Integer>, JpaSpecificationExecutor<CompanyBankAccount> {
Optional<CompanyBankAccount> findByCompanyAndAccount(Company company, String account);
}

View File

@@ -0,0 +1,19 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBlackReason;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CompanyBlackReasonRepository
// curd
extends CrudRepository<CompanyBlackReason, Integer>, PagingAndSortingRepository<CompanyBlackReason, Integer>, JpaSpecificationExecutor<CompanyBlackReason> {
List<CompanyBlackReason> findAllByCompany(Company company);
}

View File

@@ -0,0 +1,28 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyContact;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface CompanyContactRepository extends
CrudRepository<CompanyContact, Integer>,
PagingAndSortingRepository<CompanyContact, Integer>,
JpaRepository<CompanyContact, Integer>,
JpaSpecificationExecutor<CompanyContact> {
Optional<CompanyContact> findFirstByCompany(Company company);
List<CompanyContact> findAllByCompany(Company company);
List<CompanyContact> findAllByCompanyAndName(Company company, String name);
int deleteAllByCompany(Company company);
}

View File

@@ -0,0 +1,44 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyContract;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
@Repository
public interface CompanyContractRepository extends
// JDBC interfaces
CrudRepository<CompanyContract, Integer>, PagingAndSortingRepository<CompanyContract, Integer>,
// JPA interfaces
JpaRepository<CompanyContract, Integer>, JpaSpecificationExecutor<CompanyContract> {
List<CompanyContract> findByCompanyId(int companyId);
List<CompanyContract> findByCompany(Company company);
Stream<CompanyContract> findStreamByCompany(Company company);
Optional<CompanyContract> findByContractId(int contractId);
Optional<CompanyContract> findByContract(Contract contract);
Optional<CompanyContract> findByCompanyAndContract(Company company, Contract contract);
List<CompanyContract> findAllByCompany(Company company);
/**
* Delete all company contracts by company
*
* @param company Company
* @return 删除的记录行数
*/
int deleteAllByCompany(Company company);
}

View File

@@ -0,0 +1,19 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyExtendInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
public interface CompanyExtendInfoRepository extends
// JDBC interfaces
CrudRepository<CompanyExtendInfo, Integer>, PagingAndSortingRepository<CompanyExtendInfo, Integer>,
// JPA
JpaRepository<CompanyExtendInfo, Integer>, JpaSpecificationExecutor<CompanyExtendInfo> {
List<CompanyExtendInfo> findByCompany(Company company);
}

View File

@@ -0,0 +1,17 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.MyRepository;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyFile;
import java.util.List;
public interface CompanyFileRepository extends
// JDBC interfaces
MyRepository<CompanyFile, Integer> {
List<CompanyFile> findByCompany(Company company);
List<CompanyFile> findByCompanyAndType(Company company, CompanyFileType type);
}

View File

@@ -0,0 +1,36 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.company.model.CompanyFileTypeLocal;
import com.ecep.contract.manager.ds.contract.ContractFileType;
import com.ecep.contract.manager.ds.contract.model.ContractFileTypeLocal;
import com.ecep.contract.manager.ds.other.repository.BaseEnumEntityRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CompanyFileTypeLocalRepository extends BaseEnumEntityRepository<CompanyFileType, CompanyFileTypeLocal, Integer> {
@Override
default CompanyFileType[] getEnumConstants() {
return CompanyFileType.values();
}
@Override
default CompanyFileTypeLocal newEntity() {
return new CompanyFileTypeLocal();
}
CompanyFileTypeLocal findByTypeAndLang(CompanyFileType type, String lang);
default CompanyFileTypeLocal getCompleteByTypeAndLang(CompanyFileType type, String lang) {
CompanyFileTypeLocal v = findByTypeAndLang(type, lang);
if (v == null) {
v = newEntity();
v.setType(type);
v.setLang(lang);
v.setValue(type.name());
v = save(v);
}
return v;
}
}

View File

@@ -0,0 +1,21 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.CompanyInvoiceInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
/**
* 公司发票信息 Repository
*/
@Repository
public interface CompanyInvoiceInfoRepository extends
// JDBC interfaces
CrudRepository<CompanyInvoiceInfo, Integer>, PagingAndSortingRepository<CompanyInvoiceInfo, Integer>,
// JPA interfaces
JpaRepository<CompanyInvoiceInfo, Integer>, JpaSpecificationExecutor<CompanyInvoiceInfo> {
}

View File

@@ -0,0 +1,37 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public interface CompanyOldNameRepository extends
// JDBC interfaces
CrudRepository<CompanyOldName, Integer>, PagingAndSortingRepository<CompanyOldName, Integer>,
// JPA interfaces
JpaRepository<CompanyOldName, Integer>, JpaSpecificationExecutor<CompanyOldName> {
List<CompanyOldName> findAllByCompanyId(Integer companyId);
List<CompanyOldName> findAllByCompanyIdAndName(Integer companyId, String name);
List<CompanyOldName> findAllByName(String name);
List<CompanyOldName> findByNameLike(String searchText);
List<CompanyOldName> findByMemoLike(String searchText);
@Modifying
@Transactional
int deleteAllByCompanyId(Integer companyId);
}

View File

@@ -0,0 +1,35 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.Company;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
@Repository
public interface CompanyRepository extends
// JDBC interfaces
CrudRepository<Company, Integer>, PagingAndSortingRepository<Company, Integer>,
// JPA interfaces
JpaRepository<Company, Integer>, JpaSpecificationExecutor<Company> {
List<Company> findAllByName(String name);
Optional<Company> findFirstByName(String name);
List<Company> findAllByShortName(String shortName);
/**
* @param uniscid 统一社会信用代码
*/
List<Company> findAllByUniscid(String uniscid);
@Query("select u from Company u")
Stream<Company> findAllAsStream();
}

View File

@@ -0,0 +1,21 @@
package com.ecep.contract.manager.ds.company.repository;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.Invoice;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
public interface InvoiceRepository extends
// JDBC interfaces
CrudRepository<Invoice, Integer>, PagingAndSortingRepository<Invoice, Integer>,
// JPA
JpaRepository<Invoice, Integer>, JpaSpecificationExecutor<Invoice> {
List<Invoice> findByCompany(Company company);
Invoice findByCode(String invoiceNumber);
}

View File

@@ -0,0 +1,121 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBankAccount;
import com.ecep.contract.manager.ds.company.repository.CompanyBankAccountRepository;
import com.ecep.contract.manager.ds.company.vo.CompanyBankAccountViewModel;
import com.ecep.contract.manager.ui.MessageHolder;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.SpecificationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Objects;
@Lazy
@Service
@CacheConfig(cacheNames = "company-bank-account")
public class CompanyBankAccountService implements ViewModelService<CompanyBankAccount, CompanyBankAccountViewModel> {
private static final Logger logger = LoggerFactory.getLogger(CompanyBankAccountService.class);
@Lazy
@Autowired
private CompanyBankAccountRepository repository;
public CompanyBankAccount findByAccount(Company company, String account) {
return repository.findByCompanyAndAccount(company, account).orElse(null);
}
public void updateBankAccount(Company company, String bank, String bankAccount, MessageHolder holder) {
boolean modified = false;
if (!StringUtils.hasText(bankAccount)) {
// 空账户不用存储
return;
}
CompanyBankAccount account = findByAccount(company, bankAccount);
if (account == null) {
account = new CompanyBankAccount();
account.setCompany(company);
account.setAccount(bankAccount);
holder.info("新增银行账户" + bankAccount);
modified = true;
}
if (StringUtils.hasText(bank)) {
// 更新开户行
if (!Objects.equals(account.getOpeningBank(), bank)) {
account.setOpeningBank(bank);
holder.info("更新开户行" + bank);
modified = true;
}
}
if (modified) {
save(account);
}
}
public CompanyBankAccount save(CompanyBankAccount account) {
return repository.save(account);
}
public List<CompanyBankAccount> findAll(Specification<CompanyBankAccount> spec, Sort sort) {
return repository.findAll(spec, sort);
}
@Override
public CompanyBankAccount findById(Integer id) {
return repository.findById(id).orElse(null);
}
@Override
public Specification<CompanyBankAccount> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.and(
builder.isNotNull(root.get("bank")),
builder.or(
builder.like(root.get("bank").get("name"), "%" + searchText + "%"),
builder.like(root.get("bank").get("code"), "%" + searchText + "%")
)
),
builder.like(root.get("openingBank"), "%" + searchText + "%"),
builder.like(root.get("account"), "%" + searchText + "%")
);
};
}
@Override
public Page<CompanyBankAccount> findAll(Specification<CompanyBankAccount> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
public void delete(CompanyBankAccount entity) {
repository.delete(entity);
}
public List<CompanyBankAccount> searchByCompany(Company company, String searchText) {
Specification<CompanyBankAccount> spec = getSpecification(searchText);
if (company != null) {
spec = SpecificationUtils.and(spec, (root, query, builder) -> {
return builder.equal(root.get("company"), company);
});
}
return repository.findAll(spec, Pageable.ofSize(10)).getContent();
}
}

View File

@@ -0,0 +1,482 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.customer.CompanyCustomerFileType;
import com.ecep.contract.manager.ds.customer.model.CompanyCustomerFile;
import com.ecep.contract.manager.ds.other.model.CompanyBasicFile;
import com.ecep.contract.manager.ds.other.model.HolidayTable;
import com.ecep.contract.manager.ds.vendor.CompanyVendorFileType;
import com.ecep.contract.manager.ds.other.repository.HolidayTableRepository;
import com.ecep.contract.manager.ds.vendor.model.CompanyVendorFile;
import com.ecep.contract.manager.ds.company.CompanyFileUtils;
import org.hibernate.Hibernate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
public abstract class CompanyBasicService {
private static final Logger logger = LoggerFactory.getLogger(CompanyBasicService.class);
public static String formatCompanyVendorId(int itemId) {
if (itemId > 99) {
return String.valueOf(itemId);
} else if (itemId > 9) {
return "0" + itemId;
} else if (itemId > 0) {
return "00" + itemId;
} else {
throw new IllegalArgumentException();
}
}
/**
* 调整日期到工作日
*
* @param date 要调整的日期
* @return 调整的日期
*/
public static LocalDate adjustToWorkDay(LocalDate date) {
if (date.getDayOfWeek() == DayOfWeek.SATURDAY) {
// 再减去1天到周五
date = date.plusDays(-1);
} else if (date.getDayOfWeek() == DayOfWeek.SUNDAY) {
// 再减去2天到周五
date = date.plusDays(-2);
}
HolidayTableRepository holidayTableRepository = SpringApp.getBean(HolidayTableRepository.class);
//TODO 跳过节假日
int tryDays = 15;
while (tryDays-- > 0) {
HolidayTable holidayTable = holidayTableRepository.findById(date).orElse(null);
if (holidayTable == null) {
// 没有节假日定义,检查是否是工作日
DayOfWeek dayOfWeek = date.getDayOfWeek();
if (dayOfWeek == DayOfWeek.SATURDAY) {
date = date.plusDays(-1);
continue;
}
if (dayOfWeek == DayOfWeek.SUNDAY) {
date = date.plusDays(-2);
continue;
}
break;
}
if (!holidayTable.isHoliday()) {
// 不是节假日
break;
}
date = date.plusDays(-1);
}
return date;
}
@Lazy
@Autowired
protected CompanyService companyService;
protected boolean isEditableFile(String fileName) {
return CompanyFileUtils.withExtensions(fileName,
CompanyFileUtils.XLS, CompanyFileUtils.XLSX,
CompanyFileUtils.DOC, CompanyFileUtils.DOCX);
}
protected boolean isArchiveFile(String fileName) {
return CompanyFileUtils.withExtensions(fileName,
CompanyFileUtils.PNG, CompanyFileUtils.PDF,
CompanyFileUtils.JPG, CompanyFileUtils.JPEG);
}
public abstract <T, F extends CompanyBasicFile<T>, ID> void deleteFile(F file);
protected <T, F extends CompanyBasicFile<T>, ID> boolean fetchDbFiles(List<F> dbFiles, Map<String, F> map, Consumer<String> status) {
boolean modified = false;
List<File> editFiles = new ArrayList<>();
// 排除掉数据库中重复的
for (F dbFile : dbFiles) {
String filePath = dbFile.getFilePath();
// 没有文件信息,无效记录,删除
if (!StringUtils.hasText(filePath)) {
deleteFile(dbFile);
continue;
}
// 文件不存在或者隐藏文件,删除记录
File file = new File(filePath);
if (!file.exists() || CompanyFileUtils.isHiddenFile(file)) {
deleteFile(dbFile);
continue;
}
// old 是冲突的按dbFiles顺序旧的list前面的
F old = map.put(filePath, dbFile);
// 目录有重复删除
if (old != null) {
deleteFile(old);
}
String editFilePath = dbFile.getEditFilePath();
if (!Objects.equals(filePath, editFilePath)) {
// 没有文件信息,无效记录,删除
if (StringUtils.hasText(editFilePath)) {
File editFile = new File(editFilePath);
if (editFile.exists()) {
editFiles.add(editFile);
} else {
dbFile.setEditFilePath("");
}
}
}
// 类型未设置,补充类型
if (dbFile.getType() == null) {
if (fillFileAsDefaultType(dbFile, file, status)) {
modified = true;
}
}
}
for (File editFile : editFiles) {
String editFilePath = editFile.getAbsolutePath();
F dup = map.remove(editFilePath);
// 目录有重复删除
if (dup != null) {
deleteFile(dup);
}
}
return modified;
}
/**
* dbFile 的 Type 未设置时,设置为默认类型
*
* @param dbFile 要设置的 对象
* @param file 相关文件对象
* @param status 状态输出
* @param <T> 类型类
* @param <F> 文件类
* @return 是否修改了
* @see CompanyVendorFile
* @see CompanyVendorFileType
* @see CompanyCustomerFile
* @see CompanyCustomerFileType
*/
protected abstract <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file, Consumer<String> status);
protected void moveFileToCompany(Company company, List<File> needMoveToCompanyPath) {
if (needMoveToCompanyPath.isEmpty()) {
return;
}
if (!Hibernate.isInitialized(company)) {
company = companyService.findById(company.getId());
}
String companyPath = company.getPath();
if (!StringUtils.hasText(companyPath)) {
return;
}
for (File file : needMoveToCompanyPath) {
File dest = new File(companyPath, file.getName());
if (file.renameTo(dest)) {
//
if (logger.isInfoEnabled()) {
logger.info("{} -> {}", file.getAbsolutePath(), dest.getAbsolutePath());
}
} else {
//
if (dest.exists()) {
if (file.delete()) {
if (logger.isInfoEnabled()) {
logger.info("Delete File {}", file.getAbsolutePath());
}
}
}
}
}
// 公司目录下文件更新后,待公司文件自行处理
}
/**
* 遍历扫描 path 目录下的文件,
*
* @param path
* @param needMoveToCompanyPath
* @param retrieveFiles
* @param map
* @param status
* @param <T>
* @param <F>
*/
protected <T, F extends CompanyBasicFile<T>> void fetchFiles(
String path,
List<File> needMoveToCompanyPath,
List<F> retrieveFiles,
Map<String, F> map,
Consumer<String> status
) {
if (!StringUtils.hasText(path)) {
return;
}
File dir = new File(path);
if (!dir.exists()) {
return;
}
File[] files = dir.listFiles();
if (files == null) {
return;
}
List<File> step1 = new ArrayList<>();
for (File file : files) {
// 只处理文件
if (!file.isFile() || CompanyFileUtils.isHiddenFile(file)) {
continue;
}
if (CompanyFileUtils.isCompanyFile(file)) {
needMoveToCompanyPath.add(file);
continue;
}
// 先把所有文件加到列表中
step1.add(file);
}
if (!step1.isEmpty()) {
// 第一步,处理已经存在的
for (File file : new ArrayList<>(step1)) {
String filePath = file.getAbsolutePath();
if (map.containsKey(filePath)) {
// 已记录
F customerFile = map.get(filePath);
if (fillFile(customerFile, file, step1, status)) {
retrieveFiles.add(customerFile);
}
step1.remove(file);
}
}
// 第二步骤,再处理
while (!step1.isEmpty()) {
File file = step1.removeLast();
F filled = fillFileType(file, step1, status);
if (filled != null) {
retrieveFiles.add(filled);
}
}
}
}
/**
* 填充文件类型
*
* @param file
* @param fileList
* @param status 状态输出
* @param <T> 类型类
* @param <F> 文件类
*/
protected abstract <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList, Consumer<String> status);
/**
* @param customerFile 文件对象
* @param file 相关文件
* @param fileList 待处理文件列表
* @param status 状态输出
* @param <T> 类型类
* @param <F> 文件类
* @return true 有修改
*/
protected <T, F extends CompanyBasicFile<T>> boolean fillFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
String fileName = file.getName();
boolean modified = CompanyFileUtils.fillApplyDateAbsent(file, customerFile, F::getSignDate, F::setSignDate);
// 评估表
if (isEvaluationFile(fileName)) {
if (fillFileAsEvaluationFile(customerFile, file, fileList, status)) {
modified = true;
}
} else {
if (!Objects.equals(file.getAbsolutePath(), customerFile.getFilePath())) {
customerFile.setFilePath(file.getAbsolutePath());
modified = true;
}
}
return modified;
}
/**
* 以评价表单模板。填充文件信息
*
* @param customerFile 文件对象
* @param file 相关文件
* @param fileList 待处理文件列表
* @param status 状态输出
* @param <T> 类型类
* @param <F> 文件类
* @return true文件对象有修改否则返回false
*/
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsEvaluationFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
boolean modified = setFileTypeAsEvaluationForm(customerFile);
String fileName = file.getName();
// 文件全路径
String fileAbsolutePath = file.getAbsolutePath();
if (isEditableFile(fileName)) {
// 是可编辑文件时
if (!Objects.equals(fileAbsolutePath, customerFile.getEditFilePath())) {
customerFile.setEditFilePath(fileAbsolutePath);
modified = true;
}
if (useAsEditableFile(customerFile, file, fileList, status)) {
modified = true;
}
} else if (isArchiveFile(fileName)) {
// 存档文件时
if (!Objects.equals(fileAbsolutePath, customerFile.getFilePath())) {
customerFile.setFilePath(fileAbsolutePath);
modified = true;
}
if (useAsArchiveFile(customerFile, file, fileList, status)) {
modified = true;
}
} else {
customerFile.setFilePath(file.getAbsolutePath());
}
return modified;
}
private <T, F extends CompanyBasicFile<T>> boolean useAsEditableFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
if (fileList == null) {
return false;
}
// 检查存档文件
if (StringUtils.hasText(customerFile.getFilePath())) {
// 移除 存档文件
File archiveFile = new File(customerFile.getFilePath());
fileList.remove(archiveFile);
return false;
}
// 未关联存档文件,去找 fileList 查
if (fileList.isEmpty()) {
// 文件全路径
String fileAbsolutePath = file.getAbsolutePath();
// 当没有其他文件时,与 EditFile 相同
if (!Objects.equals(fileAbsolutePath, customerFile.getFilePath())) {
customerFile.setFilePath(fileAbsolutePath);
return true;
}
return false;
}
File archiveFile = null;
// 文件名
String fileName = file.getName();
// 文件名,不含后缀
String name = StringUtils.stripFilenameExtension(fileName);
for (File f : fileList) {
// 查找存档文件
if (f.getName().startsWith(name) && isArchiveFile(f.getName())) {
archiveFile = f;
break;
}
}
// 没有匹配到文件
if (archiveFile == null) {
return false;
}
if (fileList.remove(archiveFile)) {
customerFile.setFilePath(archiveFile.getAbsolutePath());
return true;
}
return false;
}
private <T, F extends CompanyBasicFile<T>> boolean useAsArchiveFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
if (fileList == null) {
return false;
}
// 未关联存档文件,去找 fileList 查
if (fileList.isEmpty()) {
return false;
}
// 检查可编辑文件
if (StringUtils.hasText(customerFile.getEditFilePath())) {
// 移除 可编辑文件
File editFile = new File(customerFile.getEditFilePath());
fileList.remove(editFile);
return false;
}
File editFile = null;
// 文件名
String fileName = file.getName();
// 文件名,不含后缀
String name = StringUtils.stripFilenameExtension(fileName);
for (File f : fileList) {
// 查找存档文件
if (f.getName().startsWith(name) && isEditableFile(f.getName())) {
editFile = f;
break;
}
}
// 没有匹配到文件
if (editFile == null) {
return false;
}
if (fileList.remove(editFile)) {
String editFilePath = editFile.getAbsolutePath();
if (!Objects.equals(editFilePath, customerFile.getEditFilePath())) {
customerFile.setEditFilePath(editFilePath);
return true;
}
}
return false;
}
/**
* 设置文件类型为表单文件
*
* @param file 文件对象
* @param <T> 类型类
* @param <F> 文件类
* @return true 文件对象有修改否则false
*/
protected abstract <T, F extends CompanyBasicFile<T>> boolean setFileTypeAsEvaluationForm(F file);
/**
* 判定 参数 fileName 是否是一个评价表文件
*
* @param fileName 文件名称
* @return true 是评价表否则false
*/
protected abstract boolean isEvaluationFile(String fileName);
}

View File

@@ -0,0 +1,68 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBlackReason;
import com.ecep.contract.manager.ds.company.repository.CompanyBlackReasonRepository;
import com.ecep.contract.manager.ds.company.vo.CompanyBlackReasonViewModel;
import com.ecep.contract.manager.ui.ViewModelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
@Lazy
@Service
public class CompanyBlackReasonService implements ViewModelService<CompanyBlackReason, CompanyBlackReasonViewModel> {
private static final Logger logger = LoggerFactory.getLogger(CompanyContactService.class);
@Autowired
private CompanyBlackReasonRepository repository;
public CompanyBlackReason findById(Integer id) {
return repository.findById(id).orElse(null);
}
@Override
public Specification<CompanyBlackReason> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("applyName"), "%" + searchText + "%"),
builder.like(root.get("blackReason"), "%" + searchText + "%"),
builder.like(root.get("description"), "%" + searchText + "%")
);
};
}
@Override
public Page<CompanyBlackReason> findAll(Specification<CompanyBlackReason> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
public void delete(CompanyBlackReason entity) {
repository.delete(entity);
}
public List<CompanyBlackReason> findAll(Specification<CompanyBlackReason> spec, Sort by) {
return repository.findAll(spec, by);
}
public List<CompanyBlackReason> findAllByCompany(Company company) {
return repository.findAllByCompany(company);
}
public CompanyBlackReason save(CompanyBlackReason companyBlackReason) {
return repository.save(companyBlackReason);
}
}

View File

@@ -0,0 +1,109 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyContact;
import com.ecep.contract.manager.ds.company.repository.CompanyContactRepository;
import com.ecep.contract.manager.ds.company.vo.CompanyContactViewModel;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.MyStringUtils;
import com.ecep.contract.manager.util.SpecificationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* 公司联系人服务
*/
@Lazy
@Service
@CacheConfig(cacheNames = "company-contact")
public class CompanyContactService implements ViewModelService<CompanyContact, CompanyContactViewModel> {
private static final Logger logger = LoggerFactory.getLogger(CompanyContactService.class);
@Autowired
private CompanyContactRepository companyContactRepository;
public CompanyContact save(CompanyContact contact) {
return companyContactRepository.save(contact);
}
public void resetTo(Company from, Company to) {
// 曾用名 关联到 updater
List<CompanyContact> list = companyContactRepository.findAllByCompany(from);
if (list.isEmpty()) {
return;
}
for (CompanyContact oldName : list) {
oldName.setMemo(MyStringUtils.appendIfAbsent(oldName.getMemo(), "转自 " + from.getId()));
oldName.setCompany(to);
}
companyContactRepository.saveAll(list);
}
public void deleteByCompany(Company company) {
int deleted = companyContactRepository.deleteAllByCompany(company);
if (deleted > 0) {
if (logger.isInfoEnabled()) {
logger.info("Delete {} records by company:#{}", deleted, company.getId());
}
}
}
public void delete(CompanyContact entity) {
companyContactRepository.delete(entity);
}
public CompanyContact findFirstByCompany(Company company) {
return companyContactRepository.findFirstByCompany(company).orElse(null);
}
public CompanyContact findById(Integer id) {
return companyContactRepository.findById(id).orElse(null);
}
@Override
public Specification<CompanyContact> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("phone"), "%" + searchText + "%"),
builder.like(root.get("email"), "%" + searchText + "%"),
builder.like(root.get("position"), "%" + searchText + "%"),
builder.like(root.get("memo"), "%" + searchText + "%")
);
};
}
@Override
public Page<CompanyContact> findAll(Specification<CompanyContact> spec, Pageable pageable) {
return companyContactRepository.findAll(spec, pageable);
}
public List<CompanyContact> searchByCompany(Company company, String userText) {
Specification<CompanyContact> spec = SpecificationUtils.and((root, query, builder) -> {
return builder.equal(root.get("company"), company);
}, getSpecification(userText));
return companyContactRepository.findAll(spec);
}
public List<CompanyContact> findAll(Specification<CompanyContact> spec, Sort sort) {
return companyContactRepository.findAll(spec, sort);
}
public List<CompanyContact> findAllByCompanyAndName(Company company, String contactName) {
return companyContactRepository.findAllByCompanyAndName(company, contactName);
}
}

View File

@@ -0,0 +1,74 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyExtendInfo;
import com.ecep.contract.manager.ds.company.repository.CompanyExtendInfoRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.context.annotation.Lazy;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 公司文件服务
*/
@Lazy
@Service
@CacheConfig(cacheNames = "company-extend-info")
public class CompanyExtendInfoService {
private static final Logger logger = LoggerFactory.getLogger(CompanyExtendInfoService.class);
@Autowired
private CompanyExtendInfoRepository repository;
@Cacheable(key = "#p0")
public CompanyExtendInfo findById(int id) {
return repository.findById(id).orElse(null);
}
public List<CompanyExtendInfo> findAll(Specification<CompanyExtendInfo> spec, Sort sort) {
return repository.findAll(spec, sort);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'byCompany-'+#p0.company.id")
}
)
public void delete(CompanyExtendInfo extendInfo) {
repository.delete(extendInfo);
}
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'byCompany-'+#p0.company.id")
}
)
public CompanyExtendInfo save(CompanyExtendInfo extendInfo) {
return repository.save(extendInfo);
}
@Cacheable(key = "'byCompany-'+#p0")
public CompanyExtendInfo findByCompany(Company company) {
List<CompanyExtendInfo> list = repository.findByCompany(company);
if (list.isEmpty()) {
CompanyExtendInfo extendInfo = new CompanyExtendInfo();
extendInfo.setCompany(company);
extendInfo.setDisableVerify(false);
return repository.save(extendInfo);
}
return list.getFirst();
}
}

View File

@@ -0,0 +1,631 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.cloud.rk.CloudRkService;
import com.ecep.contract.manager.cloud.tyc.CloudTycService;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.company.CompanyFileUtils;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyFile;
import com.ecep.contract.manager.ds.company.model.CompanyFileTypeLocal;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.repository.CompanyFileRepository;
import com.ecep.contract.manager.ds.company.repository.CompanyFileTypeLocalRepository;
import com.ecep.contract.manager.ds.company.repository.CompanyOldNameRepository;
import com.ecep.contract.manager.ds.company.vo.CompanyFileViewModel;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.ecep.contract.manager.ds.company.CompanyFileType.*;
/**
* 公司文件服务
*/
@Lazy
@Service
@CacheConfig(cacheNames = "company-file")
public class CompanyFileService implements ViewModelService<CompanyFile, CompanyFileViewModel> {
public final static String ENTERPRISE_REPORT = "企业信用报告";
public final static String BUSINESS_LICENSE = "营业执照";
public final static String ORGANIZATION_CODE_CERTIFICATE = "组织机构代码证";
public final static String OPERATION_CERTIFICATE = "操作证";
public final static String PERMIT_CERTIFICATE = "许可证";
public final static String REGISTRATION_CERTIFICATE = "登记证";
private static final Logger logger = LoggerFactory.getLogger(CompanyFileService.class);
@Lazy
@Autowired
private CompanyFileRepository companyFileRepository;
@Lazy
@Autowired
private CompanyOldNameRepository companyOldNameRepository;
@Lazy
@Autowired
private CompanyFileTypeLocalRepository fileTypeLocalRepository;
@Cacheable(key = "#p0")
public CompanyFile findById(Integer id) {
return companyFileRepository.findById(id).orElse(null);
}
@Override
public Page<CompanyFile> findAll(Specification<CompanyFile> spec, Pageable pageable) {
return companyFileRepository.findAll(spec, pageable);
}
public List<CompanyFile> findFileByCompanyAndType(Company company, CompanyFileType type) {
return companyFileRepository.findByCompanyAndType(company, type);
}
@Override
public Specification<CompanyFile> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(builder.like(root.get("filePath"), "%" + searchText + "%"));
};
}
@Cacheable(key = "'type-locals-'+#p0")
public Map<CompanyFileType, CompanyFileTypeLocal> findAllFileTypes(String lang) {
return fileTypeLocalRepository.getCompleteMapByLocal(lang);
}
// public List<CompanyFileTypeLocal> findAllFileTypes(String lang) {
// Map<CompanyFileType, CompanyFileTypeLocal> map = fileTypeLocalRepository.getCompleteMapByLocal(lang);
// List<CompanyFileTypeLocal> list = new ArrayList<>(map.values());
// list.sort((o1, o2) -> Objects.compare(o1.getValue(), o2.getValue(), String::compareTo));
// return list;
// }
/**
* 根据公司的合同的资信报告文件,推算下一个咨询报告日期
*
* @param company 公司
* @param state 状态输出
* @return 下一个咨询报告日期
*/
public LocalDate getNextCreditReportDate(Company company, Consumer<String> state) {
// 检索全部合同
ContractService contractService = SpringApp.getBean(ContractService.class);
List<Contract> contractList = contractService.findAllByCompany(company);
if (contractList.isEmpty()) {
state.accept("未发现已登记的合同");
return null;
}
LocalDate minDate = LocalDate.of(2023, 1, 1);
List<Contract> contracts = contractList.stream()
.filter(v -> !v.getSetupDate().isBefore(minDate))
.sorted(Comparator.comparing(Contract::getSetupDate))
.toList();
if (contracts.isEmpty()) {
state.accept("没有发现待处理的合同");
return null;
}
// 检索资信报告
List<CompanyFile> files = findFileByCompanyAndType(company, CompanyFileType.CreditReport);
if (files.isEmpty()) {
Contract first = contracts.getFirst();
// 没有资信报告,返回第一个合同的提交日期
state.accept("没有资信报告,推荐使用第一个合同 " + first.getCode() + " 的日期 " + first.getSetupDate());
return first.getSetupDate();
}
for (Contract contract : contracts) {
if (files.stream().noneMatch(v -> MyDateTimeUtils.dateValidFilter(contract.getSetupDate(), v.getApplyDate(), v.getExpiringDate(), 1))) {
state.accept("发现未匹配的合同 " + contract.getCode() + " " + contract.getSetupDate());
return contract.getSetupDate();
}
}
return null;
}
/**
* 验证企业文件
* <p>
* 检查是否有类型为{@link CompanyFileType#CreditReport 资讯评估}的文件且参数verifyDate在文件的{@link CompanyFile#getApplyDate()}和{@link CompanyFile#getExpiringDate()} ()}指定验证日期内有
* <p>
* 2023-01-01后要求有资信评估报告
*
* @param company 检查的公司对象
* @param verifyDate 检查日期
* @param status 状态输出
* @see CompanyFile
* @see CompanyFileType
*/
public void verify(Company company, LocalDate verifyDate, Consumer<String> status) {
if (verifyDate.isBefore(LocalDate.of(2023, 1, 1))) {
// 不检查2023-01-01之前的资信评估报告
return;
}
// 查询公司的资信评估报告
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()) {
status.accept("未匹配到资信评估报告");
} else if (dates.size() == 1) {
status.accept("未匹配到资信评估报告, 最接近日期:" + dates.getFirst());
} else {
LocalDate localDate = dates.stream().max(LocalDate::compareTo).orElse(null);
status.accept("未匹配到资信评估报告, 最接近日期:" + localDate);
}
}
}
/**
* 保存企业文件
*
* @param companyFile 企业文件
* @return 保存后的企业文件
*/
public CompanyFile save(CompanyFile companyFile) {
return companyFileRepository.save(companyFile);
}
public List<CompanyFile> findAll(Specification<CompanyFile> spec, Sort sort) {
return companyFileRepository.findAll(spec, sort);
}
public void deleteById(int id) {
companyFileRepository.deleteById(id);
}
public void delete(CompanyFile file) {
companyFileRepository.delete(file);
}
public List<CompanyFile> findByCompany(Company company) {
return companyFileRepository.findByCompany(company);
}
/**
* 重置 公司文件
*
* @param company 要重置的公司对象
* @param status 输出
*/
public boolean reBuildingFiles(Company company, Consumer<String> status) {
List<CompanyFile> dbFiles = companyFileRepository.findByCompany(company);
List<CompanyFile> retrieveFiles = new ArrayList<>();
boolean modfied = false;
Map<String, CompanyFile> map = new HashMap<>();
// 排除掉数据库中重复的
for (CompanyFile dbFile : dbFiles) {
String filePath = dbFile.getFilePath();
// 没有文件信息,无效记录,删除
if (!StringUtils.hasText(filePath)) {
companyFileRepository.delete(dbFile);
modfied = true;
continue;
}
// 目录不存在,删除
File dir = new File(filePath);
if (!dir.exists()) {
companyFileRepository.delete(dbFile);
modfied = true;
continue;
}
CompanyFile old = map.put(filePath, dbFile);
// 目录有重复删除
if (old != null) {
companyFileRepository.delete(old);
modfied = true;
}
}
Map<String, File> directoryMap = new HashMap<>();
// 公司目录
if (StringUtils.hasText(company.getPath())) {
File dir = new File(company.getPath());
directoryMap.put(company.getName(), dir);
}
// 获取所有曾用名
for (CompanyOldName companyOldName : companyOldNameRepository.findAllByCompanyId(company.getId())) {
String path = companyOldName.getPath();
if (StringUtils.hasText(path)) {
File dir = new File(path);
directoryMap.put(companyOldName.getName(), dir);
}
}
for (Map.Entry<String, File> entry : directoryMap.entrySet()) {
String companyName = entry.getKey();
File dir = entry.getValue();
if (!StringUtils.hasText(companyName)) {
continue;
}
if (dir == null || !dir.exists()) {
continue;
}
File[] files = dir.listFiles();
if (files == null) {
// 文件系统出错或者没有相关文件
continue;
}
for (File file : files) {
// 只处理文件
if (!file.isFile() || CompanyFileUtils.isHiddenFile(file)) {
continue;
}
String filePath = file.getAbsolutePath();
if (!map.containsKey(filePath)) {
// 未记录
CompanyFile filled = fillFileType(file, status);
retrieveFiles.add(filled);
}
}
}
status.accept("导入 " + retrieveFiles.size() + " 个文件");
if (retrieveFiles.isEmpty()) {
return modfied;
}
//update db
retrieveFiles.forEach(v -> v.setCompany(company));
companyFileRepository.saveAll(retrieveFiles);
return true;
}
/**
* 从文件名生成公司文件对象,文件已经存在公司对应的存储目录下
*
* @param file 文件
* @param status 状态输出
* @return 公司文件对象
*/
private CompanyFile fillFileType(File file, Consumer<String> status) {
String fileName = file.getName();
CompanyFile companyFile = new CompanyFile();
companyFile.setType(General);
companyFile.setFilePath(file.getAbsolutePath());
fillApplyDateAndExpiringDateAbsent(file, companyFile);
// 天眼查 基础版企业信用报告
if (fileName.contains(CloudTycService.TYC_ENTERPRISE_BASIC_REPORT)
|| fileName.contains(CloudTycService.TYC_ENTERPRISE_MAJOR_REPORT)
|| fileName.contains(CloudTycService.TYC_ENTERPRISE_ANALYSIS_REPORT)
) {
companyFile.setType(CreditReport);
fillExpiringDateAbsent(companyFile);
return companyFile;
}
// 天眼查 企业信用信息公示报告
if (fileName.contains(CloudTycService.TYC_ENTERPRISE_CREDIT_REPORT)) {
companyFile.setType(CreditInfoPublicityReport);
return companyFile;
}
// 集团相关方平台 元素征信 企业征信报告
if (fileName.contains(CloudRkService.VENDOR_NAME) && fileName.contains(CloudRkService.ENTERPRISE_CREDIT_REPORT)) {
companyFile.setType(CreditReport);
fillExpiringDateAbsent(companyFile);
return companyFile;
}
// 营业执照
if (fileName.contains(BUSINESS_LICENSE)) {
companyFile.setType(BusinessLicense);
return companyFile;
}
// 其他企业信用报告
if (fileName.contains(ENTERPRISE_REPORT)) {
companyFile.setType(CreditReport);
fillExpiringDateAbsent(companyFile);
return companyFile;
}
return companyFile;
}
/**
* 补齐有效期
*/
private void fillExpiringDateAbsent(CompanyFile file) {
LocalDate expiringDate = file.getExpiringDate();
if (expiringDate == null) {
LocalDate applyDate = file.getApplyDate();
if (applyDate != null) {
expiringDate = applyDate.plusYears(1);
file.setExpiringDate(expiringDate);
}
}
}
private static void fillApplyDateAndExpiringDateAbsent(File file, CompanyFile companyFile) {
LocalDate applyDate = companyFile.getApplyDate();
if (applyDate != null) {
return;
}
String fileName = file.getName();
Pattern pattern = Pattern.compile(MyDateTimeUtils.REGEX_DATE);
Matcher matcher = pattern.matcher(fileName);
while (matcher.find()) {
// 找到第一个日期,记作起始日期
String date = matcher.group();
try {
LocalDate n = LocalDate.parse(date);
companyFile.setApplyDate(n);
// 如果 截至日期未设置,则第二个日期记作截至日期(如有)
LocalDate expiringDate = companyFile.getExpiringDate();
if (expiringDate == null) {
while (matcher.find()) {
date = matcher.group();
try {
n = LocalDate.parse(date);
companyFile.setExpiringDate(n);
break;
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("parse date failure, it used to set ExpiringDate, {} from {} by Regex:{}, @{}",
date, fileName, MyDateTimeUtils.REGEX_DATE, companyFile);
}
}
}
}
break;
} catch (Exception e) {
if (logger.isDebugEnabled()) {
logger.debug("parse date failure, it used to set ApplyDate, {} from {} by Regex:{}, @{}",
date, fileName, MyDateTimeUtils.REGEX_DATE, companyFile);
}
}
}
}
/**
* 移动文件到企业目录下
*
* @param company 企业对象
* @param files 要被移动的文件集合,需要从中选择需要的
* @param status 状态输出
*/
public boolean retrieveFromDownloadFiles(Company company, File[] files, Consumer<String> status) {
Map<String, File> map = new HashMap<>();
File home = new File(company.getPath());
map.put(company.getName(), home);
List<CompanyFile> retrieveFiles = new ArrayList<>();
// 获取所有曾用名
for (CompanyOldName companyOldName : companyOldNameRepository.findAllByCompanyId(company.getId())) {
String name = companyOldName.getName();
if (!StringUtils.hasText(name)) {
continue;
}
File dir = null;
String path = companyOldName.getPath();
if (StringUtils.hasText(path)) {
dir = new File(path);
}
map.put(name, dir);
}
// 对所有文件进行遍历
for (int i = 0; i < files.length; i++) {
File file = files[i];
// 只处理文件
if (!file.isFile()) {
continue;
}
String prefix = (i + 1) + "/" + files.length + ":";
Consumer<String> inner = (str) -> {
status.accept(prefix + str);
};
String fileName = file.getName();
inner.accept(fileName);
for (Map.Entry<String, File> entry : map.entrySet()) {
String companyName = entry.getKey();
// 必须要包含公司名称否则无法区分
if (!fileName.contains(companyName)) {
continue;
}
// 文件存储的目的地目录
File dir = entry.getValue();
if (dir == null) {
dir = home;
}
CompanyFile filled = fillDownloadFileType(company, file, companyName, dir, inner);
if (filled != null) {
retrieveFiles.add(filled);
}
}
}
status.accept("导入 " + retrieveFiles.size() + " 个文件");
if (retrieveFiles.isEmpty()) {
return false;
}
//update db
retrieveFiles.forEach(v -> v.setCompany(company));
companyFileRepository.saveAll(retrieveFiles);
return true;
}
/**
* 从文件名生成公司文件对象
* 文件从下载目录中导入
*
* @param company 公司对象
* @param file 导入的文件对象
* @param companyName 公司名称
* @param destDir 目标目录
* @param status 状态输出
* @return 生成的公司文件对象如果无法转换则返回null
*/
private CompanyFile fillDownloadFileType(Company company, File file, String companyName, File destDir, Consumer<String> status) {
String fileName = file.getName();
// 天眼查的报告
// 目前只有 基础版企业信用报告, 企业信用信息公示报告下载保存时的文件名中没有天眼查
if (CloudTycService.isTycReport(fileName)) {
CompanyFile companyFile = new CompanyFile();
companyFile.setType(CreditReport);
fillApplyDateAbsent(file, companyFile);
String destFileName = fileName;
// 重命名 基础版企业信用报告
for (String report : Arrays.asList(
CloudTycService.TYC_ENTERPRISE_ANALYSIS_REPORT,
CloudTycService.TYC_ENTERPRISE_BASIC_REPORT,
CloudTycService.TYC_ENTERPRISE_MAJOR_REPORT)) {
if (fileName.contains(report)) {
LocalDate applyDate = companyFile.getApplyDate();
if (applyDate == null) {
applyDate = LocalDate.now();
companyFile.setApplyDate(applyDate);
}
String formatted = MyDateTimeUtils.format(applyDate);
String extension = StringUtils.getFilenameExtension(fileName);
destFileName = String.format("%s_%s_%s_%s.%s",
companyName, CloudTycService.NAME, report, formatted, extension);
}
}
// 重新设置 企业分析报告 未普通文件
// if (fileName.contains(CloudTycService.TYC_ENTERPRISE_ANALYSIS_REPORT)) {
// companyFile.setType(General);
// }
File dest = new File(destDir, destFileName);
// 移动文件
if (!file.renameTo(dest)) {
// 移动失败时
status.accept(fileName + " 无法移动到 " + dest.getAbsolutePath());
return null;
}
status.accept(fileName + " 移动到 " + dest.getAbsolutePath());
companyFile.setFilePath(dest.getAbsolutePath());
//
if (companyFile.getExpiringDate() == null) {
if (companyFile.getApplyDate() != null) {
companyFile.setExpiringDate(companyFile.getApplyDate().plusYears(1));
}
}
return companyFile;
}
// 企业信用信息公示报告
if (fileName.contains(CloudTycService.TYC_ENTERPRISE_CREDIT_REPORT)) {
CompanyFile companyFile = new CompanyFile();
companyFile.setType(CreditInfoPublicityReport);
fillApplyDateAbsent(file, companyFile);
File dest = new File(destDir, fileName);
// 移动文件
if (!file.renameTo(dest)) {
if (dest.exists()) {
// 尝试删除已经存在的文件
if (!dest.delete()) {
status.accept("覆盖时,无法删除已存在的文件 " + dest.getAbsolutePath());
return null;
}
if (file.renameTo(dest)) {
Optional<CompanyFile> one = companyFileRepository.findOne(((root, query, builder) -> {
return builder.and(
builder.equal(root.get("filePath"), dest.getAbsolutePath()),
builder.equal(root.get("company"), company)
);
}));
if (one.isPresent()) {
companyFile = one.get();
}
} else {
status.accept(fileName + " 无法覆盖到 " + dest.getAbsolutePath());
return null;
}
} else {
status.accept(fileName + " 无法移动到 " + dest.getAbsolutePath());
return null;
}
}
status.accept(fileName + " 移动到 " + dest.getAbsolutePath());
companyFile.setFilePath(dest.getAbsolutePath());
return companyFile;
}
return null;
}
/**
* 当 ApplyDate 未设置时,尝试使用文件名中包含的日期
*/
private static void fillApplyDateAbsent(File file, CompanyFile companyFile) {
LocalDate applyDate = companyFile.getApplyDate();
if (applyDate != null) {
return;
}
String fileName = file.getName();
// 从文件名中提取日期
LocalDate picked = MyDateTimeUtils.pickLocalDate(fileName);
if (picked != null) {
companyFile.setApplyDate(picked);
}
}
}

View File

@@ -0,0 +1,52 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyInvoiceInfo;
import com.ecep.contract.manager.ds.company.repository.CompanyInvoiceInfoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 公司发票信息服务
*/
@Lazy
@Service
@CacheConfig(cacheNames = "company-invoice-info")
public class CompanyInvoiceInfoService {
@Lazy
@Autowired
private CompanyInvoiceInfoRepository repository;
@Cacheable(key = "#p0")
public CompanyInvoiceInfo findById(int id) {
return repository.findById(id).orElse(null);
}
public List<CompanyInvoiceInfo> searchByCompany(Company company, String searchText) {
Specification<CompanyInvoiceInfo> spec = (root, query, builder) -> {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("taxId"), "%" + searchText + "%"),
builder.like(root.get("address"), "%" + searchText + "%"),
builder.like(root.get("phone"), "%" + searchText + "%"),
builder.like(root.get("bankName"), "%" + searchText + "%"),
builder.like(root.get("bankAccount"), "%" + searchText + "%")
);
};
if (company != null) {
spec = spec.and((root, query, builder) -> {
return builder.equal(root.get("company"), company);
});
}
return repository.findAll(spec, Pageable.ofSize(10)).getContent();
}
}

View File

@@ -0,0 +1,213 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.ds.company.CompanyFileUtils;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.repository.CompanyOldNameRepository;
import com.ecep.contract.manager.ds.company.vo.CompanyOldNameViewModel;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.MyStringUtils;
import com.ecep.contract.manager.util.SpecificationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.LocalDate;
import java.util.List;
@Lazy
@Service
public class CompanyOldNameService implements ViewModelService<CompanyOldName, CompanyOldNameViewModel> {
private static final Logger logger = LoggerFactory.getLogger(CompanyOldNameService.class);
@Lazy
@Autowired
private CompanyOldNameRepository companyOldNameRepository;
@Lazy
@Autowired
private CompanyService companyService;
public CompanyOldName findById(Integer id) {
return companyOldNameRepository.findById(id).orElse(null);
}
@Override
public Specification<CompanyOldName> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return SpecificationUtils.andWith(searchText, this::buildSearchSpecification);
}
protected Specification<CompanyOldName> buildSearchSpecification(String searchText) {
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("memo"), "%" + searchText + "%")
);
};
}
public CompanyOldName save(CompanyOldName companyOldName) {
return companyOldNameRepository.save(companyOldName);
}
public boolean makePathAbsent(CompanyOldName companyOldName) {
String path = companyOldName.getPath();
if (StringUtils.hasText(path)) {
File file = new File(path);
if (file.exists()) {
return false;
}
}
File dir = makePath(companyOldName);
if (dir == null) {
return false;
}
if (!dir.exists()) {
return false;
}
companyOldName.setPath(dir.getAbsolutePath());
return true;
}
public File makePath(CompanyOldName companyOldName) {
String oldName = companyOldName.getName();
File basePath = companyService.getBasePath();
Company company = companyService.findById(companyOldName.getCompanyId());
String district = company.getDistrict();
if (StringUtils.hasText(district)) {
String parentPrefix = CompanyFileUtils.getParentPrefixByDistrict(district);
if (parentPrefix != null) {
File parent = new File(basePath, parentPrefix);
if (!parent.exists()) {
if (!parent.mkdir()) {
return null;
}
}
String fileName = CompanyFileUtils.escapeFileName(oldName);
File dir = new File(parent, fileName);
if (!dir.exists()) {
if (!dir.mkdir()) {
return null;
}
}
return dir;
}
}
return null;
}
public List<CompanyOldName> findAllByName(String name) {
return companyOldNameRepository.findAllByName(name);
}
public List<CompanyOldName> findAll(Specification<CompanyOldName> spec, Sort sort) {
return companyOldNameRepository.findAll(spec, sort);
}
public List<CompanyOldName> findAllByCompany(Company company) {
return companyOldNameRepository.findAllByCompanyId(company.getId());
}
public CompanyOldName findMatchByDate(Company company, LocalDate date) {
List<CompanyOldName> oldNames = findAllByCompany(company);
if (oldNames == null || oldNames.isEmpty()) {
return null;
}
return oldNames.stream().filter(v -> {
if (v.getAmbiguity()) {
return false;
}
if (v.getBeginDate() != null && date.isBefore(v.getBeginDate())) {
return false;
}
if (v.getEndDate() != null && date.isAfter(v.getEndDate())) {
return false;
}
return true;
}).findFirst().orElse(null);
}
public void deleteById(int id) {
companyOldNameRepository.deleteById(id);
}
public void delete(CompanyOldNameViewModel model) {
int id = model.getId().get();
deleteById(id);
}
public void delete(CompanyOldName entity) {
companyOldNameRepository.delete(entity);
}
public List<CompanyOldName> findAllByCompanyAndName(Company company, String oldName) {
return companyOldNameRepository.findAllByCompanyIdAndName(company.getId(), oldName);
}
/**
* 将 from 的曾用名 关联到 to
*
* @param from from
* @param to to
*/
public void resetTo(Company from, Company to) {
// 曾用名 关联到 to
List<CompanyOldName> list = companyOldNameRepository.findAllByCompanyId(from.getId());
if (list.isEmpty()) {
return;
}
for (CompanyOldName oldName : list) {
oldName.setMemo(MyStringUtils.appendIfAbsent(oldName.getMemo(), "转自 " + from.getId()));
oldName.setCompanyId(to.getId());
}
companyOldNameRepository.saveAll(list);
}
public void deleteByCompany(Company company) {
int deleted = companyOldNameRepository.deleteAllByCompanyId(company.getId());
if (deleted > 0) {
if (logger.isInfoEnabled()) {
logger.info("Delete {} records by company:#{}", deleted, company.getId());
}
}
}
/**
* 根据提供的搜索文本查询公司旧名称列表。
* <p>
* 该函数使用JPA的Specification接口构建查询条件查找公司旧名称中包含指定文本的记录。
* 查询结果最多返回10条记录。
*
* @param searchText 用于搜索的文本,将匹配公司旧名称中包含该文本的记录。
* @return 包含匹配的公司旧名称的列表列表中的每个元素都是一个CompanyOldName对象。
*/
public List<CompanyOldName> search(String searchText) {
return companyOldNameRepository.findAll(getSpecification(searchText), Pageable.ofSize(10)).getContent();
}
@Override
public Page<CompanyOldName> findAll(Specification<CompanyOldName> spec, Pageable pageable) {
return companyOldNameRepository.findAll(spec, pageable);
}
public CompanyOldName createNew(Company company, String name, boolean ambiguity) {
CompanyOldName companyOldName = new CompanyOldName();
companyOldName.setCompanyId(company.getId());
companyOldName.setName(name);
companyOldName.setAmbiguity(ambiguity);
return companyOldName;
}
}

View File

@@ -0,0 +1,616 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.cloud.rk.CloudRkService;
import com.ecep.contract.manager.cloud.tyc.CloudTycService;
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
import com.ecep.contract.manager.ds.company.CompanyFileUtils;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.company.repository.CompanyRepository;
import com.ecep.contract.manager.ds.company.vo.CompanyViewModel;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.customer.model.CompanyCustomer;
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
import com.ecep.contract.manager.ds.other.service.SysConfService;
import com.ecep.contract.manager.ds.vendor.model.CompanyVendor;
import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import com.ecep.contract.manager.util.MyStringUtils;
import com.ecep.contract.manager.util.SpecificationUtils;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 公司服务
*/
@Lazy
@Service
@CacheConfig(cacheNames = "company")
public class CompanyService implements ViewModelService<Company, CompanyViewModel> {
private static final Logger logger = LoggerFactory.getLogger(CompanyService.class);
private static final String COMPANY_BASE_PATH = "company.base.path";
@Lazy
@Autowired
private CompanyRepository companyRepository;
@Lazy
@Autowired
private SysConfService confService;
@Lazy
@Autowired
private CompanyFileService companyFileService;
@Lazy
@Autowired
private ContractService contractService;
@Lazy
@Autowired
private CompanyVendorService companyVendorService;
@Lazy
@Autowired
private CompanyCustomerService companyCustomerService;
@Lazy
@Autowired
private CompanyOldNameService companyOldNameService;
@Lazy
@Autowired
private CompanyContactService companyContactService;
@Lazy
@Autowired
private CloudRkService cloudRkService;
@Lazy
@Autowired
private CloudTycService cloudTycService;
@Lazy
@Autowired(required = false)
private YongYouU8Service yongYouU8Service;
@Cacheable(key = "#p0")
public Company findById(Integer id) {
return companyRepository.findById(id).orElse(null);
}
@Cacheable(key = "'name-'+#p0")
public Company findByName(String name) {
return companyRepository.findFirstByName(name).orElse(null);
}
/**
* 查找名称是 name 的记录
*
* @param name 查询的公司名称
* @return 记录列表
*/
public List<Company> findAllByName(String name) {
return companyRepository.findAllByName(name);
}
public Page<Company> findAll(Specification<Company> spec, Pageable pageable) {
return companyRepository.findAll(spec, pageable);
}
/**
* 查找
* 重复的删除
*
* @param uniscid 统一社会信用代码
* @return 公司对象
*/
public Company findAndRemoveDuplicateCompanyByUniscid(String uniscid) {
// 根据统一社会信用代码去查询
List<Company> companies = companyRepository.findAllByUniscid(uniscid);
if (companies.isEmpty()) {
return null;
}
if (companies.size() == 1) {
return companies.getFirst();
} else {
List<Company> result = removeDuplicatesByUniscid(companies);
if (!result.isEmpty()) {
return result.getFirst();
}
}
return null;
}
/**
* 查找公司,根据名称或简称查询
* <p>
* 1. 先按照 name 查找Company记录如果有多个记录只保留一条保留规则参考 #removeDuplicatesByUniscid 方法
* 2. 第一步没有匹配到时,根据名称从曾用名中查询
* 3. 上一步没有匹配到时,根据简称从公司数据库查询匹配简称的公司
* 4. 上一步没有匹配到时,根据简称从曾用名中查询
* 根据简称去查询,如果有多个记录只保留一条,保留规则参考 #removeDuplicatesByUniscid 方法
* 重复的删除
*
* @param name 企业名称
* @param abbName 别名
* @return 公司对象
*/
public Company findAndRemoveDuplicateCompanyByNameOrAbbName(String name, String abbName) {
Company updater = null;
{
// 根据公司全名去查询
List<Company> companies = companyRepository.findAllByName(name);
if (companies.isEmpty()) {
if (logger.isDebugEnabled()) {
logger.debug("No record match by {}", name);
}
} else if (companies.size() == 1) {
updater = companies.getFirst();
} else {
List<Company> result = removeDuplicatesByUniscid(companies);
if (!result.isEmpty()) {
updater = result.getFirst();
}
}
}
if (updater == null) {
// 根据公司名称去曾用名中查询
List<CompanyOldName> oldNames = companyOldNameService.findAllByName(name);
if (!oldNames.isEmpty()) {
CompanyOldName oldName = oldNames.getFirst();
Optional<Company> optional = companyRepository.findById(oldName.getCompanyId());
if (optional.isPresent()) {
updater = optional.get();
}
}
}
if (updater == null && StringUtils.hasText(abbName) && !Objects.equals(abbName, name)) {
// 根据公司全面去查询
List<Company> companies = companyRepository.findAllByShortName(abbName);
if (!companies.isEmpty()) {
updater = companies.removeFirst();
}
if (updater == null) {
// 根据公司名称去曾用名中查询
List<CompanyOldName> oldNames = companyOldNameService.findAllByName(abbName);
if (!oldNames.isEmpty()) {
CompanyOldName oldName = null;
Optional<CompanyOldName> optional1 = oldNames.stream().filter(CompanyOldName::getAmbiguity).findFirst();
oldName = optional1.orElseGet(oldNames::getFirst);
Optional<Company> optional = companyRepository.findById(oldName.getCompanyId());
if (optional.isPresent()) {
updater = optional.get();
}
}
}
}
return updater;
}
/**
* 删除 列表中 Uniscid 重复的
*/
private List<Company> removeDuplicatesByUniscid(List<Company> list) {
List<Company> result = new ArrayList<>();
List<Company> removes = new ArrayList<>();
Set<String> uniqueUniscidSet = new HashSet<>();
for (Company company : list) {
// 名称相同后,统一社会信用编号 也相同的话,删除
if (uniqueUniscidSet.add(company.getUniscid())) {
// 没有记录过时
result.add(company);
} else {
// 有重复时
removes.add(company);
}
}
Company updater = result.getFirst();
// 合并重复的
for (Company company : removes) {
try {
merge(company, updater);
} catch (Exception e) {
logger.error("合并 {} -> {} 时发生错误:{}", company.toPrettyString(), updater.toPrettyString(), e.getMessage(), e);
throw e;
}
}
return result;
}
/**
* 删除
* <p>
* 删除前需要把关联数据解除
* <ul>
* <li>{@link CompanyVendorService#deleteByCompany(Company)}</li>
* <li>{@link CompanyCustomerService#deleteByCompany(Company)}</li>
* <li>{@link CompanyOldNameService#deleteByCompany(Company)}</li>
* <li>{@link CompanyContactService#deleteByCompany(Company)}</li>
* <li>{@link ContractService#deleteByCompany(Company)}</li>
* <li>{@link CompanyContactService#deleteByCompany(Company)}</li>
* </ul>
* 或者 把关联数据转移到其他公司
* <ul>
* <li>{@link CompanyVendorService#resetTo(Company, Company)} </li>
* <li>{@link CompanyCustomerService#resetTo(Company, Company)} </li>
* <li>{@link CompanyOldNameService#resetTo(Company, Company)} </li>
* <li>{@link CompanyContactService#resetTo(Company, Company)} </li>
* <li>{@link ContractService#resetTo(Company, Company)}</li>
* <li>{@link CompanyContactService#resetTo(Company, Company)}</li>
* </ul>
* </p>
*
* @param company 要删除的公司对象
*/
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'name-'+#p0.name")
}
)
public void delete(Company company) {
cloudRkService.deleteByCompany(company);
cloudTycService.deleteByCompany(company);
yongYouU8Service.deleteByCompany(company);
companyOldNameService.deleteByCompany(company);
companyContactService.deleteByCompany(company);
// 供应商和客户
companyVendorService.deleteByCompany(company);
companyCustomerService.deleteByCompany(company);
contractService.deleteByCompany(company);
companyContactService.deleteByCompany(company);
companyRepository.delete(company);
if (logger.isInfoEnabled()) {
logger.info("Delete Company {}", company);
}
}
/**
* 合并 from 到 to
* <p>
* 下述关联数据重设绑定到 to
* <ol>
* <li>曾用名</li>
* <li>供应商</li>
* <li>客户</li>
* <li>合同</li>
* <li>公司合同</li>
* </ol>
* </p>
*/
public void merge(Company from, Company to) {
// cloudRkService.findById(from.getId());
cloudRkService.resetTo(from, to);
cloudTycService.resetTo(from, to);
yongYouU8Service.resetTo(from, to);
companyOldNameService.resetTo(from, to);
companyContactService.resetTo(from, to);
// 供应商和客户
companyVendorService.resetTo(from, to);
companyCustomerService.resetTo(from, to);
contractService.resetTo(from, to);
companyContactService.resetTo(from, to);
companyRepository.delete(from);
if (logger.isInfoEnabled()) {
logger.info("Merge {} to {}", from, to);
}
}
/**
* 保存实体对象,异步方法
*
* @param company 要保存的实体对象
* @return 返回异步调用
*/
public CompletableFuture<Company> asyncSave(Company company) {
return CompletableFuture.completedFuture(companyRepository.save(company));
}
/**
* 保存实体对象
*
* @param company 要保存的实体对象
* @return 返回异步调用
*/
@Caching(
evict = {
@CacheEvict(key = "#p0.id"),
@CacheEvict(key = "'name-'+#p0.name")
}
)
public Company save(Company company) {
return companyRepository.save(company);
}
@Override
public CompanyViewModel from(Company entity) {
return CompanyViewModel.from(entity);
}
public long count() {
return companyRepository.count();
}
public long count(Specification<Company> spec) {
return companyRepository.count(spec);
}
@Transactional
public void findAllWithStream(Consumer<Stream<Company>> consumer) {
try (Stream<Company> stream = companyRepository.findAllAsStream()) {
consumer.accept(stream);
}
}
public File getVendorBasePath() {
return new File(confService.getString(CompanyVendorService.KEY_BASE_PATH));
}
public File getCustomerBasePath() {
return new File(confService.getString(CompanyCustomerService.KEY_BASE_PATH));
}
public File getBasePath() {
return new File(confService.getString(COMPANY_BASE_PATH));
}
/**
* 创建公司目录,如果公司目录未设置,或者未存在
*
* @param company 要创建目录的公司对象
* @return 是否创建了目录
*/
public boolean makePathAbsent(Company company) {
String path = company.getPath();
if (StringUtils.hasText(path)) {
File file = new File(path);
if (file.exists()) {
return false;
}
}
File dir = makePath(company);
if (dir == null) {
return false;
}
if (!dir.exists()) {
return false;
}
company.setPath(dir.getAbsolutePath());
company.setPathExist(true);
return true;
}
/**
* 创建企业目录
*
* @param company 要创建的企业对象
* @return 目录
*/
public File makePath(Company company) {
File basePath = getBasePath();
if (!basePath.exists()) {
return null;
}
String companyName = company.getName();
String district = company.getDistrict();
if (StringUtils.hasText(district)) {
String parentPrefix = CompanyFileUtils.getParentPrefixByDistrict(district);
if (parentPrefix != null) {
File parent = new File(basePath, parentPrefix);
if (!parent.exists()) {
if (!parent.mkdir()) {
return null;
}
}
String fileName = CompanyFileUtils.escapeFileName(companyName);
File dir = new File(parent, fileName);
if (!dir.exists()) {
if (!dir.mkdir()) {
return null;
}
}
return dir;
}
}
return null;
}
/**
* 移动文件到企业目录下
*
* @param company 企业对象
* @param files 要被移动的文件集合,需要从中选择需要的
* @param status 状态输出
*/
public boolean retrieveFromDownloadFiles(Company company, File[] files, Consumer<String> status) {
//
boolean companyChanged = makePathAbsent(company);
if (!StringUtils.hasText(company.getPath())) {
// fixed 要退出,需要保存
if (companyChanged) {
save(company);
}
status.accept("存储目录未设置,请检查");
return false;
}
File home = new File(company.getPath());
if (!home.exists()) {
// fixed 要退出,需要保存
if (companyChanged) {
company = save(company);
}
status.accept(company.getPath() + " 不存在,无法访问,请检查或者修改");
return false;
}
boolean retrieved = companyFileService.retrieveFromDownloadFiles(company, files, status);
if (companyChanged) {
save(company);
}
return retrieved;
}
/**
* 验证企业状态
*
* @param company 要验证的公司
* @param verifyDate 验证日期
* @param status 状态输出
*/
public void verifyEnterpriseStatus(Company company, LocalDate verifyDate, Consumer<String> status) {
// 检查营业状态
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 之后注销
status.accept("营业状态异常:" + entStatus);
} else {
if (!MyDateTimeUtils.dateValidFilter(verifyDate, begin, end, 0)) {
status.accept("营业状态异常:" + entStatus);
}
}
}
} else {
status.accept("营业状态异常:未设置");
}
}
@Override
public Specification<Company> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
// 判断是否全是数字
boolean isAllDigit = MyStringUtils.isAllDigit(searchText);
if (isAllDigit) {
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("id").as(String.class), "%" + searchText + "%"),
builder.like(root.get("uniscid"), "%" + searchText + "%")
);
};
}
Specification<Company> spec = null;
Set<Integer> idSet = companyOldNameService.search(searchText).stream().map(CompanyOldName::getCompanyId).collect(Collectors.toSet());
if (!idSet.isEmpty()) {
spec = SpecificationUtils.or(spec, (root, query, builder) -> {
return root.get("id").in(idSet);
});
}
List<CompanyVendor> searchedVendors = companyVendorService.search(searchText);
if (!searchedVendors.isEmpty()) {
spec = SpecificationUtils.or(spec, (root, query, builder) -> {
return builder.in(root.get("id")).value(searchedVendors.stream()
.map(CompanyVendor::getCompany)
.filter(Objects::nonNull)
.map(Company::getId)
.collect(Collectors.toSet()));
});
}
List<CompanyCustomer> searchedCustomers = companyCustomerService.search(searchText);
if (!searchedCustomers.isEmpty()) {
spec = SpecificationUtils.or(spec, (root, query, builder) -> {
return builder.in(root.get("id")).value(searchedCustomers.stream()
.map(CompanyCustomer::getCompany)
.filter(Objects::nonNull)
.map(Company::getId)
.collect(Collectors.toSet()));
});
}
return SpecificationUtils.or(spec, SpecificationUtils.andWith(searchText, this::buildSearchSpecification));
}
protected Specification<Company> buildSearchSpecification(String searchText) {
return (root, query, builder) -> buildSearchPredicate(searchText, root, query, builder);
}
public Predicate buildSearchPredicate(String searchText, Path<Company> root, @Nullable CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.or(
builder.like(root.get("name"), "%" + searchText + "%"),
builder.like(root.get("shortName"), "%" + searchText + "%"),
builder.like(root.get("uniscid"), "%" + searchText + "%"),
builder.like(root.get("legalRepresentative"), "%" + searchText + "%"),
builder.like(root.get("regAddr"), "%" + searchText + "%"),
builder.like(root.get("address"), "%" + searchText + "%"),
builder.like(root.get("memo"), "%" + searchText + "%")
);
}
/**
* 检索企业
* 企业名称中模糊搜索
*
* @param searchText 搜索文本
* @return 企业列表返回前10个企业
*/
public List<Company> search(String searchText) {
Specification<Company> spec = getSpecification(searchText);
return companyRepository.findAll(spec, Pageable.ofSize(10)).getContent();
}
public Company createNewCompany(String name) {
Company company = new Company();
company.setName(name);
company.setCreated(LocalDate.now());
return company;
}
public List<String> getAllNames(Company company) {
List<String> list = new ArrayList<>();
list.add(company.getName());
companyOldNameService.findAllByCompany(company).forEach(oldName -> {
// 歧义的曾用名不采用
if (oldName.getAmbiguity()) {
return;
}
list.add(oldName.getName());
});
return list;
}
}

View File

@@ -0,0 +1,75 @@
package com.ecep.contract.manager.ds.company.service;
import com.ecep.contract.manager.ds.company.model.Invoice;
import com.ecep.contract.manager.ds.company.repository.InvoiceRepository;
import com.ecep.contract.manager.ds.company.vo.InvoiceViewModel;
import com.ecep.contract.manager.ui.ViewModelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
@Lazy
@Service
@CacheConfig(cacheNames = "invoice")
public class InvoiceService implements ViewModelService<Invoice, InvoiceViewModel> {
private static final Logger logger = LoggerFactory.getLogger(InvoiceService.class);
@Autowired
private InvoiceRepository repository;
@Cacheable(key = "#p0")
public Invoice findById(Integer id) {
return repository.findById(id).orElse(null);
}
@Override
public Specification<Invoice> getSpecification(String searchText) {
if (!StringUtils.hasText(searchText)) {
return null;
}
return (root, query, builder) -> {
return builder.or(
builder.like(root.get("code"), "%" + searchText + "%"),
builder.like(root.get("description"), "%" + searchText + "%")
);
};
}
@Override
public Page<Invoice> findAll(Specification<Invoice> spec, Pageable pageable) {
return repository.findAll(spec, pageable);
}
@CacheEvict(key = "#p0.id")
public void delete(Invoice entity) {
repository.delete(entity);
}
public List<Invoice> findAll(Specification<Invoice> spec, Sort by) {
return repository.findAll(spec, by);
}
public Invoice findByCode(String invoiceNumber) {
return repository.findByCode(invoiceNumber);
}
@CacheEvict(key = "#p0.id")
public Invoice save(Invoice invoice) {
return repository.save(invoice);
}
}

View File

@@ -0,0 +1,147 @@
package com.ecep.contract.manager.ds.company.tasker;
import com.ecep.contract.manager.cloud.rk.CloudRk;
import com.ecep.contract.manager.cloud.rk.CloudRkService;
import com.ecep.contract.manager.cloud.rk.ctx.CloudRkCtx;
import com.ecep.contract.manager.cloud.tyc.CloudTycService;
import com.ecep.contract.manager.cloud.u8.CloudYu;
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
import com.ecep.contract.manager.cloud.u8.ctx.CompanyCtx;
import com.ecep.contract.manager.cloud.u8.ctx.ContractCtx;
import com.ecep.contract.manager.cloud.u8.ctx.CustomerCtx;
import com.ecep.contract.manager.cloud.u8.ctx.VendorCtx;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ui.MessageHolder;
import com.ecep.contract.manager.ui.Tasker;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import java.time.Instant;
import java.time.LocalDate;
/**
* 合并更新
*/
public class CompanyCompositeUpdateTasker extends Tasker<Object> {
private static final Logger logger = LoggerFactory.getLogger(CompanyCompositeUpdateTasker.class);
CloudRkCtx cloudRkCtx = new CloudRkCtx();
@Setter
private CloudRkService cloudRkService;
@Setter
private CloudTycService cloudTycService;
@Setter
private YongYouU8Service yongYouU8Service;
@Setter
private Company company;
@Override
protected Object execute(MessageHolder holder) throws Exception {
updateProgress(0.1, 1);
syncFromCloudRk(holder);
updateProgress(0.3, 1);
syncFromYongYouU8(holder);
updateProgress(0.6, 1);
syncFromCloudTyc(holder);
return null;
}
private void syncFromCloudRk(MessageHolder holder) {
holder.debug("1. 从 " + CloudRkService.NAME + " 更新...");
try {
cloudRkService = getBean(CloudRkService.class);
} catch (BeansException e) {
holder.warn("未启用 " + CloudRkService.NAME + " 服务");
return;
}
CloudRk cloudRk = cloudRkService.getOrCreateCloudRk(company);
if (cloudRk == null) {
holder.error("无法创建或获取 CloudRk 对象");
return;
}
try {
cloudRkCtx.setCloudRkService(cloudRkService);
if (cloudRkCtx.syncCompany(company, cloudRk, holder)) {
}
} catch (Exception e) {
cloudRk.setDescription(e.getMessage());
} finally {
cloudRk.setLatestUpdate(Instant.now());
cloudRkService.save(cloudRk);
}
}
private void syncFromYongYouU8(MessageHolder holder) {
holder.debug("2. 从 " + YongYouU8Service.NAME + " 更新...");
try {
yongYouU8Service = getBean(YongYouU8Service.class);
} catch (BeansException e) {
holder.warn("未启用 " + YongYouU8Service.NAME + " 服务");
return;
}
CloudYu cloudYu = yongYouU8Service.getOrCreateCloudYu(company);
if (cloudYu == null) {
holder.error("无法创建或获取 CloudYu 对象");
return;
}
try {
CompanyCtx companyCtx = new CompanyCtx();
yongYouU8Service.initialize(companyCtx);
if (companyCtx.syncCompany(company, holder)) {
holder.info("更新");
}
VendorCtx vendorCtx = new VendorCtx();
yongYouU8Service.initialize(vendorCtx);
vendorCtx.setCompanyCtx(companyCtx);
if (vendorCtx.syncVendor(company, holder)) {
cloudYu.setVendorUpdateDate(LocalDate.now());
}
CustomerCtx customerCtx = new CustomerCtx();
yongYouU8Service.initialize(customerCtx);
customerCtx.setCompanyCtx(companyCtx);
if (customerCtx.syncCustomer(company, holder)) {
cloudYu.setCustomerUpdateDate(LocalDate.now());
}
ContractCtx contractCtx = new ContractCtx();
yongYouU8Service.initialize(contractCtx);
contractCtx.syncContract(company, holder);
cloudYu.setCloudLatest(Instant.now());
cloudYu.setExceptionMessage("");
} catch (Exception e) {
String message = e.getMessage();
holder.error("同步过程中发生错误: " + message);
// 保留255个字符
if (message.length() > 255) {
message = message.substring(0, 255);
}
cloudYu.setExceptionMessage(message);
} finally {
cloudYu.setLatestUpdate(Instant.now());
yongYouU8Service.save(cloudYu);
}
}
private void syncFromCloudTyc(MessageHolder holder) {
holder.debug("3. 从 " + CloudTycService.NAME + " 更新...");
try {
cloudTycService = getBean(CloudTycService.class);
} catch (BeansException e) {
holder.warn("未启用 " + CloudTycService.NAME + " 服务");
return;
}
cloudTycService.syncCompany(company, holder);
updateProgress(1, 1);
}
}

View File

@@ -0,0 +1,71 @@
package com.ecep.contract.manager.ds.company.tasker;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyFileService;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ui.MessageHolder;
import com.ecep.contract.manager.ui.Tasker;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 对所有公司的文件进行重置
*/
public class CompanyFilesRebuildTasker extends Tasker<Object> {
private CompanyFileService companyFileService;
public CompanyFilesRebuildTasker() {
updateTitle("合同文件重置");
}
@Override
protected Object execute(MessageHolder holder) throws Exception {
Pageable pageRequest = PageRequest.ofSize(200);
AtomicInteger counter = new AtomicInteger(0);
Specification<Company> spec = null;
// Specification<Contract> spec = (root, query, cb) -> {
// return cb.greaterThan(root.get("created"), Instant.now().minusSeconds(TimeUnit.DAYS.toSeconds(360)));
// };
updateTitle("遍历所有公司,对每个可以公司的文件进行“重置”操作");
long total = getCompanyService().count(spec);
while (true) {
if (isCancelled()) {
break;
}
Page<Company> page = getCompanyService().findAll(spec, pageRequest);
if (page.isEmpty()) {
break;
}
for (Company company : page) {
if (isCancelled()) {
break;
}
String prefix = counter.get() + " / " + total + "> " + company.getName() + " #" + company.getId() + "> ";
getCompanyFileService().reBuildingFiles(company, holder.sub(prefix)::info);
updateProgress(counter.incrementAndGet(), total);
}
if (!page.hasNext()) {
break;
}
pageRequest = page.nextPageable();
}
return super.call();
}
private CompanyFileService getCompanyFileService() {
if (companyFileService == null) {
companyFileService = getBean(CompanyFileService.class);
}
return companyFileService;
}
}

View File

@@ -0,0 +1,92 @@
package com.ecep.contract.manager.ds.company.tasker;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.tasker.ContractVerifyComm;
import com.ecep.contract.manager.ui.MessageHolder;
import com.ecep.contract.manager.ui.Tasker;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
public class CompanyVerifyTasker extends Tasker<Object> {
@Setter
private CompanyService companyService;
@Getter
@Setter
private Company company;
ContractVerifyComm comm = new ContractVerifyComm();
AtomicBoolean verified = new AtomicBoolean(true);
public CompanyService getCompanyService() {
if (companyService == null) {
companyService = getBean(CompanyService.class);
}
return companyService;
}
@Override
protected Object call() throws Exception {
comm.getVerifyCompanyPath().set(false);
comm.getVerifyCompanyStatus().set(false);
comm.getVerifyCompanyCredit().set(false);
return execute(new MessageHolderImpl() {
@Override
public void addMessage(Level level, String message) {
super.addMessage(level, message);
if (level.intValue() > Level.INFO.intValue()) {
verified.set(false);
}
}
});
}
@Override
protected Object execute(MessageHolder holder) throws Exception {
updateTitle("验证企业是否符合合规要求");
verify(company, holder);
if (verified.get()) {
updateMessage(Level.CONFIG, "合规验证通过");
} else {
updateMessage(Level.SEVERE, "合规验证不通过");
}
return null;
}
/**
* 核验公司名下的所有合同
*
* @param company 公司
* @param holder 输出
*/
private void verify(Company company, MessageHolder holder) {
LocalDate now = LocalDate.now();
getCompanyService().verifyEnterpriseStatus(company, now, holder::info);
// 验证所有的合同
List<Contract> list = comm.getContractService().findAllByCompany(company);
if (list.isEmpty()) {
holder.debug("!没有相关合同!");
return;
}
holder.debug("检索到相关合同 " + list.size() + "");
AtomicInteger counter = new AtomicInteger(0);
long total = list.size();
for (Contract contract : list) {
holder.debug("核验合同:" + contract.getCode() + ", " + contract.getName());
comm.verify(company, contract, holder.sub("-- "));
updateProgress(counter.incrementAndGet(), total);
}
updateProgress(1, 1);
}
}

View File

@@ -0,0 +1,73 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyBankAccount;
import com.ecep.contract.manager.ds.company.model.CompanyBasedEntity;
import com.ecep.contract.manager.ds.other.model.Bank;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
import java.util.Objects;
@Data
@EqualsAndHashCode(callSuper = false)
public class CompanyBankAccountViewModel extends IdentityViewModel<CompanyBankAccount> implements CompanyBasedViewModel {
private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleObjectProperty<Company> company = new SimpleObjectProperty<>();
private SimpleObjectProperty<Bank> bank = new SimpleObjectProperty<>();
private SimpleStringProperty openingBank = new SimpleStringProperty();
private SimpleStringProperty account = new SimpleStringProperty();
private SimpleObjectProperty<LocalDate> created = new SimpleObjectProperty<>();
private SimpleIntegerProperty version = new SimpleIntegerProperty();
@Override
protected void updateFrom(CompanyBankAccount v) {
getId().set(v.getId());
getCompany().set(v.getCompany());
getBank().set(v.getBank());
getOpeningBank().set(v.getOpeningBank());
getAccount().set(v.getAccount());
}
@Override
public boolean copyTo(CompanyBankAccount v) {
boolean modified = super.copyTo(v);
if (!Objects.equals(id.get(), v.getId())) {
v.setId(id.get());
modified = true;
}
if (!Objects.equals(company.get(), v.getCompany())) {
v.setCompany(company.get());
modified = true;
}
if (!Objects.equals(bank.get(), v.getBank())) {
v.setBank(bank.get());
modified = true;
}
if (!Objects.equals(openingBank.get(), v.getOpeningBank())) {
v.setOpeningBank(openingBank.get());
modified = true;
}
if (!Objects.equals(account.get(), v.getAccount())) {
v.setAccount(account.get());
modified = true;
}
return modified;
}
public static CompanyBankAccountViewModel from(CompanyBankAccount v) {
CompanyBankAccountViewModel vm = new CompanyBankAccountViewModel();
vm.updateFrom(v);
return vm;
}
}

View File

@@ -0,0 +1,8 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.Company;
import javafx.beans.property.SimpleObjectProperty;
public interface CompanyBasedViewModel {
SimpleObjectProperty<Company> getCompany();
}

View File

@@ -0,0 +1,102 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.BlackReasonType;
import com.ecep.contract.manager.ds.company.model.CompanyBlackReason;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDate;
import java.util.Objects;
@Data
@EqualsAndHashCode(callSuper = false)
@ToString
public class CompanyBlackReasonViewModel extends IdentityViewModel<CompanyBlackReason> {
private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleObjectProperty<BlackReasonType> type = new SimpleObjectProperty<>();
private SimpleStringProperty applyName = new SimpleStringProperty();
private SimpleStringProperty blackReason = new SimpleStringProperty();
private SimpleStringProperty description = new SimpleStringProperty();
private SimpleStringProperty key = new SimpleStringProperty();
private SimpleObjectProperty<LocalDate> applyDate = new SimpleObjectProperty<>();
private SimpleObjectProperty<LocalDate> updateTime = new SimpleObjectProperty<>();
private SimpleObjectProperty<LocalDate> createTime = new SimpleObjectProperty<>();
private SimpleObjectProperty<LocalDate> includeDate = new SimpleObjectProperty<>();
public static CompanyBlackReasonViewModel from(CompanyBlackReason reason) {
CompanyBlackReasonViewModel model = new CompanyBlackReasonViewModel();
model.update(reason);
return model;
}
@Override
protected void updateFrom(CompanyBlackReason v) {
getId().set(v.getId());
getType().set(v.getType());
getApplyName().set(v.getApplyName());
getBlackReason().set(v.getBlackReason());
getDescription().set(v.getDescription());
getKey().set(v.getKey());
getApplyDate().set(v.getApplyDate());
getUpdateTime().set(v.getUpdateTime());
getCreateTime().set(v.getCreateTime());
getIncludeDate().set(v.getIncludeDate());
}
@Override
public boolean copyTo(CompanyBlackReason v) {
boolean modified = super.copyTo(v);
if (!Objects.equals(id.get(), v.getId())) {
v.setId(id.get());
modified = true;
}
if (!Objects.equals(type.get(), v.getType())) {
v.setType(type.get());
modified = true;
}
if (!Objects.equals(applyName.get(), v.getApplyName())) {
v.setApplyName(applyName.get());
modified = true;
}
if (!Objects.equals(blackReason.get(), v.getBlackReason())) {
v.setBlackReason(blackReason.get());
modified = true;
}
if (!Objects.equals(description.get(), v.getDescription())) {
v.setDescription(description.get());
modified = true;
}
if (!Objects.equals(key.get(), v.getKey())) {
v.setKey(key.get());
modified = true;
}
if (!Objects.equals(applyDate.get(), v.getApplyDate())) {
v.setApplyDate(applyDate.get());
modified = true;
}
if (!Objects.equals(updateTime.get(), v.getUpdateTime())) {
v.setUpdateTime(updateTime.get());
modified = true;
}
if (!Objects.equals(createTime.get(), v.getCreateTime())) {
v.setCreateTime(createTime.get());
modified = true;
}
if (!Objects.equals(includeDate.get(), v.getIncludeDate())) {
v.setIncludeDate(includeDate.get());
modified = true;
}
return modified;
}
}

View File

@@ -0,0 +1,60 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.CompanyContact;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
@Data
@EqualsAndHashCode(callSuper = false)
public class CompanyContactViewModel extends IdentityViewModel<CompanyContact> {
private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleStringProperty position = new SimpleStringProperty();
private SimpleStringProperty phone = new SimpleStringProperty();
private SimpleStringProperty email = new SimpleStringProperty();
private SimpleStringProperty address = new SimpleStringProperty();
private SimpleStringProperty u8Code = new SimpleStringProperty();
private SimpleStringProperty memo = new SimpleStringProperty();
private SimpleIntegerProperty version = new SimpleIntegerProperty();
private SimpleObjectProperty<LocalDate> created = new SimpleObjectProperty<>();
public static CompanyContactViewModel from(CompanyContact contact) {
CompanyContactViewModel model = new CompanyContactViewModel();
model.update(contact);
return model;
}
public void updateFrom(CompanyContact v) {
id.set(v.getId());
name.set(v.getName());
position.set(v.getPosition());
phone.set(v.getPhone());
email.set(v.getEmail());
address.set(v.getAddress());
u8Code.set(v.getU8Code());
created.set(v.getCreated());
memo.set(v.getMemo());
version.set(v.getVersion());
}
public boolean copyTo(CompanyContact v) {
v.setId(id.get());
v.setName(name.get());
v.setPosition(position.get());
v.setPhone(phone.get());
v.setEmail(email.get());
v.setAddress(address.get());
v.setU8Code(u8Code.get());
v.setCreated(created.get());
v.setMemo(memo.get());
return true;
}
}

View File

@@ -0,0 +1,60 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyExtendInfo;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Objects;
@Data
@EqualsAndHashCode(callSuper = false)
public class CompanyExtendInfoViewModel extends BaseViewModel<CompanyExtendInfo> {
private SimpleIntegerProperty id = new SimpleIntegerProperty();
/**
* 关联的公司
*/
private SimpleObjectProperty<Company> company = new SimpleObjectProperty<>();
/**
* 是否禁用核验
*/
private SimpleBooleanProperty disableVerify = new SimpleBooleanProperty();
private SimpleIntegerProperty version = new SimpleIntegerProperty();
public static CompanyExtendInfoViewModel from(CompanyExtendInfo v) {
CompanyExtendInfoViewModel vm = new CompanyExtendInfoViewModel();
vm.updateFrom(v);
return vm;
}
@Override
protected void updateFrom(CompanyExtendInfo v) {
super.updateFrom(v);
getId().set(v.getId());
getCompany().set(v.getCompany());
getDisableVerify().set(v.isDisableVerify());
getVersion().set(v.getVersion());
}
@Override
public boolean copyTo(CompanyExtendInfo v) {
boolean modified = super.copyTo(v);
if (!Objects.equals(id.get(), v.getId())) {
v.setId(id.get());
modified = true;
}
if (!Objects.equals(company.get(), v.getCompany())) {
v.setCompany(company.get());
modified = true;
}
if (!Objects.equals(disableVerify.get(), v.isDisableVerify())) {
v.setDisableVerify(disableVerify.get());
modified = true;
}
return modified;
}
}

View File

@@ -0,0 +1,77 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.CompanyFile;
import com.ecep.contract.manager.ds.company.CompanyFileType;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
import java.util.Objects;
/**
* View Model for {@link CompanyFile}
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class CompanyFileViewModel extends IdentityViewModel<CompanyFile> {
SimpleIntegerProperty id = new SimpleIntegerProperty();
SimpleObjectProperty<Company> company = new SimpleObjectProperty<>();
SimpleObjectProperty<CompanyFileType> type = new SimpleObjectProperty<>();
SimpleObjectProperty<LocalDate> applyDate = new SimpleObjectProperty<>();
SimpleObjectProperty<LocalDate> expiringDate = new SimpleObjectProperty<>();
SimpleStringProperty filePath = new SimpleStringProperty();
@Override
protected void updateFrom(CompanyFile v) {
id.set(v.getId());
company.set(v.getCompany());
type.set(v.getType());
applyDate.set(v.getApplyDate());
expiringDate.set(v.getExpiringDate());
filePath.set(v.getFilePath());
}
public boolean copyTo(CompanyFile v) {
boolean modified = super.copyTo(v);
if (!Objects.equals(id.get(), v.getId())) {
v.setId(id.get());
modified = true;
}
if (!Objects.equals(company.get(), v.getCompany())) {
v.setCompany(company.get());
modified = true;
}
if (!Objects.equals(type.get(), v.getType())) {
v.setType(type.get());
modified = true;
}
if (!Objects.equals(applyDate.get(), v.getApplyDate())) {
v.setApplyDate(applyDate.get());
modified = true;
}
if (!Objects.equals(expiringDate.get(), v.getExpiringDate())) {
v.setExpiringDate(expiringDate.get());
modified = true;
}
if (!Objects.equals(filePath.get(), v.getFilePath())) {
v.setFilePath(filePath.get());
modified = true;
}
return modified;
}
public static CompanyFileViewModel from(CompanyFile file) {
CompanyFileViewModel model = new CompanyFileViewModel();
model.update(file);
return model;
}
}

View File

@@ -0,0 +1,60 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.CompanyOldName;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
@Data
@EqualsAndHashCode(callSuper = false)
public class CompanyOldNameViewModel extends IdentityViewModel<CompanyOldName> {
private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleStringProperty path = new SimpleStringProperty();
private SimpleObjectProperty<LocalDate> beginDate = new SimpleObjectProperty<>();
private SimpleObjectProperty<LocalDate> endDate = new SimpleObjectProperty<>();
private SimpleBooleanProperty ambiguity = new SimpleBooleanProperty();
private SimpleIntegerProperty version = new SimpleIntegerProperty();
private SimpleStringProperty memo = new SimpleStringProperty();
public static CompanyOldNameViewModel from(CompanyOldName name) {
CompanyOldNameViewModel model = new CompanyOldNameViewModel();
model.update(name);
return model;
}
public void updateFrom(CompanyOldName oldName) {
id.set(oldName.getId());
name.set(oldName.getName());
path.set(oldName.getPath());
memo.set(oldName.getMemo());
beginDate.set(oldName.getBeginDate());
endDate.set(oldName.getEndDate());
ambiguity.set(oldName.getAmbiguity());
version.set(oldName.getVersion());
}
public boolean copyTo(CompanyOldName c) {
c.setId(id.get());
c.setName(name.get());
c.setPath(path.get());
c.setMemo(memo.get());
c.setBeginDate(beginDate.get());
c.setEndDate(endDate.get());
c.setAmbiguity(ambiguity.get());
return false;
}
}

View File

@@ -0,0 +1,174 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
import java.util.Objects;
@Data
@EqualsAndHashCode(callSuper = false)
public class CompanyViewModel extends IdentityViewModel<Company> {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleStringProperty shortName = new SimpleStringProperty();
private SimpleStringProperty uid = new SimpleStringProperty();
private SimpleBooleanProperty pathExist = new SimpleBooleanProperty();
private SimpleStringProperty path = new SimpleStringProperty();
private SimpleObjectProperty<LocalDate> setupDate = new SimpleObjectProperty<>();
private SimpleStringProperty entStatus = new SimpleStringProperty();
private SimpleStringProperty entType = new SimpleStringProperty();
private SimpleStringProperty district = new SimpleStringProperty();
private SimpleStringProperty industry = new SimpleStringProperty();
private SimpleStringProperty regAddress = new SimpleStringProperty();
private SimpleStringProperty address = new SimpleStringProperty();
private SimpleStringProperty telephone = new SimpleStringProperty();
private SimpleObjectProperty<LocalDate> operationPeriodBegin = new SimpleObjectProperty<>();
private SimpleObjectProperty<LocalDate> operationPeriodEnd = new SimpleObjectProperty<>();
private SimpleStringProperty registeredCapital = new SimpleStringProperty();
private SimpleStringProperty registeredCapitalCurrency = new SimpleStringProperty();
private SimpleStringProperty legalRepresentative = new SimpleStringProperty();
private SimpleStringProperty memo = new SimpleStringProperty();
private SimpleObjectProperty<LocalDate> created = new SimpleObjectProperty<>();
private SimpleIntegerProperty version = new SimpleIntegerProperty();
public static CompanyViewModel from(Company company) {
CompanyViewModel model = new CompanyViewModel();
model.update(company);
return model;
}
@Override
protected void updateFrom(Company company) {
super.updateFrom(company);
name.set(company.getName());
shortName.set(company.getShortName());
uid.set(company.getUniscid());
if (company.getPathExist() != null) {
pathExist.set(company.getPathExist());
}
path.set(company.getPath());
setupDate.set(company.getSetupDate());
entStatus.set(company.getEntStatus());
entType.set(company.getEntType());
district.set(company.getDistrict());
industry.set(company.getIndustry());
regAddress.set(company.getRegAddr());
address.set(company.getAddress());
telephone.set(company.getTelephone());
operationPeriodBegin.set(company.getOperationPeriodBegin());
operationPeriodEnd.set(company.getOperationPeriodEnd());
registeredCapital.set(company.getRegisteredCapital());
registeredCapitalCurrency.set(company.getRegisteredCapitalCurrency());
legalRepresentative.set(company.getLegalRepresentative());
created.set(company.getCreated());
memo.set(company.getMemo());
version.set(company.getVersion());
}
public boolean copyTo(Company v) {
boolean modified = super.copyTo(v);
if (!Objects.equals(name.get(), v.getName())) {
v.setName(name.get());
modified = true;
}
if (!Objects.equals(shortName.get(), v.getShortName())) {
v.setShortName(shortName.get());
modified = true;
}
if (!Objects.equals(uid.get(), v.getUniscid())) {
v.setUniscid(uid.get());
modified = true;
}
if (!Objects.equals(pathExist.get(), v.getPathExist())) {
v.setPathExist(pathExist.get());
modified = true;
}
if (!Objects.equals(path.get(), v.getPath())) {
v.setPath(path.get());
modified = true;
}
if (!Objects.equals(setupDate.get(), v.getSetupDate())) {
v.setSetupDate(setupDate.get());
modified = true;
}
if (!Objects.equals(entStatus.get(), v.getEntStatus())) {
v.setEntStatus(entStatus.get());
modified = true;
}
if (!Objects.equals(entType.get(), v.getEntType())) {
v.setEntType(entType.get());
modified = true;
}
if (!Objects.equals(district.get(), v.getDistrict())) {
v.setDistrict(district.get());
modified = true;
}
if (!Objects.equals(industry.get(), v.getIndustry())) {
v.setIndustry(industry.get());
modified = true;
}
if (!Objects.equals(regAddress.get(), v.getRegAddr())) {
v.setRegAddr(regAddress.get());
modified = true;
}
if (!Objects.equals(address.get(), v.getAddress())) {
v.setAddress(address.get());
modified = true;
}
if (!Objects.equals(telephone.get(), v.getTelephone())) {
v.setTelephone(telephone.get());
modified = true;
}
if (!Objects.equals(operationPeriodBegin.get(), v.getOperationPeriodBegin())) {
v.setOperationPeriodBegin(operationPeriodBegin.get());
modified = true;
}
if (!Objects.equals(operationPeriodEnd.get(), v.getOperationPeriodEnd())) {
v.setOperationPeriodEnd(operationPeriodEnd.get());
modified = true;
}
if (!Objects.equals(registeredCapital.get(), v.getRegisteredCapital())) {
v.setRegisteredCapital(registeredCapital.get());
modified = true;
}
if (!Objects.equals(registeredCapitalCurrency.get(), v.getRegisteredCapitalCurrency())) {
v.setRegisteredCapitalCurrency(registeredCapitalCurrency.get());
modified = true;
}
if (!Objects.equals(legalRepresentative.get(), v.getLegalRepresentative())) {
v.setLegalRepresentative(legalRepresentative.get());
modified = true;
}
if (!Objects.equals(memo.get(), v.getMemo())) {
v.setMemo(memo.get());
modified = true;
}
if (!Objects.equals(created.get(), v.getCreated())) {
v.setCreated(created.get());
modified = true;
}
return modified;
}
}

View File

@@ -0,0 +1,66 @@
package com.ecep.contract.manager.ds.company.vo;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.model.Invoice;
import com.ecep.contract.manager.ds.other.vo.BaseViewModel;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDate;
import java.util.Objects;
@Data
@EqualsAndHashCode(callSuper = false)
public class InvoiceViewModel extends IdentityViewModel<Invoice> {
SimpleIntegerProperty id = new SimpleIntegerProperty();
SimpleStringProperty code = new SimpleStringProperty();
SimpleObjectProperty<Company> company = new SimpleObjectProperty<>();
SimpleObjectProperty<LocalDate> invoiceDate = new SimpleObjectProperty<>();
SimpleStringProperty description = new SimpleStringProperty();
@Override
protected void updateFrom(Invoice v) {
super.updateFrom(v);
getId().set(v.getId());
getCode().set(v.getCode());
getCompany().set(v.getCompany());
getInvoiceDate().set(v.getInvoiceDate());
getDescription().set(v.getDescription());
}
@Override
public boolean copyTo(Invoice v) {
boolean modified = super.copyTo(v);
if (!Objects.equals(id.get(), v.getId())) {
v.setId(id.get());
modified = true;
}
if (!Objects.equals(code.get(), v.getCode())) {
v.setCode(code.get());
modified = true;
}
if (!Objects.equals(company.get(), v.getCompany())) {
v.setCompany(company.get());
modified = true;
}
if (!Objects.equals(invoiceDate.get(), v.getInvoiceDate())) {
v.setInvoiceDate(invoiceDate.get());
modified = true;
}
if (!Objects.equals(description.get(), v.getDescription())) {
v.setDescription(description.get());
modified = true;
}
return modified;
}
public static InvoiceViewModel from(Invoice invoice) {
InvoiceViewModel vm = new InvoiceViewModel();
vm.updateFrom(invoice);
return vm;
}
}

View File

@@ -0,0 +1,129 @@
package com.ecep.contract.manager.ds.contract;
import lombok.Getter;
/**
* 合同审批文件
*/
@Getter
public enum ContractFileType {
/**
* 普通文件,一般的文件当文件没有特殊情况时,默认为普通文件
*/
General(true, true),
/**
* 成本审批
*/
Cost(true, false),
/**
* 成本审批表
*/
CostForm(true, false),
/**
* 采购申请表
*/
PurchaseRequestForm(false, true),
/**
* 采购合同审批表
*/
PurchaseContractApprovalForm(false, true),
/**
* 报价
*/
Quotation(true, false),
/**
* 报价审批表(单)
*/
QuotationApprovalForm(true, false),
/**
* 报价表(单)
*/
QuotationSheet(false, true),
/**
* 合同
*/
Contract(true, true),
/**
* 销售合同审批表
*/
ContractApprovalForm(true, false),
/**
* 提货单
*/
DeliveryOrder(true, true),
/**
* 投标审批表
*/
BidApprovalForm(true, false),
/**
* 中标通知书
*/
BidAcceptanceLetter(true, false),
/**
* 项目计划文件(项目策划书)
*/
ProjectPlanningDocument(true, false),
/**
* 提单申请单(发货申请单)
*/
ShippingApplication(true, false),
/**
* 到货签收单
*/
SignedDeliveryNote(true, false),
/**
* 完工验收单
*/
AcceptanceForm(true, true),
/**
* 重大项目决策记录单
*/
CriticalProjectDecisionRecord(true, true)
;
final boolean supportCustomer;
final boolean supportVendor;
ContractFileType(boolean supportCustomer, boolean supportVendor) {
this.supportCustomer = supportCustomer;
this.supportVendor = supportVendor;
}
/**
* 文件频率
*/
public enum Frequency {
/**
* 一次性
*/
Once,
/**
* 每日
*/
Daily,
/**
* 每周
*/
Weekly,
/**
* 每两周
*/
BiWeekly,
/**
* 每月
*/
Monthly,
/**
* 每季度
*/
Quarterly,
/**
* 每半年
*/
HalfYearly,
/**
* 每年
*/
Yearly;
}
}

View File

@@ -0,0 +1,41 @@
package com.ecep.contract.manager.ds.contract;
/**
* 付款方式
*/
public enum ContractPayWay {
/**
* 付款方式,对应采购合同
*/
PAY(""),
/**
* 收款方式, 对应销售合同
*/
RECEIVE(""),
/**
* 其他方式,对应框架协议等
*/
OTHER("其他");
private final String text;
ContractPayWay(String text) {
this.text = text;
}
public static ContractPayWay valueOfText(String way) {
for (ContractPayWay value : values()) {
if (value.getText().equals(way)) {
return value;
}
}
return null;
}
public String getText() {
return text;
}
}

View File

@@ -0,0 +1,28 @@
package com.ecep.contract.manager.ds.contract;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.other.EntityStringConverter;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Lazy
@Component
public class ContractStringConverter extends EntityStringConverter<Contract> {
@Lazy
@Autowired
ContractService service;
public ContractStringConverter() {
}
@PostConstruct
private void init() {
setInitialized(project -> service.findById(project.getId()));
setSuggestion(service::search);
//TODO 按名称找出,容易出问题
setFromString(service::findByName);
}
}

View File

@@ -0,0 +1,22 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import com.ecep.contract.manager.ui.AbstEntityBasedTabSkin;
import com.ecep.contract.manager.ui.TabSkin;
import lombok.Setter;
public abstract class AbstContractBasedTabSkin
extends AbstEntityBasedTabSkin<ContractWindowController, Contract, ContractViewModel>
implements TabSkin {
public AbstContractBasedTabSkin(ContractWindowController controller) {
super(controller);
viewModel = controller.getViewModel();
}
public ContractService getContractService() {
return controller.contractService;
}
}

View File

@@ -0,0 +1,32 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
import com.ecep.contract.manager.ui.AbstEntityTableTabSkin;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.TableOfTabSkin;
import com.ecep.contract.manager.util.SpecificationUtils;
import org.springframework.data.jpa.domain.Specification;
public abstract class AbstContractTableTabSkin<T extends IdentityEntity, TV extends IdentityViewModel<T>>
extends AbstEntityTableTabSkin<ContractWindowController, Contract, ContractViewModel, T, TV>
implements TabSkin, TableOfTabSkin<Contract, T, TV> {
public AbstContractTableTabSkin(ContractWindowController controller) {
super(controller);
}
public ContractService getContractService() {
return controller.contractService;
}
@Override
public Specification<T> getSpecification(Contract parent) {
return SpecificationUtils.and(getSpecification(), (root, query, builder) -> {
return builder.equal(root.get("contract"), parent);
});
}
}

View File

@@ -0,0 +1,40 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.model.ContractGroup;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import javafx.scene.control.TableCell;
import org.hibernate.Hibernate;
import static com.ecep.contract.manager.SpringApp.getBean;
public class ContractGroupTableCell extends TableCell<ContractViewModel, ContractGroup> {
private ContractService contractService;
public ContractGroupTableCell() {
}
public ContractGroupTableCell(ContractService contractService) {
this.contractService = contractService;
}
ContractService getContractService() {
if (contractService == null) {
contractService = getBean(ContractService.class);
}
return contractService;
}
@Override
protected void updateItem(ContractGroup item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
return;
}
if (!Hibernate.isInitialized(item)) {
item = getContractService().findGroupById(item.getId());
}
setText(item.getName());
}
}

View File

@@ -0,0 +1,41 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.model.ContractKind;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import javafx.scene.control.TableCell;
import org.hibernate.Hibernate;
import static com.ecep.contract.manager.SpringApp.getBean;
public class ContractKindTableCell extends TableCell<ContractViewModel, ContractKind> {
private ContractService contractService;
public ContractKindTableCell() {
}
public ContractKindTableCell(ContractService contractService) {
this.contractService = contractService;
}
ContractService getContractService() {
if (contractService == null) {
contractService = getBean(ContractService.class);
}
return contractService;
}
@Override
protected void updateItem(ContractKind item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
return;
}
if (!Hibernate.isInitialized(item)) {
item = getContractService().findKindById(item.getId());
}
setText(item.getName());
}
}

View File

@@ -0,0 +1,128 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.company.controller.CompanyTableCell;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractGroup;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
import com.ecep.contract.manager.ui.AbstEntityManagerSkin;
import com.ecep.contract.manager.ui.ComboBoxUtils;
import com.ecep.contract.manager.ui.ManagerSkin;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import com.ecep.contract.manager.util.SpecificationUtils;
import jakarta.persistence.criteria.Path;
import javafx.application.Platform;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.CurrencyStringConverter;
import javafx.util.converter.LocalDateTimeStringConverter;
import lombok.Setter;
import org.springframework.data.jpa.domain.Specification;
import java.time.format.DateTimeFormatter;
public class ContractManagerSkin
extends AbstEntityManagerSkin<Contract, ContractViewModel, ContractManagerSkin, ContractManagerWindowController>
implements ManagerSkin {
@Setter
private ContractService contractService;
public ContractManagerSkin(ContractManagerWindowController controller) {
super(controller);
}
public ContractService getContractService() {
if (contractService == null) {
contractService = getBean(ContractService.class);
}
return contractService;
}
@Override
public Specification<Contract> getSpecification() {
Specification<Contract> spec = super.getSpecification();
if (controller.composeViewBtn.isSelected()) {
spec = SpecificationUtils.and(spec, (root, query, builder) -> {
Path<String> parentCode = root.get("parentCode");
Path<ContractPayWay> payWay = root.get("payWay");
return builder.or(
builder.equal(payWay, ContractPayWay.RECEIVE),
builder.and(
builder.equal(payWay, ContractPayWay.PAY),
builder.or(
builder.equal(parentCode, ""),
parentCode.isNull()
)
)
);
});
}
ContractGroup selectedGroup = controller.groupSelector.getValue();
if (selectedGroup != null) {
spec = SpecificationUtils.and(spec, (root, query, builder) -> {
return builder.equal(root.get("group"), selectedGroup);
});
}
return spec;
}
@SuppressWarnings("unchecked")
@Override
public void initializeTable() {
ComboBoxUtils.initialComboBox(controller.groupSelector, contractService.findAllGroups(), true);
controller.groupSelector.valueProperty().addListener((observable, oldValue, newValue) -> {
loadTableDataSet(false);
});
controller.idColumn.setCellValueFactory(param -> param.getValue().getId());
controller.nameColumn.setCellValueFactory(param -> param.getValue().getName());
controller.codeColumn.setCellValueFactory(param -> param.getValue().getCode());
controller.groupColumn.setCellValueFactory(param -> param.getValue().getGroup());
controller.groupColumn.setCellFactory(param -> new ContractGroupTableCell(contractService));
controller.typeColumn.setCellValueFactory(param -> param.getValue().getType());
controller.typeColumn.setCellFactory(param -> new ContractTypeTableCell(contractService));
controller.kindColumn.setCellValueFactory(param -> param.getValue().getKind());
controller.kindColumn.setCellFactory(param -> new ContractKindTableCell(contractService));
controller.parentCodeColumn.setCellValueFactory(param -> param.getValue().getParentCode());
controller.setupDateColumn.setCellValueFactory(param -> param.getValue().getSetupDate());
controller.orderDateColumn.setCellValueFactory(param -> param.getValue().getOrderDate());
controller.startDateColumn.setCellValueFactory(param -> param.getValue().getStartDate());
controller.employeeColumn.setCellValueFactory(param -> param.getValue().getEmployee());
controller.employeeColumn.setCellFactory(TextFieldTableCell.forTableColumn(getBean(EmployeeStringConverter.class)));
controller.createdColumn.setCellValueFactory(param -> param.getValue().getCreated());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(MyDateTimeUtils.DEFAULT_DATETIME_FORMAT_PATTERN);
controller.createdColumn.setCellFactory(TextFieldTableCell.forTableColumn(new LocalDateTimeStringConverter(formatter, null)));
controller.amountColumn.setCellValueFactory(param -> param.getValue().getAmount());
controller.amountColumn.setCellFactory(TextFieldTableCell.forTableColumn(new CurrencyStringConverter(getLocale(), "#,##0")));
controller.companyColumn.setCellValueFactory(param -> param.getValue().getCompany());
controller.companyColumn.setCellFactory(param -> new CompanyTableCell<>());
Platform.runLater(() -> {
controller.composeViewBtn.selectedProperty().addListener((observable, oldValue, newValue) -> {
loadTableDataSet(false);
});
controller.parentCodeColumn.visibleProperty().bind(controller.composeViewBtn.selectedProperty().not());
getTableView().getSortOrder().addAll(controller.createdColumn, controller.setupDateColumn);
});
}
@Override
protected void onTableRowDoubleClickedAction(ContractViewModel item) {
showInOwner(item);
}
private void showInOwner(ContractViewModel model) {
showInOwner(ContractWindowController.class, model);
}
}

View File

@@ -0,0 +1,97 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractGroup;
import com.ecep.contract.manager.ds.contract.model.ContractKind;
import com.ecep.contract.manager.ds.contract.model.ContractType;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.tasker.ContractFilesRebuildAllTasker;
import com.ecep.contract.manager.ds.contract.tasker.ContractRepairAllTasker;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ui.AbstManagerWindowController;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.UITools;
import javafx.event.ActionEvent;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableColumn;
import javafx.stage.Stage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/contract/contract-manager.fxml")
public class ContractManagerWindowController
extends AbstManagerWindowController<Contract, ContractViewModel, ContractManagerSkin> {
public ComboBox<ContractGroup> groupSelector;
public CheckBox composeViewBtn;
// columns
public TableColumn<ContractViewModel, Number> idColumn;
public TableColumn<ContractViewModel, String> nameColumn;
public TableColumn<ContractViewModel, String> codeColumn;
public TableColumn<ContractViewModel, ContractGroup> groupColumn;
public TableColumn<ContractViewModel, ContractType> typeColumn;
public TableColumn<ContractViewModel, ContractKind> kindColumn;
public TableColumn<ContractViewModel, String> parentCodeColumn;
public TableColumn<ContractViewModel, LocalDate> setupDateColumn;
public TableColumn<ContractViewModel, LocalDate> orderDateColumn;
public TableColumn<ContractViewModel, LocalDate> startDateColumn;
public TableColumn<ContractViewModel, Employee> employeeColumn;
public TableColumn<ContractViewModel, LocalDateTime> createdColumn;
public TableColumn<ContractViewModel, Number> amountColumn;
public TableColumn<ContractViewModel, Company> companyColumn;
@Autowired
private ContractService contractService;
@Override
public ContractService getViewModelService() {
return contractService;
}
@Override
protected ContractManagerSkin createDefaultSkin() {
ContractManagerSkin skin = new ContractManagerSkin(this);
skin.setContractService(contractService);
return skin;
}
@Override
public void show(Stage stage) {
super.show(stage);
getTitle().set("合同管理");
}
public void onVerifyAction(ActionEvent event) {
show(ContractVerifyWindowController.class, null);
}
public void onCreateNewContractAction(ActionEvent event) {
// getSkin().onTableCreateNewAction(event);
}
public void onContractFilesRebuildAction(ActionEvent event) {
ContractFilesRebuildAllTasker task = new ContractFilesRebuildAllTasker();
task.setContractService(contractService);
task.setGroup(groupSelector.getValue());
UITools.showTaskDialogAndWait("合同文件重置", task, null);
}
public void onContractRepairAllAction(ActionEvent event) {
ContractRepairAllTasker task = new ContractRepairAllTasker();
UITools.showTaskDialogAndWait("合同同步修复", task, null);
}
}

View File

@@ -0,0 +1,533 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.company.CompanyFileUtils;
import com.ecep.contract.manager.ds.company.CompanyStringConverter;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.ContractStringConverter;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractType;
import com.ecep.contract.manager.ds.contract.service.ExtendVendorInfoService;
import com.ecep.contract.manager.ds.contract.tasker.ContractRepairComm;
import com.ecep.contract.manager.ds.customer.controller.CompanyCustomerWindowController;
import com.ecep.contract.manager.ds.customer.model.CompanyCustomer;
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ds.project.controller.ProjectWindowController;
import com.ecep.contract.manager.ds.project.model.Project;
import com.ecep.contract.manager.ds.project.model.ProjectSaleType;
import com.ecep.contract.manager.ds.project.service.ProjectService;
import com.ecep.contract.manager.ds.project.service.ProjectStringConverter;
import com.ecep.contract.manager.ds.project.service.SaleTypeService;
import com.ecep.contract.manager.ds.vendor.controller.CompanyVendorWindowController;
import com.ecep.contract.manager.ds.vendor.model.CompanyVendor;
import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
import com.ecep.contract.manager.ds.vendor.service.VendorGroupService;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import com.ecep.contract.manager.util.UITools;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.stage.DirectoryChooser;
import javafx.util.StringConverter;
import javafx.util.converter.LocalDateStringConverter;
import javafx.util.converter.LocalDateTimeStringConverter;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;
import org.controlsfx.control.textfield.TextFields;
import org.controlsfx.glyphfont.Glyph;
import org.hibernate.Hibernate;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
*
*/
public class ContractTabSkinBase
extends AbstContractBasedTabSkin
implements TabSkin {
@Setter
private CompanyCustomerService companyCustomerService;
@Setter
private SaleTypeService saleTypeService;
@Setter
private ExtendVendorInfoService extendVendorInfoService;
@Setter
private VendorGroupService vendorGroupService;
public ContractTabSkinBase(ContractWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.baseInfoTab;
}
@Override
public void initializeTab() {
controller.openMainContractBtn.setOnAction(this::onContractOpenMainContractAction);
controller.contractRenameBtn.setOnAction(this::onContractRenameAction);
controller.contractPathCreateBtn.setOnAction(this::onContractCreatePathAction);
controller.contractPathChangeBtn.setOnAction(this::onContractChangePathAction);
controller.contractPathAsNameBtn.setOnAction(this::onContractPathSameAsNameAction);
controller.contractPathAsCodeBtn.setOnAction(this::onContractPathSameAsCodeAction);
controller.linkContractProjectBtn.setText(viewModel.getProject().get() == null ? "0" : "1");
controller.linkContractProjectBtn.textProperty().bind(viewModel.getProject().map(v -> {
return v == null ? "关联" : "打开";
}));
Glyph linkContractProjectBtnIcon = new Glyph("FontAwesome", viewModel.getProject().get() == null ? "UNLINK" : "LINK");
controller.linkContractProjectBtn.graphicProperty().set(linkContractProjectBtnIcon);
linkContractProjectBtnIcon.iconProperty().bind(viewModel.getProject().map(v -> {
return v == null ? "UNLINK" : "LINK";
}));
controller.linkContractProjectBtn.setOnAction(this::onLinkContractProjectAction);
controller.openMainContractBtn.disableProperty().bind(viewModel.getParentCode().isEmpty());
// 与主合同编码是否为空绑定按钮可以
controller.calcMainContractNoBtn.disableProperty().bind(viewModel.getParentCode().isNotEmpty());
controller.calcMainContractNoBtn.setOnAction(this::calcMainContractNoAction);
controller.payWayField.textProperty().bind(viewModel.getPayWay().map(ContractPayWay::getText));
controller.nameField.textProperty().bind(viewModel.getName());
controller.codeField.textProperty().bind(viewModel.getCode());
controller.parentCodeField.textProperty().bindBidirectional(viewModel.getParentCode());
parentCodeFieldAutoCompletion(controller.parentCodeField);
controller.stateField.textProperty().bind(viewModel.getState());
initializeBaseTabCompanyFieldAutoCompletion(controller.companyField);
controller.groupField.textProperty().bind(viewModel.getGroup().map(group -> {
if (!Hibernate.isInitialized(group)) {
group = getContractService().findGroupById(group.getId());
}
return group.getCode() + " " + group.getName() + " " + group.getTitle();
}));
controller.typeField.textProperty().bind(viewModel.getType().map(type -> {
if (!Hibernate.isInitialized(type)) {
type = getContractService().findTypeById(type.getId());
}
return type.getCode() + " " + type.getCatalog() + " " + type.getName() + " " + type.getTitle() + "(" + type.getDirection() + ")";
}));
controller.kindField.textProperty().bind(viewModel.getKind().map(kind -> {
if (!Hibernate.isInitialized(kind)) {
kind = getContractService().findKindById(kind.getId());
}
return kind.getCode() + " " + kind.getName() + " " + kind.getTitle();
}));
// as customer
controller.openRelativeCompanyCustomerBtn.setOnAction(this::onContractOpenRelativeCompanyCustomerAction);
controller.openRelativeCompanyCustomerBtn.disableProperty().bind(Bindings.createBooleanBinding(() -> {
ContractType type = viewModel.getType().get();
if (type == null) {
return true;
}
Company company = viewModel.getCompany().get();
if (company == null) {
return true;
}
if (!Hibernate.isInitialized(type)) {
type = getContractService().findTypeById(type.getId());
}
return !Objects.equals(type.getDirection(), "");
}, viewModel.getType()));
controller.openRelativeCompanyCustomerBtn.managedProperty().bind(controller.openRelativeCompanyCustomerBtn.disabledProperty().not());
controller.openRelativeCompanyCustomerBtn.visibleProperty().bind(controller.openRelativeCompanyCustomerBtn.managedProperty());
// as vendor
controller.openRelativeCompanyVendorBtn.setOnAction(this::onContractOpenRelativeCompanyVendorAction);
controller.openRelativeCompanyVendorBtn.disableProperty().bind(Bindings.createBooleanBinding(() -> {
ContractType type = viewModel.getType().get();
if (type == null) {
return true;
}
Company company = viewModel.getCompany().get();
if (company == null) {
return true;
}
if (!Hibernate.isInitialized(type)) {
type = getContractService().findTypeById(type.getId());
}
return !Objects.equals(type.getDirection(), "");
}, viewModel.getType()));
controller.openRelativeCompanyVendorBtn.managedProperty().bind(controller.openRelativeCompanyVendorBtn.disabledProperty().not());
controller.openRelativeCompanyVendorBtn.visibleProperty().bind(controller.openRelativeCompanyVendorBtn.managedProperty());
LocalDateStringConverter localDateStringConverter = controller.localDateStringConverter;
controller.setupDateField.setConverter(localDateStringConverter);
controller.setupDateField.valueProperty().bindBidirectional(viewModel.getSetupDate());
controller.startDateField.setConverter(localDateStringConverter);
controller.startDateField.valueProperty().bindBidirectional(viewModel.getStartDate());
controller.endDateField.setConverter(localDateStringConverter);
controller.endDateField.valueProperty().bindBidirectional(viewModel.getEndDate());
controller.orderDateField.setConverter(localDateStringConverter);
controller.orderDateField.valueProperty().bindBidirectional(viewModel.getOrderDate());
controller.inureDateField.setConverter(localDateStringConverter);
controller.inureDateField.valueProperty().bindBidirectional(viewModel.getInureDate());
controller.varyDateField.setConverter(localDateStringConverter);
controller.varyDateField.valueProperty().bindBidirectional(viewModel.getVaryDate());
EmployeeStringConverter employeeStringConverter = SpringApp.getBean(EmployeeStringConverter.class);
UITools.autoCompletion(controller.setupPersonField, viewModel.getSetupPerson(),
employeeStringConverter::suggest, employeeStringConverter);
UITools.autoCompletion(controller.inurePersonField, viewModel.getInurePerson(),
employeeStringConverter::suggest, employeeStringConverter);
UITools.autoCompletion(controller.varyPersonField, viewModel.getVaryPerson(),
employeeStringConverter::suggest, employeeStringConverter);
UITools.autoCompletion(controller.employeeField, viewModel.getEmployee(),
employeeStringConverter::suggest, employeeStringConverter);
UITools.autoCompletion(controller.handlerField, viewModel.getHandler(),
employeeStringConverter::suggest, employeeStringConverter);
initializeBaseTabProjectFieldAutoCompletion(controller.projectField);
controller.pathField.textProperty().bind(viewModel.getPath());
// controller.createdField.textProperty().bind(viewModel.getCreated().map(MyDateTimeUtils::format));
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(MyDateTimeUtils.DEFAULT_DATETIME_FORMAT_PATTERN);
controller.createdField.textProperty().bindBidirectional(viewModel.getCreated(), new LocalDateTimeStringConverter(dateTimeFormatter, null));
controller.guidField.textProperty().bind(viewModel.getGuid());
controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());
NumberStringConverter numberStringConverter = new NumberStringConverter(controller.getLocale(), "#,##0.00");
controller.amountField.textProperty().bindBidirectional(viewModel.getAmount(), numberStringConverter);
controller.totalQuantityField.textProperty().bindBidirectional(viewModel.getTotalQuantity(), numberStringConverter);
controller.totalAmountField.textProperty().bindBidirectional(viewModel.getTotalAmount(), numberStringConverter);
controller.totalUnTaxAmountField.textProperty().bindBidirectional(viewModel.getTotalUnTaxAmount(), numberStringConverter);
controller.execQuantityField.textProperty().bindBidirectional(viewModel.getExecQuantity(), numberStringConverter);
controller.execAmountField.textProperty().bindBidirectional(viewModel.getExecAmount(), numberStringConverter);
controller.execUnTaxAmountField.textProperty().bindBidirectional(viewModel.getExecUnTaxAmount(), numberStringConverter);
controller.versionLabel.textProperty().bind(viewModel.getVersion().asString());
}
private void parentCodeFieldAutoCompletion(TextField textField) {
ContractStringConverter converter = SpringApp.getBean(ContractStringConverter.class);
converter.setFormater(Contract::getCode);
TextFields.bindAutoCompletion(textField, converter::suggest, converter);
}
private void calcMainContractNoAction(ActionEvent event) {
try {
Contract contract = controller.getEntity();
if (getContractService().updateParentCode(contract)) {
save(contract);
}
} catch (NoSuchElementException e) {
viewModel.getParentCode().set(e.getMessage());
}
}
public void onLinkContractProjectAction(ActionEvent event) {
Project project = viewModel.getProject().get();
if (project != null) {
ProjectWindowController.show(project, null);
return;
}
String code = viewModel.getParentCode().get();
if (!StringUtils.hasText(code)) {
code = viewModel.getCode().get();
if (code.contains("-")) {
code = code.substring(0, code.indexOf("-"));
}
if (!StringUtils.hasText(code)) {
setStatus("未设置合同编号, 无法关联项目");
return;
}
}
project = getProjectService().findByCode(code);
if (project == null) {
if (code.contains("-")) {
setStatus("未找到关联项目");
return;
}
project = new Project();
String name = viewModel.getName().get();
if (StringUtils.hasText(name)) {
project.setName(name);
}
getProjectService().applyCode(project, code);
// 设置项目的开始创建时间,从合同的创建时间、提交日期、开始日期中取最早的日期
List<LocalDate> dates = new ArrayList<>();
if (viewModel.getCreated().get() != null) {
dates.add(viewModel.getCreated().get().toLocalDate());
}
if (viewModel.getSetupDate().get() != null) {
dates.add(viewModel.getSetupDate().get());
}
if (viewModel.getStartDate().get() != null) {
dates.add(viewModel.getStartDate().get());
}
dates.stream().min(LocalDate::compareTo).ifPresent(project::setCreated);
Employee applicant = viewModel.getEmployee().get();
if (applicant != null) {
project.setApplicant(applicant);
}
if (viewModel.getAmount().get() > 0) {
project.setAmount((int) viewModel.getAmount().get());
}
project = getProjectService().save(project);
}
viewModel.getProject().set(project);
save();
}
public void onContractRenameAction(ActionEvent event) {
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("合同名称变更");
dialog.setHeaderText("请输入变更的合同名称");
dialog.setContentText(controller.nameField.getText());
Optional<String> result = dialog.showAndWait();
if (result.isPresent()) {
System.out.println("You entered: " + result.get());
} else {
System.out.println("No input provided.");
}
}
public void onContractOpenMainContractAction(ActionEvent event) {
String parentCode = viewModel.getParentCode().get();
Contract parent = getContractService().findByCode(parentCode);
if (parent == null) {
UITools.showAlertAndWait("没有找到上级合同:" + parentCode);
return;
}
ContractWindowController.show(parent, controller.root.getScene().getWindow());
}
/**
* 创建合同存储目录
*/
public void onContractCreatePathAction(ActionEvent event) {
Contract contract = getEntity();
ContractRepairComm comm = new ContractRepairComm();
if (CompanyFileUtils.exists(contract.getPath())) {
File dir = new File(contract.getPath());
if (!dir.exists()) {
dir = comm.makePath(contract, (level, message) -> controller.setStatus(message));
contract.setPath(dir.getAbsolutePath());
save(contract);
}
}
if (comm.makePathAbsent(contract, (level, message) -> controller.setStatus(message))) {
save(contract);
} else {
controller.setStatus("目录存在或创建失败");
}
}
public void onContractChangePathAction(ActionEvent event) {
DirectoryChooser chooser = new DirectoryChooser();
Contract entity = getEntity();
String path = entity.getPath();
File initialDirectory = null;
// 如果当前已经设置了目录并且路径有效,则设置初始目录为该目录
if (StringUtils.hasText(path)) {
File dir = new File(path);
if (dir.exists()) {
initialDirectory = dir;
}
}
if (initialDirectory == null) {
if (entity.getPayWay() == ContractPayWay.RECEIVE) {
// 根据项目设置初始目录
Project project = entity.getProject();
if (project != null) {
if (!Hibernate.isInitialized(project)) {
project = getProjectService().findById(project.getId());
}
// 根据项目销售方式设置初始目录
ProjectSaleType saleType = project.getSaleType();
if (saleType != null) {
if (!Hibernate.isInitialized(saleType)) {
saleType = getSaleTypeService().findById(saleType.getId());
}
File dir = new File(saleType.getPath());
if (saleType.isStoreByYear()) {
dir = new File(dir, "20" + project.getCodeYear());
}
initialDirectory = dir;
}
}
} else if (entity.getPayWay() == ContractPayWay.PAY) {
// 根据上级合同设置初始目录
String parentCode = entity.getParentCode();
if (StringUtils.hasText(parentCode)) {
Contract parent = getContractService().findByCode(parentCode);
if (parent != null) {
if (StringUtils.hasText(parent.getPath())) {
File dir = new File(parent.getPath());
if (dir.exists()) {
initialDirectory = dir;
}
}
}
}
}
if (initialDirectory == null) {
initialDirectory = getContractService().getBasePath();
}
}
if (initialDirectory != null) {
chooser.setInitialDirectory(initialDirectory);
}
File newDirectory = chooser.showDialog(getTab().getContent().getScene().getWindow());
if (newDirectory != null) {
entity.setPath(newDirectory.getAbsolutePath());
save(entity);
}
}
public void onContractPathSameAsNameAction(ActionEvent event) {
Contract contract = getEntity();
String path = contract.getPath();
if (!StringUtils.hasText(path)) {
return;
}
File file = new File(path);
if (!file.exists()) {
return;
}
if (file.getName().equals(contract.getName())) {
return;
}
File dest = new File(file.getParent(), contract.getName());
if (file.renameTo(dest)) {
contract.setPath(dest.getAbsolutePath());
save(contract);
controller.setStatus("目录变更为" + dest.getName());
}
}
public void onContractPathSameAsCodeAction(ActionEvent event) {
Contract contract = getEntity();
String path = contract.getPath();
if (!StringUtils.hasText(path)) {
return;
}
File file = new File(path);
if (!file.exists()) {
return;
}
if (file.getName().equals(contract.getCode())) {
return;
}
File dest = new File(file.getParent(), contract.getCode());
if (file.renameTo(dest)) {
contract.setPath(dest.getAbsolutePath());
save(contract);
controller.setStatus("目录变更为" + dest.getName());
}
}
public void onContractOpenRelativeCompanyCustomerAction(ActionEvent event) {
Contract contract = getEntity();
Company company = contract.getCompany();
CompanyCustomer companyCustomer = getCompanyCustomerService().findByCompany(company);
CompanyCustomerWindowController.show(companyCustomer, null);
}
public void onContractOpenRelativeCompanyVendorAction(ActionEvent event) {
Contract contract = getEntity();
Company company = contract.getCompany();
CompanyVendorService service = SpringApp.getBean(CompanyVendorService.class);
CompanyVendor companyVendor = service.findByCompany(company);
CompanyVendorWindowController.show(companyVendor, null);
}
private void initializeBaseTabCompanyFieldAutoCompletion(TextField textField) {
CompanyStringConverter converter = SpringApp.getBean(CompanyStringConverter.class);
UITools.autoCompletion(textField, viewModel.getCompany(), converter);
}
private void initializeBaseTabProjectFieldAutoCompletion(TextField textField) {
ProjectStringConverter converter = SpringApp.getBean(ProjectStringConverter.class);
StringConverter<Project> stringConverter = new StringConverter<>() {
@Override
public String toString(Project object) {
Project project = converter.prefixObject(object);
if (project == null) {
return "";
}
return project.getCode();
}
@Override
public Project fromString(String string) {
return converter.fromString(string);
}
};
converter.setFormater(Project::getCode);
UITools.autoCompletion(textField, viewModel.getProject(), converter::suggest, stringConverter);
}
public CompanyCustomerService getCompanyCustomerService() {
if (companyCustomerService == null) {
companyCustomerService = SpringApp.getBean(CompanyCustomerService.class);
}
return companyCustomerService;
}
public ProjectService getProjectService() {
return controller.projectService;
}
public SaleTypeService getSaleTypeService() {
if (saleTypeService == null) {
saleTypeService = SpringApp.getBean(SaleTypeService.class);
}
return saleTypeService;
}
public ExtendVendorInfoService getExtendVendorInfoService() {
if (extendVendorInfoService == null) {
extendVendorInfoService = SpringApp.getBean(ExtendVendorInfoService.class);
}
return extendVendorInfoService;
}
public VendorGroupService getVendorGroupService() {
if (vendorGroupService == null) {
vendorGroupService = SpringApp.getBean(VendorGroupService.class);
}
return vendorGroupService;
}
}

View File

@@ -0,0 +1,157 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ExtendVendorInfo;
import com.ecep.contract.manager.ds.contract.service.ExtendVendorInfoService;
import com.ecep.contract.manager.ds.contract.vo.ExtendVendorInfoViewModel;
import com.ecep.contract.manager.ds.vendor.model.VendorGroup;
import com.ecep.contract.manager.ds.vendor.service.VendorGroupService;
import com.ecep.contract.manager.ui.ComboBoxUtils;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.util.UITools;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.scene.control.*;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;
import org.hibernate.Hibernate;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@FxmlPath("/ui/contract/contract-tab-ext-vendor-info.fxml")
public class ContractTabSkinExtendVendorInfo
extends AbstContractBasedTabSkin
implements TabSkin {
@Setter
private ExtendVendorInfoService extendVendorInfoService;
@Setter
private VendorGroupService vendorGroupService;
public ComboBox<VendorGroup> vendorGroupField;
public Label vendorGroupLabel;
public TextField sequenceNumberField;
public CheckBox assignedProviderField;
public CheckBox prePurchaseField;
CompletableFuture<ExtendVendorInfo> loadedFuture;
private ExtendVendorInfoViewModel viewModel = new ExtendVendorInfoViewModel();
public ContractTabSkinExtendVendorInfo(ContractWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.extendVendorInfo;
}
@Override
public void initializeUIComponents() {
super.initializeUIComponents();
listenTabSelectionChanged();
}
@Override
public BooleanProperty changeProperty() {
return viewModel.getChanged();
}
@Override
public void onTabShown() {
if (loadedFuture == null) {
loadedFuture = CompletableFuture.supplyAsync(() -> {
initializeTab();
Contract contract = getEntity();
return loadExtendVendorInfo(contract);
});
}
}
void updateViewModel(ExtendVendorInfo info) {
if (Platform.isFxApplicationThread()) {
viewModel.update(info);
} else {
Platform.runLater(() -> viewModel.update(info));
}
}
private ExtendVendorInfo loadExtendVendorInfo(Contract contract) {
ExtendVendorInfoService service = getExtendVendorInfoService();
try {
ExtendVendorInfo info = service.findByContract(contract);
if (info == null) {
info = service.newInstanceByContract(contract);
info = service.save(info);
}
updateViewModel(info);
viewModel.bindListener();
return info;
} catch (Exception e) {
UITools.showExceptionAndWait("加载成本时发生错误", e);
throw e;
}
}
@Override
public void initializeTab() {
List<VendorGroup> groups = getVendorGroupService().findAll();
ComboBoxUtils.initialComboBox(vendorGroupField, groups, true);
vendorGroupField.valueProperty().bindBidirectional(viewModel.getGroup());
vendorGroupLabel.textProperty().bind(vendorGroupField.valueProperty().map(v -> {
if (v == null) {
return "-";
}
if (!Hibernate.isInitialized(v)) {
v = getVendorGroupService().findById(v.getId());
viewModel.getGroup().set(v);
}
return v.getDescription();
}));
sequenceNumberField.textProperty().bindBidirectional(viewModel.getCodeSequenceNumber(), new NumberStringConverter());
assignedProviderField.selectedProperty().bindBidirectional(viewModel.getAssignedProvider());
assignedProviderField.disableProperty().bind(Bindings.createBooleanBinding(() -> {
VendorGroup group = viewModel.getGroup().get();
if (group == null) {
return false;
}
return !group.isPriceComparison();
}, viewModel.getGroup()));
prePurchaseField.selectedProperty().bindBidirectional(viewModel.getPrePurchase());
}
@Override
public void save() {
if (loadedFuture != null) {
ExtendVendorInfo vendorInfo = loadedFuture.join();
if (viewModel.copyTo(vendorInfo)) {
ExtendVendorInfo saved = getExtendVendorInfoService().save(vendorInfo);
updateViewModel(saved);
loadedFuture = CompletableFuture.completedFuture(saved);
}
}
}
public ExtendVendorInfoService getExtendVendorInfoService() {
if (extendVendorInfoService == null) {
extendVendorInfoService = SpringApp.getBean(ExtendVendorInfoService.class);
}
return extendVendorInfoService;
}
public VendorGroupService getVendorGroupService() {
if (vendorGroupService == null) {
vendorGroupService = SpringApp.getBean(VendorGroupService.class);
}
return vendorGroupService;
}
}

View File

@@ -0,0 +1,820 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.Desktop;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.cloud.u8.ctx.ContractCtx;
import com.ecep.contract.manager.ds.company.CompanyFileUtils;
import com.ecep.contract.manager.ds.contract.ContractFileType;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractFile;
import com.ecep.contract.manager.ds.contract.model.ContractFileTypeLocal;
import com.ecep.contract.manager.ds.contract.model.ContractType;
import com.ecep.contract.manager.ds.contract.service.ContractFileService;
import com.ecep.contract.manager.ds.contract.tasker.ContractFilesRebuildTasker;
import com.ecep.contract.manager.ds.contract.tasker.CustomerContractCostFormUpdateTask;
import com.ecep.contract.manager.ds.contract.vo.ContractFileViewModel;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.util.LocalDateFieldTableCell;
import com.ecep.contract.manager.util.MyDateTimeUtils;
import com.ecep.contract.manager.util.UITools;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.stage.WindowEvent;
import javafx.util.StringConverter;
import lombok.Setter;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.io.RandomAccessStreamCache;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.multipdf.Splitter;
import org.apache.pdfbox.pdfwriter.compress.CompressParameters;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.springframework.util.StringUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 合同文件
*/
@FxmlPath("/ui/contract/contract-tab-file.fxml")
public class ContractTabSkinFiles
extends AbstContractTableTabSkin<ContractFile, ContractFileViewModel>
implements TabSkin, EditableEntityTableTabSkin<ContractFile, ContractFileViewModel> {
public Button fileTableReBuildBtn;
public MenuItem fileTable_menu_refresh;
public MenuItem fileTable_menu_del;
public Menu fileTable_menu_pdf;
public Menu fileTable_menu_update;
public Menu fileTable_menu_change_type;
public Menu fileTable_menu_change_type_and_name;
public TableColumn<ContractFileViewModel, Number> fileTable_idColumn;
public TableColumn<ContractFileViewModel, ContractFileTypeLocal> fileTable_typeColumn;
public TableColumn<ContractFileViewModel, String> fileTable_filePathColumn;
public TableColumn<ContractFileViewModel, LocalDate> fileTable_applyDateColumn;
public TableColumn<ContractFileViewModel, String> fileTable_descriptionColumn;
@Setter
private ContractFileService contractFileService;
private final ObservableMap<ContractFileType, ContractFileTypeLocal> fileTypeLocalMap = FXCollections.observableHashMap();
public ContractTabSkinFiles(ContractWindowController controller) {
super(controller);
setDragAndDrop(true);
setDragAndDropFileHandler(this::moveFileToCustomer);
}
@Override
protected ContractFileService getViewModelService() {
return getContractFileService();
}
public ContractFileService getContractFileService() {
if (contractFileService == null) {
contractFileService = SpringApp.getBean(ContractFileService.class);
}
return contractFileService;
}
@Override
public Tab getTab() {
return controller.fileTab;
}
static class ContractFileTypeLocalStringConverter extends StringConverter<ContractFileTypeLocal> {
@Override
public String toString(ContractFileTypeLocal local) {
if (local == null) {
return "-";
}
return local.getValue();
}
@Override
public ContractFileTypeLocal fromString(String string) {
return null;
}
}
@Override
public void initializeTab() {
TableView<ContractFileViewModel> table = getTableView();
ContractPayWay payWay = viewModel.getPayWay().get();
ContractType contractType = viewModel.getType().get();
boolean isCustomer = payWay == ContractPayWay.RECEIVE;
boolean isVendor = payWay == ContractPayWay.PAY;
fileTable_menu_refresh.setOnAction(this::onTableRefreshAction);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.getContextMenu().setOnShowing(this::onFileTableContextMenuShowing);
fileTableReBuildBtn.setOnAction(this::onFileReBuildingAction);
fileTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
fileTable_idColumn.setEditable(false);
fileTable_idColumn.setReorderable(false);
fileTable_typeColumn.setCellValueFactory(param -> Bindings.valueAt(fileTypeLocalMap, param.getValue().getType()));
fileTable_typeColumn.setCellFactory(param -> new TextFieldTableCell<>(new ContractFileTypeLocalStringConverter()));
// 监听 type map 变化
fileTypeLocalMap.addListener((MapChangeListener<? super ContractFileType, ? super ContractFileTypeLocal>) change -> {
List<ContractFileTypeLocal> types = fileTypeLocalMap.values().stream().filter(typeLocal -> {
ContractFileType type = typeLocal.getType();
if (type == null) {
return false;
}
if (isCustomer && !type.isSupportCustomer()) {
return false;
}
return !isVendor || type.isSupportVendor();
}).toList();
fileTable_menu_change_type.getItems().setAll(types.stream()
.map(typeLocal -> {
MenuItem item = new MenuItem();
item.setText(typeLocal.getValue());
item.getProperties().put("typeLocal", typeLocal);
item.setOnAction(this::onFileTableContextMenuChangeTypeAndNameAction);
return item;
}).toList());
fileTable_menu_change_type_and_name.getItems().setAll(types.stream()
.filter(typeLocal -> StringUtils.hasText(typeLocal.getSuggestFileName()))
.map(typeLocal -> {
MenuItem item = new MenuItem();
item.setText(typeLocal.getValue());
item.getProperties().put("typeLocal", typeLocal);
item.getProperties().put("rename", true);
item.setOnAction(this::onFileTableContextMenuChangeTypeAndNameAction);
return item;
}).toList());
});
fileTable_typeColumn.setEditable(false);
/* 文件名编辑器 */
fileTable_filePathColumn.setCellValueFactory(param -> param.getValue().getFileName());
fileTable_filePathColumn.setCellFactory(TextFieldTableCell.forTableColumn());
fileTable_filePathColumn.setEditable(true);
fileTable_filePathColumn.setOnEditCommit(this::onFilePathColumnEditCommitAction);
/* 日期编辑器 */
fileTable_applyDateColumn.setCellValueFactory(param -> param.getValue().getApplyDate());
fileTable_applyDateColumn.setCellFactory(LocalDateFieldTableCell.forTableColumn());
fileTable_applyDateColumn.setEditable(true);
fileTable_applyDateColumn.setOnEditCommit(this::onFileTableApplyDateColumnEditCommitAction);
/* 备注编辑器 */
fileTable_descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
fileTable_descriptionColumn.setCellFactory(TextFieldTableCell.forTableColumn());
fileTable_descriptionColumn.setEditable(true);
fileTable_descriptionColumn.setOnEditCommit(this::onFileTableDescriptionColumnEditCommitAction);
table.setEditable(true);
fileTable_menu_del.setOnAction(this::onTableDeleteAction);
MenuItem composePdfMenu = createComposePdfMenu();
MenuItem splitPDFMenu = createSplitPDFMenu();
fileTable_menu_pdf.getItems().setAll(splitPDFMenu, composePdfMenu);
fileTable_menu_pdf.setOnMenuValidation(e -> {
splitPDFMenu.setDisable(true);
composePdfMenu.setVisible(false);
SelectionMode selectionMode = table.getSelectionModel().getSelectionMode();
// 是否多选
if (table.getSelectionModel().getSelectedItems().size() > 1) {
// 多选时启用合并菜单
if (selectionMode == SelectionMode.MULTIPLE) {
composePdfMenu.setVisible(true);
}
} else {
ContractFileViewModel selectedItem = table.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
String extension = StringUtils.getFilenameExtension(selectedItem.getFileName().get());
splitPDFMenu.setDisable(extension == null || !extension.equals("pdf"));
}
}
});
// 当 菜单 onShowing 时触发
fileTable_menu_change_type.setOnMenuValidation(e -> {
System.out.println("fileTable_menu_change_type:setOnMenuValidation");
});
// 当 菜单 onShowing 时触发
fileTable_menu_change_type_and_name.setOnMenuValidation(e -> {
System.out.println("fileTable_menu_change_type_and_name:setOnMenuValidation");
});
fileTable_menu_update.getItems().setAll(
createCustomerContractCostByTemplateUpdateMenuItem(),
createCustomerContractBidByTemplateUpdateMenuItem(),
createCustomerContractApplyByTemplateUpdateMenuItem(),
createVendorContractRequestByTemplateUpdateMenuItem(),
createVendorContractApplyByTemplateUpdateMenuItem()
);
fileTypeLocalMap.putAll(getContractFileService().findAllFileTypes(getLocale().toLanguageTag()));
super.initializeTab();
}
private MenuItem createSplitPDFMenu() {
MenuItem item = new MenuItem();
item.setText("拆分PDF");
item.setOnAction(this::onFileTableSplitPDFAction);
return item;
}
private MenuItem createComposePdfMenu() {
MenuItem item = new MenuItem();
item.setText("合并PDF");
item.setOnAction(this::onFileTableComposePDFAction_V2);
return item;
}
/**
* 合并PDF
*
* @param event 菜单事件
*/
private void onFileTableComposePDFAction(ActionEvent event) {
Contract contract = getParent();
if (!StringUtils.hasText(contract.getPath())) {
setStatus("合同未设置路径");
return;
}
File contractPath = new File(contract.getPath());
if (!contractPath.exists()) {
setStatus("合同路径不存在,请检查");
return;
}
ObservableList<ContractFileViewModel> selectedItems = getTableView().getSelectionModel().getSelectedItems();
if (selectedItems.isEmpty()) {
setStatus("请选择文件");
return;
}
List<ContractFileViewModel> rows = selectedItems.stream().filter(selectedItem -> {
String fileName = selectedItem.getFileName().get();
if (!StringUtils.hasText(fileName)) {
return false;
}
File file = new File(contractPath, fileName);
return file.exists();
}).toList();
if (rows.isEmpty()) {
setStatus("请选择PDF文件");
return;
}
PDFMergerUtility merger = new PDFMergerUtility();
File dest = new File(contractPath, "合并的" + rows.getFirst().getFileName().get());
merger.setDestinationFileName(dest.getAbsolutePath());
for (ContractFileViewModel row : rows) {
try {
File file = new File(contractPath, row.getFileName().get());
String extension = StringUtils.getFilenameExtension(file.getName());
if (!"pdf".equalsIgnoreCase(extension)) {
merger.addSource(file);
} else {
if (!"jpg".equalsIgnoreCase(extension)) {
PDDocument document = new PDDocument();
}
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
try {
merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly().streamCache); // null
} catch (IOException e) {
throw new RuntimeException(e);
}
ContractFileViewModel append = new ContractFileViewModel();
append.getContract().set(contract);
append.getFileName().set(dest.getName());
append.getType().set(ContractFileType.General);
saveRow(append);
getTableView().getItems().add(append);
for (ContractFileViewModel row : rows) {
if (deleteRow(row, false)) {
getTableView().getItems().remove(row);
}
}
}
private void onFileTableComposePDFAction_V2(ActionEvent event) {
Contract contract = getParent();
if (!StringUtils.hasText(contract.getPath())) {
setStatus("合同未设置路径");
return;
}
File contractPath = new File(contract.getPath());
if (!contractPath.exists()) {
setStatus("合同路径不存在,请检查");
return;
}
ObservableList<ContractFileViewModel> selectedItems = getTableView().getSelectionModel().getSelectedItems();
if (selectedItems.isEmpty()) {
setStatus("请选择文件");
return;
}
List<ContractFileViewModel> rows = selectedItems.stream().filter(selectedItem -> {
String fileName = selectedItem.getFileName().get();
if (!StringUtils.hasText(fileName)) {
return false;
}
File file = new File(contractPath, fileName);
return file.exists();
}).toList();
if (rows.isEmpty()) {
setStatus("请选择PDF文件");
return;
}
List<File> files = rows.stream().map(v -> new File(contractPath, v.getFileName().get())).toList();
PDFMergerUtility merger = new PDFMergerUtility();
File dest = new File(contractPath, "合并的" + stripFilename(files.getFirst()) + ".pdf");
String[] imageReaderFormats = null;
List<PDDocument> tobeClosed = new ArrayList<>();
RandomAccessStreamCache.StreamCacheCreateFunction createFunction = IOUtils.createMemoryOnlyStreamCache();
try (PDDocument destination = new PDDocument(createFunction)) {
for (File file : files) {
String extension = StringUtils.getFilenameExtension(file.getName());
if ("pdf".equalsIgnoreCase(extension)) {
PDDocument doc = Loader.loadPDF(file);
tobeClosed.add(doc);
merger.appendDocument(destination, doc);
} else {
if (imageReaderFormats == null) {
imageReaderFormats = ImageIO.getReaderFormatNames();
}
boolean found = false;
for (String format : imageReaderFormats) {
if (format.equals(extension)) {
found = true;
break;
}
}
if (!found) {
continue;
}
PDPage page = new PDPage();
// 加载 PNG 图片
BufferedImage image = ImageIO.read(file);
// 将图片添加到 PDF
try (PDPageContentStream contentStream =
new PDPageContentStream(destination, page)) {
PDImageXObject pdImage = LosslessFactory.createFromImage(destination, image);
float scale = 1f; // 图片缩放比例
contentStream.drawImage(pdImage, 0, 0,
pdImage.getWidth() * scale,
pdImage.getHeight() * scale);
}
destination.addPage(page);
}
}
destination.save(dest, CompressParameters.DEFAULT_COMPRESSION);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
for (PDDocument doc : tobeClosed) {
IOUtils.closeQuietly(doc);
}
}
ContractFileViewModel append = new ContractFileViewModel();
append.getContract().set(contract);
append.getFileName().set(dest.getName());
append.getType().set(ContractFileType.General);
saveRow(append);
getTableView().getItems().add(append);
for (ContractFileViewModel row : rows) {
if (deleteRow(row, false)) {
getTableView().getItems().remove(row);
}
}
}
private String stripFilename(File file) {
String filename = file.getName();
String extension = StringUtils.getFilenameExtension(filename);
if (extension == null) {
return filename;
}
return filename.substring(0, filename.length() - (extension.length() + 1));
}
private MenuItem createVendorContractRequestByTemplateUpdateMenuItem() {
MenuItem item = new MenuItem();
item.setText("采购与服务申请表");
item.visibleProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.PAY));
return item;
}
private MenuItem createVendorContractApplyByTemplateUpdateMenuItem() {
MenuItem item = new MenuItem();
item.setText("采购合同审批表");
item.visibleProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.PAY));
return item;
}
private MenuItem createCustomerContractApplyByTemplateUpdateMenuItem() {
MenuItem item = new MenuItem();
item.setText("销售合同审批表");
item.visibleProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.RECEIVE));
return item;
}
private MenuItem createCustomerContractBidByTemplateUpdateMenuItem() {
MenuItem item = new MenuItem();
item.setText("投标报价审批表");
item.visibleProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.RECEIVE));
return item;
}
private MenuItem createCustomerContractCostByTemplateUpdateMenuItem() {
MenuItem item = new MenuItem();
item.setText("成本核算审批表");
item.visibleProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.RECEIVE));
item.setOnAction(event -> {
Contract contract = getContractService().findById(viewModel.getId().get());
if (contract == null) {
setStatus("异常,对应的合同不存在#" + viewModel.getId().get());
return;
}
if (!StringUtils.hasText(contract.getPath())) {
setStatus("合同目录未创建");
return;
}
String template = controller.getConfService().getString(ContractFileService.KEY_CUSTOMER_COST_TEMPLATE);
if (!StringUtils.hasText(template)) {
setStatus("模板文件未配置");
return;
}
ContractFileViewModel model = dataSet.stream()
.filter(v -> v.getType().get().equals(ContractFileType.Cost))
.findFirst().orElse(null);
if (model == null) {
ContractFile file = new ContractFile();
file.setContract(contract);
file.setType(ContractFileType.Cost);
file.setApplyDate(LocalDate.now());
String fileName = item.getText();
ContractFileTypeLocal local = fileTypeLocalMap.get(ContractFileType.CostForm);
if (local != null) {
if (StringUtils.hasText(local.getSuggestFileName())) {
fileName = local.getSuggestFileName();
}
}
String dest = contract.getCode() + "-" + fileName + "." + StringUtils.getFilenameExtension(template);
file.setFileName(dest);
file = getContractFileService().save(file);
model = new ContractFileViewModel();
model.update(file);
dataSet.add(model);
}
CustomerContractCostFormUpdateTask task = new CustomerContractCostFormUpdateTask();
task.setContract(contract);
task.setTemplate(template);
task.setFileName(model.getFileName().get());
task.setApplyDate(model.getApplyDate().get());
UITools.showTaskDialogAndWait("更新 " + model.getFileName().get(), task, null);
});
return item;
}
private void onFileTableDescriptionColumnEditCommitAction(TableColumn.CellEditEvent<ContractFileViewModel, String> event) {
acceptCellEditEvent(event, ContractFileViewModel::getDescription);
}
private void onFileTableApplyDateColumnEditCommitAction(TableColumn.CellEditEvent<ContractFileViewModel, LocalDate> event) {
acceptCellEditEvent(event, ContractFileViewModel::getApplyDate);
}
private void onFilePathColumnEditCommitAction(TableColumn.CellEditEvent<ContractFileViewModel, String> event) {
ContractFileViewModel row = event.getRowValue();
File src = new File(viewModel.getPath().get(), row.getFileName().get());
File desc = new File(viewModel.getPath().get(), event.getNewValue());
if (!src.exists()) {
setStatus("原文件不存在, " + src.getAbsolutePath());
return;
}
if (desc.exists()) {
setStatus("目标文件已存在, " + desc.getAbsolutePath());
return;
}
if (src.renameTo(desc)) {
acceptCellEditEvent(event, ContractFileViewModel::getFileName);
}
}
@Override
protected void onTableRowDoubleClickedAction(ContractFileViewModel item) {
String parent = viewModel.getPath().get();
if (!CompanyFileUtils.exists(parent)) {
setStatus("合同的目录未设置或者无效,请检查!");
return;
}
File file = new File(parent, item.getFileName().get());
if (!file.exists()) {
setStatus("文件不存在 " + file.getName());
return;
}
Desktop.showInExplorer(file);
}
public void onFileTableContextMenuShowing(WindowEvent windowEvent) {
ContextMenu contextMenu = (ContextMenu) windowEvent.getSource();
ContractFileViewModel selectedItem = getSelectedItem();
if (selectedItem == null) {
// 未选择行
windowEvent.consume();
//contextMenu.hide();
fileTable_menu_del.setVisible(false);
fileTable_menu_change_type.setVisible(false);
fileTable_menu_change_type_and_name.setVisible(false);
return;
}
fileTable_menu_del.setVisible(true);
//
fileTable_menu_change_type.setVisible(true);
for (MenuItem item : fileTable_menu_change_type.getItems()) {
ContractFileTypeLocal typeLocal = (ContractFileTypeLocal) item.getProperties().get("typeLocal");
item.setVisible(typeLocal.getType() != selectedItem.getType().get());
}
fileTable_menu_change_type_and_name.setVisible(true);
for (MenuItem item : fileTable_menu_change_type.getItems()) {
ContractFileTypeLocal typeLocal = (ContractFileTypeLocal) item.getProperties().get("typeLocal");
item.setVisible(typeLocal.getType() != selectedItem.getType().get());
}
}
private void onFileTableContextMenuChangeTypeAndNameAction(ActionEvent event) {
MenuItem item = (MenuItem) event.getSource();
ObservableList<ContractFileViewModel> selectedItems = getTableView().getSelectionModel().getSelectedItems();
if (selectedItems == null || selectedItems.isEmpty()) {
return;
}
ContractFileTypeLocal typeLocal = (ContractFileTypeLocal) item.getProperties().get("typeLocal");
if (typeLocal == null) {
return;
}
for (ContractFileViewModel selectedItem : selectedItems) {
if (typeLocal.getType() == selectedItem.getType().get()) {
continue;
}
Boolean rename = (Boolean) item.getProperties().get("rename");
String suggestFileName = typeLocal.getSuggestFileName();
if (rename != null && rename && StringUtils.hasText(suggestFileName)) {
String fileName = selectedItem.getFileName().get();
String extension = StringUtils.getFilenameExtension(fileName);
LocalDate localDate = selectedItem.getApplyDate().get();
String contractCode = viewModel.getCode().get();
String newFileName = contractCode + "-" + suggestFileName + (localDate == null ? "" : ("-" + MyDateTimeUtils.format(localDate))) + "." + extension;
// 新旧文件名不一样,需要改名
if (!Objects.equals(newFileName, fileName)) {
File src = new File(viewModel.getPath().get(), fileName);
File desc = new File(viewModel.getPath().get(), newFileName);
if (src.renameTo(desc)) {
selectedItem.getType().set(typeLocal.getType());
selectedItem.getFileName().set(newFileName);
saveRow(selectedItem);
}
} else {
setStatus("文件名没有变化");
}
}
selectedItem.getType().set(typeLocal.getType());
saveRow(selectedItem);
setStatus("文件类型修改成功");
}
}
@Override
public ContractFile loadRowData(ContractFileViewModel row) {
return getContractFileService().findById(row.getId().get());
}
@Override
public ContractFile saveRowData(ContractFile entity) {
return getContractFileService().save(entity);
}
@Override
public void deleteRowData(ContractFile entity) {
getContractFileService().delete(entity);
}
/**
* 重置文件
* <br>
* 依据已存在的文件重建
*/
public void onFileReBuildingAction(ActionEvent event) {
Contract contract = getParent();
ContractFilesRebuildTasker task = new ContractFilesRebuildTasker();
task.setContractService(getContractService());
task.setContract(contract);
UITools.showTaskDialogAndWait("文件重置", task, null);
if (task.isRepaired()) {
loadTableDataSet();
}
}
private void moveFileToCustomer(List<File> files) {
String path = viewModel.getPath().get();
if (!StringUtils.hasText(path)) {
setStatus("未设置目录");
return;
}
File dir = new File(path);
if (!dir.exists()) {
setStatus("目录错误,不存在");
return;
}
Contract contract = getParent();
for (File file : files) {
File dest = new File(dir, file.getName());
if (file.renameTo(dest)) {
ContractFile ccf = new ContractFile();
ccf.setContract(contract);
ccf.setType(ContractFileType.General);
ccf.setFileName(dest.getName());
getContractFileService().save(ccf);
}
}
loadTableDataSet();
}
public void onFileTableSplitPDFAction(ActionEvent event) {
ContractFileViewModel selectedItem = getSelectedItem();
if (selectedItem == null) {
// 未选择行
return;
}
Contract contract = getParent();
if (!StringUtils.hasText(contract.getPath())) {
setStatus("合同未设置路径");
return;
}
File contractPath = new File(contract.getPath());
if (!contractPath.exists()) {
setStatus("合同路径不存在,请检查");
return;
}
String fileName = selectedItem.getFileName().get();
if (!StringUtils.hasText(fileName)) {
setStatus("选中行没有文件信息");
return;
}
if (!"pdf".equalsIgnoreCase(StringUtils.getFilenameExtension(fileName))) {
setStatus(fileName + "不是PDF文件支持拆分");
return;
}
File pdfFile = new File(contractPath, fileName);
if (!pdfFile.exists()) {
setStatus(fileName + "不存在,请检查");
return;
}
// TODO 放到其他线程中, UI线程卡了
ContractCtx contractCtx = new ContractCtx();
try (PDDocument pdDocument = Loader.loadPDF(pdfFile)) {
Splitter splitter = new Splitter();
List<PDDocument> pages = splitter.split(pdDocument);
String name = StringUtils.stripFilenameExtension(fileName);
for (int i = 0; i < pages.size(); i++) {
PDDocument page = pages.get(i);
File outputFile = new File(contractPath, name + "-" + (i + 1) + ".pdf");
page.save(outputFile);
page.close();
ContractFile contractFile = new ContractFile();
contractFile.setContract(contract);
contractCtx.syncContractFile(contractFile, outputFile, (lv, message) -> {
setStatus(message);
});
ContractFile saved = getContractFileService().save(contractFile);
dataSet.add(ContractFileViewModel.from(saved));
}
} catch (Exception e) {
setStatus(e.getMessage());
return;
}
// loadFileTableDataSet(contract);
}
@Override
protected void onTableDeleteAction(ActionEvent event) {
Contract contract = getParent();
String path = contract.getPath();
if (!StringUtils.hasText(path)) {
setStatus("未设置目录");
return;
}
super.onTableDeleteAction(event);
}
@Override
public boolean deleteRow(ContractFileViewModel row) {
return deleteRow(row, true);
}
protected boolean deleteRow(ContractFileViewModel row, boolean confirm) {
boolean deleted = super.deleteRow(row);
if (deleted) {
Contract contract = getParent();
File file = new File(contract.getPath(), row.getFileName().get());
if (!file.exists()) {
setStatus(file.getAbsolutePath() + " 文件不存在, 无法删除");
} else {
if (confirm) {
UITools.showConfirmation("数据记录已经删除,请确认是否删除物理文件", file.getAbsolutePath())
.thenAccept(buttonType -> {
if (buttonType == ButtonType.OK) {
if (file.delete()) {
setStatus("删除文件 " + file.getAbsolutePath());
}
}
});
} else {
if (file.delete()) {
setStatus("删除文件 " + file.getAbsolutePath());
}
}
}
}
return deleted;
}
}

View File

@@ -0,0 +1,373 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractItem;
import com.ecep.contract.manager.ds.contract.service.ContractItemService;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractItemComposeViewModel;
import com.ecep.contract.manager.ds.contract.vo.ContractItemViewModel;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.ViewModelService;
import javafx.application.Platform;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.util.Callback;
import javafx.util.Duration;
import lombok.Setter;
import org.hibernate.Hibernate;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
@FxmlPath("/ui/contract/contract-tab-item.fxml")
public class ContractTabSkinItems
extends AbstContractTableTabSkin<ContractItem, ContractItemViewModel>
implements TabSkin {
@Setter
ContractItemService itemService;
/* 以下是合同内容 */
public TableColumn<ContractItemComposeViewModel, Number> itemTable_idColumn;
public TableColumn<ContractItemComposeViewModel, String> itemTable_titleColumn;
public TableColumn<ContractItemComposeViewModel, String> itemTable_specificationColumn;
public TableColumn<ContractItemComposeViewModel, String> itemTable_unitColumn;
public TableColumn itemTable_columnGroup1;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_exclusiveTaxPriceColumn1;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_taxRateColumn1;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_taxPriceColumn1;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_quantityColumn1;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_exclusiveTaxAmountColumn1;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_taxAmountColumn1;
public TableColumn itemTable_columnGroup2;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_exclusiveTaxPriceColumn2;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_taxRateColumn2;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_taxPriceColumn2;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_quantityColumn2;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_exclusiveTaxAmountColumn2;
public TableColumn<ContractItemComposeViewModel, Double> itemTable_taxAmountColumn2;
public TableColumn<ContractItemComposeViewModel, String> itemTable_remarkColumn;
public ContractTabSkinItems(ContractWindowController controller) {
super(controller);
}
@Override
protected ContractItemService getViewModelService() {
return itemService;
}
@Override
public Tab getTab() {
return controller.itemTab;
}
@Override
public void initializeUIComponents() {
super.initializeUIComponents();
itemTable_columnGroup1.visibleProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.RECEIVE));
//itemTable_columnGroup2.visibleProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.PAY));
}
static class UnitTableCell extends TableCell<ContractItemComposeViewModel, String> {
{
setAlignment(Pos.CENTER);
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
return;
}
setText(item);
}
}
ContractItemComposeViewModel createNew(String key, ContractItem item) {
ContractItemComposeViewModel m = new ContractItemComposeViewModel();
// set key
m.getTitle().set(item.getTitle());
m.getSpecification().set(item.getSpecification());
return m;
}
private void addIn(HashMap<String, ContractItemComposeViewModel> map, List<ContractItem> list) {
for (ContractItem item : list) {
String key = makeKey(item);
ContractItemComposeViewModel model = map.computeIfAbsent(key, k -> createNew(k, item));
model.getUnit().set(item.getUnit());
model.getIn().add(item);
}
}
private void addOut(List<ContractItem> list, HashMap<String, ContractItemComposeViewModel> map) {
for (ContractItem item : list) {
String key = makeKey(item);
ContractItemComposeViewModel model = map.computeIfAbsent(key, k -> createNew(k, item));
model.getUnit().set(item.getUnit());
model.getOut().add(item);
}
}
@Override
public void initializeTab() {
super.initializeTab();
itemTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
itemTable_titleColumn.setCellValueFactory(param -> param.getValue().getTitle());
itemTable_specificationColumn.setCellValueFactory(param -> param.getValue().getSpecification());
itemTable_unitColumn.setCellValueFactory(param -> param.getValue().getUnit());
itemTable_unitColumn.setCellFactory(col -> new UnitTableCell());
NumberCellFactory v1 = new NumberCellFactory("%,.1f", null);
NumberCellFactory v2 = new NumberCellFactory("%,.2f", null);
NumberCellFactory v3 = new NumberCellFactory("%,.2f", "custom-cell");
// 进项
itemTable_exclusiveTaxPriceColumn1.setCellValueFactory(param -> param.getValue().getIn().getExclusiveTaxPrice().asObject());
itemTable_exclusiveTaxPriceColumn1.setCellFactory(v2);
itemTable_taxRateColumn1.setCellValueFactory(param -> param.getValue().getIn().getTaxRate().asObject());
itemTable_taxRateColumn1.setCellFactory(v1);
itemTable_taxPriceColumn1.setCellValueFactory(param -> param.getValue().getIn().getTaxPrice().asObject());
itemTable_taxPriceColumn1.setCellFactory(v2);
itemTable_quantityColumn1.setCellValueFactory(param -> param.getValue().getIn().getQuantity().asObject());
itemTable_quantityColumn1.setCellFactory(v1);
itemTable_taxAmountColumn1.setCellValueFactory(param -> param.getValue().getIn().getTaxAmount().asObject());
itemTable_taxAmountColumn1.setCellFactory(v3);
itemTable_exclusiveTaxAmountColumn1.setCellValueFactory(param -> param.getValue().getIn().getExclusiveTaxAmount().asObject());
itemTable_exclusiveTaxAmountColumn1.setCellFactory(v3);
// 出项
itemTable_exclusiveTaxPriceColumn2.setCellValueFactory(param -> param.getValue().getOut().getExclusiveTaxPrice().asObject());
itemTable_exclusiveTaxPriceColumn2.setCellFactory(v2);
itemTable_taxRateColumn2.setCellValueFactory(param -> param.getValue().getOut().getTaxRate().asObject());
itemTable_taxRateColumn2.setCellFactory(v1);
itemTable_taxPriceColumn2.setCellValueFactory(param -> param.getValue().getOut().getTaxPrice().asObject());
itemTable_taxPriceColumn2.setCellFactory(v2);
itemTable_quantityColumn2.setCellValueFactory(param -> param.getValue().getOut().getQuantity().asObject());
itemTable_quantityColumn2.setCellFactory(v1);
itemTable_taxAmountColumn2.setCellValueFactory(param -> param.getValue().getOut().getTaxAmount().asObject());
itemTable_taxAmountColumn2.setCellFactory(v3);
itemTable_exclusiveTaxAmountColumn2.setCellValueFactory(param -> param.getValue().getOut().getExclusiveTaxAmount().asObject());
itemTable_exclusiveTaxAmountColumn2.setCellFactory(v3);
itemTable_remarkColumn.setCellValueFactory(param -> param.getValue().getRemark());
}
@Override
protected void createContextMenu(ContextMenu contextMenu) {
MenuItem item2 = new MenuItem("刷新");
item2.setOnAction(this::onTableRefreshAction);
MenuItem item3 = new MenuItem("删除");
item3.setOnAction(this::onTableDeleteAction);
contextMenu.getItems().addAll(item2, item3);
}
public ContractItemService getItemService() {
if (itemService == null) {
itemService = SpringApp.getBean(ContractItemService.class);
}
return itemService;
}
private void sum(ContractItemComposeViewModel model, Contract contract, HashMap<String, ContractItemComposeViewModel> map) {
double inQuantity = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getQuantity().get()).sum();
Platform.runLater(() -> model.getIn().getQuantity().set(inQuantity));
double inTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getTaxAmount().get()).sum();
Platform.runLater(() -> model.getIn().getTaxAmount().set(inTaxAmount));
double inExclusiveTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getExclusiveTaxAmount().get()).sum();
Platform.runLater(() -> model.getIn().getExclusiveTaxAmount().set(inExclusiveTaxAmount));
double outQuantity = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getQuantity().get()).sum();
Platform.runLater(() -> model.getOut().getQuantity().set(outQuantity));
double outTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getTaxAmount().get()).sum();
Platform.runLater(() -> model.getOut().getTaxAmount().set(outTaxAmount));
double outExclusiveTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getExclusiveTaxAmount().get()).sum();
Platform.runLater(() -> model.getOut().getExclusiveTaxAmount().set(outExclusiveTaxAmount));
}
String makeKey(ContractItem item) {
return item.getTitle() + "-" + item.getSpecification();
}
static class NumberTableCell extends TableCell<ContractItemComposeViewModel, Double> {
// "%.1f"
private final String format;
public NumberTableCell(String format, String styleClass) {
this.format = format;
if (StringUtils.hasText(styleClass)) {
getStyleClass().add(styleClass);
}
}
@Override
protected void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
return;
}
ContractItemComposeViewModel model = getTableRow().getItem();
String title = model.getTitle().get();
setText(String.format(format, item));
String tooltipText = null;
switch (getTableColumn().getId()) {
case "itemTable_taxAmountColumn1": {
if ("合计".equals(title)) {
setTooltip((String) null);
return;
}
SimpleListProperty<ContractItem> items = model.getIn().getItems();
ObservableList<ContractItem> list = items.get();
if (list == null) {
setText(null);
setTooltip("");
return;
}
setTooltip(list, ContractItem::getTaxPrice);
break;
}
case "itemTable_exclusiveTaxAmountColumn1": {
if ("合计".equals(title)) {
setTooltip((String) null);
return;
}
SimpleListProperty<ContractItem> items = model.getIn().getItems();
ObservableList<ContractItem> list = items.get();
if (list == null) {
setText(null);
setTooltip("");
return;
}
setTooltip(list, ContractItem::getExclusiveTaxPrice);
}
break;
case "itemTable_taxAmountColumn2": {
if ("合计".equals(title)) {
setTooltip((String) null);
return;
}
SimpleListProperty<ContractItem> items = model.getOut().getItems();
ObservableList<ContractItem> list = items.get();
if (list == null) {
setText(null);
setTooltip("");
return;
}
setTooltip(list, ContractItem::getTaxPrice);
}
break;
case "itemTable_exclusiveTaxAmountColumn2": {
if ("合计".equals(title)) {
setTooltip((String) null);
return;
}
SimpleListProperty<ContractItem> items = model.getOut().getItems();
ObservableList<ContractItem> list = items.get();
if (list == null) {
setText(null);
setTooltip("");
return;
}
setTooltip(list, ContractItem::getExclusiveTaxPrice);
}
break;
default:
if ("合计".equals(title)) {
setTooltip((String) null);
setText(null);
return;
}
setTooltip("");
return;
}
}
private void setTooltip(ObservableList<ContractItem> list, Function<ContractItem, Double> getPrice) {
String text = list.stream().map(v -> {
Contract contract = v.getContract();
if (!Hibernate.isInitialized(contract)) {
contract = SpringApp.getBean(ContractService.class).findById(contract.getId());
}
Double price = getPrice.apply(v);
double quantity = v.getQuantity();
return contract.getCode() + " " + String.format(format, price) + " x " + quantity + " = " + String.format(format, (price * quantity));
}).collect(Collectors.joining("\n"));
setTooltip(text);
}
private void setTooltip(String text) {
Tooltip tooltip = getTooltip();
if (StringUtils.hasText(text)) {
if (tooltip == null) {
tooltip = new Tooltip();
setTooltip(tooltip);
}
tooltip.setShowDelay(Duration.ZERO);
tooltip.setHideDelay(Duration.ZERO);
tooltip.setText(text);
} else {
if (tooltip != null) {
tooltip.setText(null);
}
}
}
}
static class NumberCellFactory implements Callback<TableColumn<ContractItemComposeViewModel, Double>, TableCell<ContractItemComposeViewModel, Double>> {
private final String format;
private final String styleClass;
public NumberCellFactory(String format, String styleClass) {
this.format = format;
this.styleClass = styleClass;
}
@Override
public TableCell<ContractItemComposeViewModel, Double> call(TableColumn<ContractItemComposeViewModel, Double> param) {
NumberTableCell cell = new NumberTableCell(format, styleClass);
cell.setAlignment(Pos.CENTER_RIGHT);
return cell;
}
}
}

View File

@@ -0,0 +1,192 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractItem;
import com.ecep.contract.manager.ds.contract.service.ContractItemService;
import com.ecep.contract.manager.ds.contract.vo.ContractItemComposeViewModel;
import com.ecep.contract.manager.ds.contract.vo.ContractItemViewModel;
import com.ecep.contract.manager.ds.contract.vo.ProjectCostItemViewModel;
import com.ecep.contract.manager.ds.other.EntityStringConverter;
import com.ecep.contract.manager.ds.other.controller.employee.EmployeeTableCell;
import com.ecep.contract.manager.ds.other.controller.inventory.InventoryWindowController;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ds.other.model.Inventory;
import com.ecep.contract.manager.ds.other.service.InventoryService;
import com.ecep.contract.manager.ds.other.vo.InventoryViewModel;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.util.LocalDateTimeTableCell;
import javafx.application.Platform;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.CurrencyStringConverter;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;
import org.hibernate.Hibernate;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
@FxmlPath("/ui/contract/contract-tab-item-v2.fxml")
public class ContractTabSkinItemsV2
extends AbstContractTableTabSkin<ContractItem, ContractItemViewModel>
implements TabSkin, EditableEntityTableTabSkin<ContractItem, ContractItemViewModel> {
@Setter
ContractItemService itemService;
@Setter
InventoryService inventoryService;
/* 以下是合同内容 */
public TableColumn<ContractItemViewModel, Number> idColumn;
public TableColumn<ContractItemViewModel, String> titleColumn;
public TableColumn<ContractItemViewModel, String> specificationColumn;
public TableColumn<ContractItemViewModel, String> unitColumn;
public TableColumn<ContractItemViewModel, Inventory> inventoryColumn;
public TableColumn<ContractItemViewModel, Number> refIdColumn;
public TableColumn<ContractItemViewModel, String> codeColumn;
public TableColumn<ContractItemViewModel, Employee> creatorColumn;
public TableColumn<ContractItemViewModel, LocalDateTime> createDateColumn;
public TableColumn<ContractItemViewModel, Employee> updaterColumn;
public TableColumn<ContractItemViewModel, LocalDateTime> updateDateColumn;
public TableColumn<ContractItemViewModel, LocalDate> startDateColumn;
public TableColumn<ContractItemViewModel, LocalDate> endDateColumn;
public TableColumn<ContractItemViewModel, Number> exclusiveTaxPriceColumn;
public TableColumn<ContractItemViewModel, Number> taxRateColumn;
public TableColumn<ContractItemViewModel, Number> taxPriceColumn;
public TableColumn<ContractItemViewModel, Number> quantityColumn;
public TableColumn<ContractItemViewModel, Number> exclusiveTaxAmountColumn;
public TableColumn<ContractItemViewModel, Number> taxAmountColumn;
public TableColumn<ContractItemViewModel, String> remarkColumn;
public ContractTabSkinItemsV2(ContractWindowController controller) {
super(controller);
}
@Override
public Tab getTab() {
return controller.itemTab;
}
@Override
protected ContractItemService getViewModelService() {
return getItemService();
}
@Override
public void initializeTable() {
super.initializeTable();
NumberFormat numberInstance = NumberFormat.getNumberInstance(getLocale());
numberInstance.setMaximumFractionDigits(2);
numberInstance.setMinimumFractionDigits(2);
CurrencyStringConverter currencyStringConverter = new CurrencyStringConverter(numberInstance);
idColumn.setCellValueFactory(param -> param.getValue().getId());
titleColumn.setCellValueFactory(param -> param.getValue().getTitle());
specificationColumn.setCellValueFactory(param -> param.getValue().getSpecification());
unitColumn.setCellValueFactory(param -> param.getValue().getUnit());
inventoryColumn.setCellValueFactory(param -> param.getValue().getInventory());
EntityStringConverter<Inventory> converter = new EntityStringConverter<>();
converter.setInitialized(v -> getInventoryService().findById(v.getId()));
converter.setFormater(Inventory::getCode);
inventoryColumn.setCellFactory(TextFieldTableCell.forTableColumn(converter));
exclusiveTaxPriceColumn.setCellValueFactory(param -> param.getValue().getExclusiveTaxPrice());
exclusiveTaxPriceColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));
taxRateColumn.setCellValueFactory(param -> param.getValue().getTaxRate());
taxRateColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));
taxPriceColumn.setCellValueFactory(param -> param.getValue().getTaxPrice());
taxPriceColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));
quantityColumn.setCellValueFactory(param -> param.getValue().getQuantity());
quantityColumn.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter(getLocale())));
taxAmountColumn.setCellValueFactory(param -> param.getValue().getTaxAmount());
taxAmountColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));
exclusiveTaxAmountColumn.setCellValueFactory(param -> param.getValue().getExclusiveTaxAmount());
exclusiveTaxAmountColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));
refIdColumn.setCellValueFactory(param -> param.getValue().getRefId());
codeColumn.setCellValueFactory(param -> param.getValue().getCode());
startDateColumn.setCellValueFactory(param -> param.getValue().getStartDate());
endDateColumn.setCellValueFactory(param -> param.getValue().getEndDate());
creatorColumn.setCellValueFactory(param -> param.getValue().getCreator());
creatorColumn.setCellFactory(cell -> new EmployeeTableCell<>(getEmployeeService()));
updaterColumn.setCellValueFactory(param -> param.getValue().getUpdater());
updaterColumn.setCellFactory(cell -> new EmployeeTableCell<>(getEmployeeService()));
createDateColumn.setCellValueFactory(param -> param.getValue().getCreateDate());
createDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
updateDateColumn.setCellValueFactory(param -> param.getValue().getUpdateDate());
updateDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
remarkColumn.setCellValueFactory(param -> param.getValue().getRemark());
}
public ContractItemService getItemService() {
if (itemService == null) {
itemService = getBean(ContractItemService.class);
}
return itemService;
}
InventoryService getInventoryService() {
if (inventoryService == null) {
inventoryService = getBean(InventoryService.class);
}
return inventoryService;
}
private void sum(ContractItemComposeViewModel model, Contract contract, HashMap<String, ContractItemComposeViewModel> map) {
double inQuantity = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getQuantity().get()).sum();
Platform.runLater(() -> model.getIn().getQuantity().set(inQuantity));
double inTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getTaxAmount().get()).sum();
Platform.runLater(() -> model.getIn().getTaxAmount().set(inTaxAmount));
double inExclusiveTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getExclusiveTaxAmount().get()).sum();
Platform.runLater(() -> model.getIn().getExclusiveTaxAmount().set(inExclusiveTaxAmount));
double outQuantity = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getQuantity().get()).sum();
Platform.runLater(() -> model.getOut().getQuantity().set(outQuantity));
double outTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getTaxAmount().get()).sum();
Platform.runLater(() -> model.getOut().getTaxAmount().set(outTaxAmount));
double outExclusiveTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getExclusiveTaxAmount().get()).sum();
Platform.runLater(() -> model.getOut().getExclusiveTaxAmount().set(outExclusiveTaxAmount));
}
@Override
protected void createContextMenu(ContextMenu contextMenu) {
super.createContextMenu(contextMenu);
MenuItem showInventory = new MenuItem("查看存货");
showInventory.setOnAction(event -> {
ContractItemViewModel selectedItem = getTableView().getSelectionModel().getSelectedItem();
Inventory inventory = selectedItem.getInventory().get();
if (inventory == null) {
return;
}
if (!Hibernate.isInitialized(inventory)) {
inventory = getInventoryService().findById(inventory.getId());
}
showInOwner(InventoryWindowController.class, InventoryViewModel.from(inventory));
});
}
}

View File

@@ -0,0 +1,84 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.model.ContractPayPlan;
import com.ecep.contract.manager.ds.contract.service.ContractPayPlanService;
import com.ecep.contract.manager.ds.contract.vo.ContractPayPlanViewModel;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.ui.util.LocalDateTimeTableCell;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.CurrencyStringConverter;
import javafx.util.converter.NumberStringConverter;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
@FxmlPath("/ui/contract/contract-tab-pay-plan.fxml")
public class ContractTabSkinPayPlan extends AbstContractTableTabSkin<ContractPayPlan, ContractPayPlanViewModel> {
public TableColumn<ContractPayPlanViewModel, Number> idColumn;
public TableColumn<ContractPayPlanViewModel, LocalDate> payDateColumn;
public TableColumn<ContractPayPlanViewModel, Number> payRatioColumn;
public TableColumn<ContractPayPlanViewModel, Number> payCurrencyColumn;
public TableColumn<ContractPayPlanViewModel, String> payTermColumn;
public TableColumn<ContractPayPlanViewModel, Number> refIdColumn;
public TableColumn<ContractPayPlanViewModel, LocalDateTime> updateDateColumn;
ContractPayPlanService payPlanService;
public ContractTabSkinPayPlan(ContractWindowController controller) {
super(controller);
}
ContractPayPlanService getPayPlanService() {
if (payPlanService == null) {
payPlanService = getBean(ContractPayPlanService.class);
}
return payPlanService;
}
@Override
public Tab getTab() {
return controller.payPlanTab;
}
@Override
protected ViewModelService<ContractPayPlan, ContractPayPlanViewModel> getViewModelService() {
return getPayPlanService();
}
@Override
public void initializeTable() {
super.initializeTable();
NumberFormat numberInstance = NumberFormat.getNumberInstance(getLocale());
numberInstance.setMaximumFractionDigits(2);
numberInstance.setMinimumFractionDigits(2);
CurrencyStringConverter currencyStringConverter = new CurrencyStringConverter(numberInstance);
idColumn.setCellValueFactory(param -> param.getValue().getId());
payDateColumn.setCellValueFactory(param -> param.getValue().getPayDate());
payRatioColumn.setCellValueFactory(param -> param.getValue().getPayRatio());
payRatioColumn.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter()));
payCurrencyColumn.setCellValueFactory(param -> param.getValue().getPayCurrency());
payCurrencyColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));
payTermColumn.setCellValueFactory(param -> param.getValue().getPayTerm());
refIdColumn.setCellValueFactory(param -> param.getValue().getRefId());
updateDateColumn.setCellValueFactory(param -> param.getValue().getUpdateDate());
updateDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
}
@Override
protected void createContextMenu(ContextMenu contextMenu) {
super.createContextMenu(contextMenu);
}
}

View File

@@ -0,0 +1,105 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.controller.purchase_order.PurchaseOrderWindowController;
import com.ecep.contract.manager.ds.contract.model.PurchaseOrder;
import com.ecep.contract.manager.ds.contract.service.PurchaseOrdersService;
import com.ecep.contract.manager.ds.contract.vo.PurchaseOrderViewModel;
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.util.LocalDateTimeTableCell;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import java.time.LocalDateTime;
/**
* 子合同
*/
@FxmlPath("/ui/contract/contract-tab-purchase-orders.fxml")
public class ContractTabSkinPurchaseOrders
extends AbstContractTableTabSkin<PurchaseOrder, PurchaseOrderViewModel>
implements TabSkin {
private PurchaseOrdersService purchaseOrdersService;
private EmployeeStringConverter employeeStringConverter;
public TableColumn<PurchaseOrderViewModel, Number> idColumn;
public TableColumn<PurchaseOrderViewModel, String> codeColumn;
public TableColumn<PurchaseOrderViewModel, String> table_makerColumn;
public TableColumn<PurchaseOrderViewModel, LocalDateTime> table_makerDateColumn;
public TableColumn<PurchaseOrderViewModel, String> table_verifierColumn;
public TableColumn<PurchaseOrderViewModel, LocalDateTime> table_verifierDateColumn;
public TableColumn<PurchaseOrderViewModel, String> table_closerColumn;
public TableColumn<PurchaseOrderViewModel, LocalDateTime> table_closerDateColumn;
public TableColumn<PurchaseOrderViewModel, String> table_descriptionColumn;
public MenuItem table_menu_refresh;
private Tab tab;
public ContractTabSkinPurchaseOrders(ContractWindowController controller, Tab tab) {
super(controller);
this.tab = tab;
}
@Override
protected PurchaseOrdersService getViewModelService() {
return getPurchaseOrdersService();
}
@Override
public void initializeUIComponents() {
super.initializeUIComponents();
// 合同是收时,有关联子合同
getTab().disableProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.PAY).not());
}
@Override
public Tab getTab() {
return tab;
}
@Override
public void initializeTab() {
table_menu_refresh.setOnAction(this::onTableRefreshAction);
idColumn.setCellValueFactory(param -> param.getValue().getId());
codeColumn.setCellValueFactory(param -> param.getValue().getCode());
EmployeeStringConverter converter = getEmployeeStringConverter();
table_makerColumn.setCellValueFactory(param -> param.getValue().getMaker().map(converter::toString));
table_makerDateColumn.setCellValueFactory(param -> param.getValue().getMakerDate());
table_makerDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
table_verifierColumn.setCellValueFactory(param -> param.getValue().getMaker().map(converter::toString));
table_verifierDateColumn.setCellValueFactory(param -> param.getValue().getVerifierDate());
table_verifierDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
table_closerColumn.setCellValueFactory(param -> param.getValue().getMaker().map(converter::toString));
table_closerDateColumn.setCellValueFactory(param -> param.getValue().getCloserDate());
table_closerDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
table_descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
super.initializeTab();
}
@Override
protected void onTableRowDoubleClickedAction(PurchaseOrderViewModel item) {
showInOwner(PurchaseOrderWindowController.class, item);
}
PurchaseOrdersService getPurchaseOrdersService() {
if (purchaseOrdersService == null) {
purchaseOrdersService = getBean(PurchaseOrdersService.class);
}
return purchaseOrdersService;
}
EmployeeStringConverter getEmployeeStringConverter() {
if (employeeStringConverter == null) {
employeeStringConverter = getBean(EmployeeStringConverter.class);
}
return employeeStringConverter;
}
}

View File

@@ -0,0 +1,115 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.controller.sale_order.SalesOrderWindowController;
import com.ecep.contract.manager.ds.contract.model.SalesOrder;
import com.ecep.contract.manager.ds.contract.service.SaleOrdersService;
import com.ecep.contract.manager.ds.contract.vo.SalesOrderViewModel;
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.util.LocalDateFieldTableCell;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.KeyCode;
import lombok.Setter;
import java.time.LocalDate;
/**
* 子合同
*/
@FxmlPath("/ui/contract/contract-tab-sale-orders.fxml")
public class ContractTabSkinSaleOrders
extends AbstContractTableTabSkin<SalesOrder, SalesOrderViewModel>
implements TabSkin {
@Setter
private SaleOrdersService saleOrdersService;
@Setter
private EmployeeStringConverter employeeStringConverter;
public TableColumn<SalesOrderViewModel, Number> idColumn;
public TableColumn<SalesOrderViewModel, String> codeColumn;
public TableColumn<SalesOrderViewModel, Employee> employeeColumn;
public TableColumn<SalesOrderViewModel, Employee> makerColumn;
public TableColumn<SalesOrderViewModel, LocalDate> makerDateColumn;
public TableColumn<SalesOrderViewModel, Employee> verifierColumn;
public TableColumn<SalesOrderViewModel, LocalDate> verifierDateColumn;
public TableColumn<SalesOrderViewModel, String> descriptionColumn;
public MenuItem subContractTable_menu_refresh;
public TextField contractSearchKeyField;
public Button searchBtn;
private Tab tab;
public ContractTabSkinSaleOrders(ContractWindowController controller, Tab tab) {
super(controller);
this.tab = tab;
}
@Override
public void initializeUIComponents() {
super.initializeUIComponents();
// 合同是收时,有关联子合同
getTab().disableProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.RECEIVE).not());
}
@Override
public Tab getTab() {
return tab;
}
@Override
protected SaleOrdersService getViewModelService() {
return getSaleOrdersService();
}
@Override
public void initializeTab() {
contractSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
searchBtn.fire();
}
});
searchBtn.setOnAction(this::onTableRefreshAction);
subContractTable_menu_refresh.setOnAction(this::onTableRefreshAction);
idColumn.setCellValueFactory(param -> param.getValue().getId());
codeColumn.setCellValueFactory(param -> param.getValue().getCode());
employeeColumn.setCellValueFactory(param -> param.getValue().getEmployee());
employeeColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
makerColumn.setCellValueFactory(param -> param.getValue().getMaker());
makerColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
makerDateColumn.setCellValueFactory(param -> param.getValue().getMakerDate());
makerDateColumn.setCellFactory(LocalDateFieldTableCell.forTableColumn());
verifierColumn.setCellValueFactory(param -> param.getValue().getVerifier());
verifierColumn.setCellFactory(TextFieldTableCell.forTableColumn(getEmployeeStringConverter()));
verifierDateColumn.setCellValueFactory(param -> param.getValue().getVerifierDate());
verifierDateColumn.setCellFactory(LocalDateFieldTableCell.forTableColumn());
descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
super.initializeTab();
}
@Override
protected void onTableRowDoubleClickedAction(SalesOrderViewModel item) {
SalesOrderWindowController.show(item, getTableView().getScene().getWindow());
}
private EmployeeStringConverter getEmployeeStringConverter() {
if (employeeStringConverter == null) {
employeeStringConverter = getBean(EmployeeStringConverter.class);
}
return employeeStringConverter;
}
SaleOrdersService getSaleOrdersService() {
if (saleOrdersService == null) {
saleOrdersService = getBean(SaleOrdersService.class);
}
return saleOrdersService;
}
}

View File

@@ -0,0 +1,99 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.ViewModelService;
import com.ecep.contract.manager.util.SpecificationUtils;
import javafx.application.Platform;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.util.List;
/**
* 子合同
*/
@FxmlPath("/ui/contract/contract-tab-sub-contract.fxml")
public class ContractTabSkinSubContract
extends AbstContractTableTabSkin<Contract, ContractViewModel>
implements TabSkin {
public TableColumn<ContractViewModel, Number> subContractTable_idColumn;
public TableColumn<ContractViewModel, String> subContractTable_nameColumn;
public TableColumn<ContractViewModel, String> subContractTable_codeColumn;
public TableColumn<ContractViewModel, LocalDate> subContractTable_setupDateColumn;
public TableColumn<ContractViewModel, LocalDate> subContractTable_inureDateColumn;
public TableColumn<ContractViewModel, LocalDate> subContractTable_orderDateColumn;
public TableColumn<ContractViewModel, LocalDate> subContractTable_varyDateColumn;
public MenuItem subContractTable_menu_refresh;
public TextField contractSearchKeyField;
public Button contractSearchBtn;
public ContractTabSkinSubContract(ContractWindowController controller) {
super(controller);
}
@Override
public void initializeUIComponents() {
super.initializeUIComponents();
// 合同是收时,有关联子合同
getTab().disableProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.RECEIVE).not());
}
@Override
public Tab getTab() {
return controller.contractTab;
}
@Override
protected ContractService getViewModelService() {
return getContractService();
}
@Override
public Specification<Contract> getSpecification(Contract parent) {
return SpecificationUtils.and(getSpecification(), (root, query, builder) -> {
return builder.equal(root.get("parentCode"), parent.getCode());
});
}
@Override
public void initializeTab() {
super.initializeTab();
contractSearchKeyField.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ENTER) {
contractSearchBtn.fire();
}
});
contractSearchBtn.setOnAction(this::onTableRefreshAction);
subContractTable_menu_refresh.setOnAction(this::onTableRefreshAction);
subContractTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
subContractTable_nameColumn.setCellValueFactory(param -> param.getValue().getName());
subContractTable_codeColumn.setCellValueFactory(param -> param.getValue().getCode());
subContractTable_setupDateColumn.setCellValueFactory(param -> param.getValue().getSetupDate());
subContractTable_inureDateColumn.setCellValueFactory(param -> param.getValue().getInureDate());
subContractTable_orderDateColumn.setCellValueFactory(param -> param.getValue().getOrderDate());
subContractTable_varyDateColumn.setCellValueFactory(param -> param.getValue().getVaryDate());
Platform.runLater(() -> {
getTableView().getSortOrder().add(subContractTable_codeColumn);
});
}
@Override
protected void onTableRowDoubleClickedAction(ContractViewModel item) {
ContractWindowController.show(item, getTableView().getScene().getWindow());
}
}

View File

@@ -0,0 +1,193 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.ds.company.model.Company;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.company.vo.CompanyViewModel;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.model.ContractBidVendor;
import com.ecep.contract.manager.ds.contract.model.ContractFile;
import com.ecep.contract.manager.ds.contract.service.ContractBidVendorService;
import com.ecep.contract.manager.ds.contract.service.ContractFileService;
import com.ecep.contract.manager.ds.contract.vo.ContractBidVendorViewModel;
import com.ecep.contract.manager.ui.EditableEntityTableTabSkin;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.TabSkin;
import com.ecep.contract.manager.ui.ViewModelService;
import javafx.event.ActionEvent;
import javafx.scene.control.*;
import javafx.util.StringConverter;
import lombok.Setter;
import org.controlsfx.control.textfield.TextFields;
import org.hibernate.Hibernate;
import org.springframework.data.jpa.domain.Specification;
import java.util.List;
/**
* 以下是比价供应商
*/
@FxmlPath("/ui/contract/contract-tab-bid.fxml")
public class ContractTabSkinVendorBid
extends AbstContractTableTabSkin<ContractBidVendor, ContractBidVendorViewModel>
implements TabSkin, EditableEntityTableTabSkin<ContractBidVendor, ContractBidVendorViewModel> {
@Setter
private ContractBidVendorService service;
public TableColumn<ContractBidVendorViewModel, Number> bidVendorTable_idColumn;
public TableColumn<ContractBidVendorViewModel, String> bidVendorTable_companyColumn;
public TableColumn<ContractBidVendorViewModel, ContractFile> bidVendorTable_quotationSheetColumn;
public Button bidVendorCreateBtn;
public MenuItem bidVendorTable_menu_refresh;
public MenuItem bidVendorTable_menu_delete;
public MenuItem bidVendorTable_menu_chose_sheet;
public ContractTabSkinVendorBid(ContractWindowController controller) {
super(controller);
}
@Override
protected ContractBidVendorService getViewModelService() {
return getService();
}
@Override
public void initializeUIComponents() {
super.initializeUIComponents();
// 合同是收时,有关联子合同
getTab().disableProperty().bind(viewModel.getPayWay().isEqualTo(ContractPayWay.PAY).not());
}
@Override
public Tab getTab() {
return controller.bidVendorTab;
}
static class QuotationSheetColumnTableCell extends TableCell<ContractBidVendorViewModel, ContractFile> {
private ContractFileService contractFileService;
public ContractFileService getContractFileService() {
if (contractFileService == null) {
contractFileService = SpringApp.getBean(ContractFileService.class);
}
return contractFileService;
}
@Override
protected void updateItem(ContractFile item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
if (!Hibernate.isInitialized(item)) {
item = getContractFileService().findById(item.getId());
ContractBidVendorViewModel viewModel = getTableRow().getItem();
viewModel.getQuotationSheet().set(item);
}
setText(item.getFileName());
}
}
}
@Override
public void initializeTab() {
bidVendorCreateBtn.setOnAction(this::onBidVendorTableCreateAction);
bidVendorTable_menu_refresh.setOnAction(this::onTableRefreshAction);
bidVendorTable_menu_delete.setOnAction(this::onTableDeleteAction);
bidVendorTable_menu_chose_sheet.setOnAction(this::onBidVendorTableChoseQuotationSheetAction);
bidVendorTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
bidVendorTable_companyColumn.setCellValueFactory(param -> param.getValue().getCompany().map(c -> {
if (c == null) {
return null;
} else {
return c.getName();
}
}));
bidVendorTable_quotationSheetColumn.setCellValueFactory(param -> param.getValue().getQuotationSheet());
bidVendorTable_quotationSheetColumn.setCellFactory(param -> new QuotationSheetColumnTableCell());
super.initializeTab();
}
@Override
protected void onTableRowDoubleClickedAction(ContractBidVendorViewModel item) {
showInOwner(VendorBidWindowController.class, item);
}
public void onBidVendorTableCreateAction(ActionEvent event) {
Contract contract = getParent();
ChoiceDialog<String> dialog = new ChoiceDialog<>();
dialog.setTitle("添加比价供应商");
dialog.setHeaderText("请输入比价的供应商公司名称,支持模糊搜索功能");
dialog.setWidth(400);
ComboBox<String> comboBox = (ComboBox<String>) dialog.getDialogPane().getContent().lookup("ComboBox");
TextFields.bindAutoCompletion(comboBox.getEditor(), p -> {
if (p.isCancelled()) {
return null;
}
return getCompanyService().search(p.getUserText()).stream().map(CompanyViewModel::from).toList();
}, new StringConverter<>() {
@Override
public String toString(CompanyViewModel viewModel) {
return viewModel.getName().get();
}
@Override
public CompanyViewModel fromString(String string) {
return null;
}
});
comboBox.setEditable(true);
dialog.showAndWait().ifPresent(selectedItem -> {
Company company = getCompanyService().findAllByName(selectedItem).getFirst();
List<ContractBidVendor> list = getService().findByContractAndCompany(contract, company);
if (list == null || list.isEmpty()) {
ContractBidVendor bidVendor = new ContractBidVendor();
bidVendor.setContract(contract);
bidVendor.setCompany(company);
getService().save(bidVendor);
loadTableDataSet();
} else {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("添加比价供应商");
alert.setHeaderText("添加的供应商:" + company.getName() + " 已经存在。");
alert.showAndWait();
}
});
}
/**
* 匹配报价表
*
* @param event event
*/
public void onBidVendorTableChoseQuotationSheetAction(ActionEvent event) {
ContractBidVendorViewModel selectedItem = getSelectedItem();
if (selectedItem == null) {
return;
}
// TODO xx
}
private ContractBidVendorService getService() {
if (service == null) {
service = SpringApp.getBean(ContractBidVendorService.class);
}
return service;
}
private CompanyService getCompanyService() {
return controller.companyService;
}
}

View File

@@ -0,0 +1,40 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.model.ContractType;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.vo.ContractViewModel;
import javafx.scene.control.TableCell;
import org.hibernate.Hibernate;
import static com.ecep.contract.manager.SpringApp.getBean;
public class ContractTypeTableCell extends TableCell<ContractViewModel, ContractType> {
private ContractService contractService;
public ContractTypeTableCell() {
}
public ContractTypeTableCell(ContractService contractService) {
this.contractService = contractService;
}
ContractService getContractService() {
if (contractService == null) {
contractService = getBean(ContractService.class);
}
return contractService;
}
@Override
protected void updateItem(ContractType item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
return;
}
if (!Hibernate.isInitialized(item)) {
item = getContractService().findTypeById(item.getId());
}
setText(item.getName());
}
}

View File

@@ -0,0 +1,195 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.SpringApp;
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
import com.ecep.contract.manager.ds.company.service.CompanyService;
import com.ecep.contract.manager.ds.contract.model.ContractGroup;
import com.ecep.contract.manager.ds.contract.model.ContractKind;
import com.ecep.contract.manager.ds.contract.model.ContractType;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ds.other.service.EmployeeService;
import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
import com.ecep.contract.manager.ui.MessageHolder;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.Getter;
import org.springframework.beans.BeansException;
import java.util.Map;
import java.util.logging.Level;
@Data
public class ContractUpdater implements MessageHolder {
@lombok.Data
static class Data {
@Getter
private boolean changed = false;
private String guid;
private String code;
private String name;
private String parentCode;
private String description;
private String typeCode;
private String groupCode;
private String kindName;
private String way;
private String unit;
private java.sql.Date orderDate;
private java.sql.Date startDate;
private java.sql.Date endDate;
private String setupPerson;
private java.sql.Date setupDate;
private String inurePerson;
private java.sql.Date inureDate;
private String varyPerson;
private java.sql.Date varyDate;
private Double totalCurrency;
private String personId;
private void setValues(ContractUpdater updater, Map<String, Object> rs) {
guid = (String) rs.get("GUID");
code = (String) rs.get("strContractID");
name = (String) rs.get("strContractName");
parentCode = (String) rs.get("strParentID");
description = (String) rs.get("strContractDesc");
typeCode = (String) rs.get("strContractType");
groupCode = (String) rs.get("strContractGrp");
kindName = (String) rs.get("strContractKind");
way = (String) rs.get("strWay");
unit = (String) rs.get("strBisectionUnit");
orderDate = updater.convertValue(rs.get("strContractOrderDate"), java.sql.Date.class);
startDate = updater.convertValue(rs.get("strContractStartDate"), java.sql.Date.class);
endDate = updater.convertValue(rs.get("strContractEndDate"), java.sql.Date.class);
setupPerson = (String) rs.get("strSetupPerson");
setupDate = updater.convertValue(rs.get("strSetupDate"), java.sql.Date.class);
inurePerson = (String) rs.get("strInurePerson");
inureDate = updater.convertValue(rs.get("strInureDate"), java.sql.Date.class);
varyPerson = (String) rs.get("strVaryPerson");
varyDate = updater.convertValue(rs.get("dtVaryDate"), java.sql.Date.class);
totalCurrency = (Double) rs.get("dblTotalCurrency");
personId = (String) rs.get("strPersonID");
}
private void changed() {
changed = true;
}
}
public static ContractUpdater with(MessageHolder holder) {
ContractUpdater updater = new ContractUpdater();
updater.holder = holder;
return updater;
}
private ObjectMapper objectMapper;
private MessageHolder holder;
private ContractService contractService;
private EmployeeService employeeService;
private CompanyService companyService;
private CompanyVendorService vendorService;
private CompanyCustomerService customerService;
private YongYouU8Service u8Service;
public <T> T convertValue(Object fromValue, Class<T> toValueType) throws IllegalArgumentException {
return getObjectMapper().convertValue(fromValue, toValueType);
}
@Override
public void addMessage(Level level, String message) {
holder.addMessage(level, message);
}
public void updateMessage(String message) {
MessageHolder consumer = getHolder();
if (consumer != null) {
consumer.info(message);
}
}
<T> T getBean(Class<T> requiredType) throws BeansException {
return SpringApp.getBean(requiredType);
}
private ObjectMapper getObjectMapper() {
if (objectMapper == null) {
objectMapper = getBean(ObjectMapper.class);
}
return objectMapper;
}
private ContractService getContractService() {
if (contractService == null) {
contractService = getBean(ContractService.class);
}
return contractService;
}
private EmployeeService getEmployeeService() {
if (employeeService == null) {
employeeService = getBean(EmployeeService.class);
}
return employeeService;
}
private ContractType getTypeByCode(String typeCode) {
return getContractService().findTypeByCode(typeCode);
}
private ContractGroup getGroupByCode(String groupCode) {
return getContractService().findGroupByCode(groupCode);
}
private ContractKind getKindByName(String kindName) {
return getContractService().findKindByName(kindName);
}
private Employee findEmployeeByCode(String personCode) {
return getEmployeeService().findByCode(personCode);
}
private Employee findEmployeeByName(String personName) {
if (personName == null) {
return null;
}
return getEmployeeService().findByName(personName);
}
private CompanyVendorService getVendorService() {
if (vendorService == null) {
vendorService = SpringApp.getBean(CompanyVendorService.class);
}
return vendorService;
}
private CompanyCustomerService getCustomerService() {
if (customerService == null) {
customerService = SpringApp.getBean(CompanyCustomerService.class);
}
return customerService;
}
private CompanyService getCompanyService() {
if (companyService == null) {
companyService = SpringApp.getBean(CompanyService.class);
}
return companyService;
}
private YongYouU8Service getU8Service() {
if (u8Service == null) {
u8Service = SpringApp.getBean(YongYouU8Service.class);
}
return u8Service;
}
}

View File

@@ -0,0 +1,397 @@
package com.ecep.contract.manager.ds.contract.controller;
import com.ecep.contract.manager.ds.contract.ContractPayWay;
import com.ecep.contract.manager.ds.contract.model.Contract;
import com.ecep.contract.manager.ds.contract.service.ContractService;
import com.ecep.contract.manager.ds.contract.tasker.ContractVerifyComm;
import com.ecep.contract.manager.ds.contract.tasker.ContractVerifyResultExportAsExcelFile;
import com.ecep.contract.manager.ui.BaseController;
import com.ecep.contract.manager.ds.other.model.Employee;
import com.ecep.contract.manager.ds.other.service.EmployeeService;
import com.ecep.contract.manager.ds.project.service.SaleTypeService;
import com.ecep.contract.manager.ds.vendor.service.VendorGroupService;
import com.ecep.contract.manager.ui.FxmlPath;
import com.ecep.contract.manager.ui.Message;
import com.ecep.contract.manager.ui.MessageHolder;
import com.ecep.contract.manager.util.UITools;
import javafx.application.Platform;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.stage.*;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.Hibernate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.File;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import static com.ecep.contract.manager.util.TableViewUtils.bindDoubleClicked;
import static com.ecep.contract.manager.util.TableViewUtils.bindEnterPressed;
import static java.util.concurrent.CompletableFuture.runAsync;
@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/contract/contract-verify.fxml")
public class ContractVerifyWindowController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(ContractVerifyWindowController.class);
@Override
public Stage show(FXMLLoader loader, Window owner, Modality modality) {
return super.show(loader, owner, modality);
}
@Setter
@Getter
public static class MessageExt extends Message {
private String prefix = null;
public MessageExt(Level level, String message) {
super(level, message);
}
}
@Data
public static class Model implements MessageHolder {
private SimpleStringProperty code = new SimpleStringProperty();
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleObjectProperty<Employee> employee = new SimpleObjectProperty<>();
private SimpleObjectProperty<LocalDate> setupDate = new SimpleObjectProperty<>();
private SimpleListProperty<MessageExt> messages = new SimpleListProperty<>(FXCollections.observableArrayList());
@Override
public void addMessage(Level level, String message) {
MessageExt msg = new MessageExt(level, message);
messages.add(msg);
}
@Override
public MessageHolder sub(String prefix) {
return (level, message) -> {
MessageExt msg = new MessageExt(level, message);
msg.setPrefix(prefix);
msg.setMessage(message);
messages.add(msg);
};
}
}
class EmployeeTableCell extends TableCell<Model, Employee> {
@Override
protected void updateItem(Employee item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
return;
}
if (!Hibernate.isInitialized(item)) {
item = employeeService.findById(item.getId());
Model model = getTableRow().getItem();
if (model != null) {
model.getEmployee().set(item);
}
}
setText(item.toPrettyString());
}
}
static class StateTableCell extends TableCell<Model, ObservableList<MessageExt>> {
Label message2Label(MessageExt message) {
Label label = new Label(message.getMessage());
label.getStyleClass().add("msg-text");
label.getStyleClass().add(message.getLevel().getName().toLowerCase());
return label;
}
@Override
protected void updateItem(ObservableList<MessageExt> item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
return;
}
if (item.isEmpty()) {
setText("");
setGraphic(null);
return;
}
try {
HBox box = new HBox();
box.getStyleClass().add("message-column-ctx");
// 使用绑定方式监听列表变化,避免重复创建节点
List<Label> labels = item.stream().map(this::message2Label).toList();
Platform.runLater(() -> box.getChildren().setAll(labels));
// 监听消息列表变化,动态更新 UI
item.addListener((ListChangeListener<? super MessageExt>) change -> {
List<MessageExt> messages = new ArrayList<>(change.getList());
List<Label> list = messages.stream().map(this::message2Label).toList();
Platform.runLater(() -> box.getChildren().setAll(list));
});
setGraphic(box);
} catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("{} @ {}", e.getMessage(), getTableRow().getItem().getCode(), e);
}
}
}
}
ContractVerifyComm comm = new ContractVerifyComm();
@Autowired
private SaleTypeService saleTypeService;
@Autowired
private VendorGroupService vendorGroupService;
@Autowired
private ContractService contractService;
@Autowired
private EmployeeService employeeService;
public DatePicker setupDateBeginSelector;
public DatePicker setupDateEndSelector;
// 企业验证开关
public CheckMenuItem verifyCompanyStatusChecker;
public CheckMenuItem verifyCompanyPathChecker;
public CheckMenuItem verifyCompanyCreditChecker;
// 供应商验证开关
public CheckMenuItem verifyVendorChecker;
public CheckMenuItem verifyVendorFileChecker;
// 客户验证开关
public CheckMenuItem verifyCustomerChecker;
public CheckMenuItem verifyCustomerFileChecker;
public CheckMenuItem verifyCustomerSubContractDateChecker;
public CheckMenuItem onlyShowVerifiedChecker;
public TableView<Model> viewTable;
private final ObservableList<Model> viewTableDataSet = FXCollections.observableArrayList();
public TableColumn<Model, String> viewTable_codeColumn;
public TableColumn<Model, String> viewTable_nameColumn;
public TableColumn<Model, Employee> viewTable_employeeColumn;
public TableColumn<Model, LocalDate> viewTable_setupDateColumn;
public TableColumn<Model, ObservableList<MessageExt>> viewTable_stateColumn;
@Override
public void show(Stage stage) {
super.show(stage);
getTitle().set("合同合规验证");
}
public void onShown(WindowEvent windowEvent) {
super.onShown(windowEvent);
comm.setContractService(contractService);
viewTable.getScene().getStylesheets().add("/ui/contract/contract-verify.css");
LocalDate now = LocalDate.now();
setupDateBeginSelector.setValue(LocalDate.of(2024, 1, 1));
setupDateEndSelector.setValue(now);
viewTable_codeColumn.setCellValueFactory(param -> param.getValue().getCode());
viewTable_nameColumn.setCellValueFactory(param -> param.getValue().getName());
viewTable_employeeColumn.setCellValueFactory(param -> param.getValue().getEmployee());
viewTable_employeeColumn.setCellFactory(param -> new EmployeeTableCell());
viewTable_setupDateColumn.setCellValueFactory(param -> param.getValue().getSetupDate());
// viewTable_stateColumn.setCellValueFactory(param -> param.getValue().getMessages().map(messages -> {
// return messages.stream().map(Message::getMessage).collect(Collectors.joining(", "));
// }));
viewTable_stateColumn.setCellValueFactory(param -> param.getValue().getMessages());
viewTable_stateColumn.setCellFactory(param -> new StateTableCell());
viewTable.setItems(viewTableDataSet);
comm.getVerifyCompanyPath().bind(verifyCompanyPathChecker.selectedProperty());
comm.getVerifyCompanyStatus().bind(verifyCompanyStatusChecker.selectedProperty());
comm.getVerifyCompanyCredit().bind(verifyCompanyCreditChecker.selectedProperty());
comm.getVerifyVendor().bind(verifyVendorChecker.selectedProperty());
comm.getVerifyVendorFiles().bind(verifyVendorFileChecker.selectedProperty());
comm.getVerifyCustomer().bind(verifyCustomerChecker.selectedProperty());
comm.getVerifyCustomerFiles().bind(verifyCustomerFileChecker.selectedProperty());
comm.getVerifyCustomerSubContractDate().bind(verifyCustomerSubContractDateChecker.selectedProperty());
bindDoubleClicked(viewTable, this::showContract);
bindEnterPressed(viewTable, this::reVerifyContract);
}
/**
* 合同验证
*/
public void onVerifyAction(ActionEvent event) {
Button btn = (Button) event.getSource();
CompletableFuture<Void> future = runAsync(() -> {
viewTableDataSet.clear();
Pageable pageRequest = PageRequest.ofSize(200);
AtomicInteger counter = new AtomicInteger(0);
Specification<Contract> spec = (root, query, builder) -> {
return builder.and(
builder.or(
builder.equal(root.get("payWay"), ContractPayWay.RECEIVE),
builder.and(
builder.equal(root.get("payWay"), ContractPayWay.PAY),
builder.or(
builder.isNull(root.get("parentCode")),
builder.equal(root.get("parentCode"), "")
)
)
),
builder.between(root.get("setupDate"), setupDateBeginSelector.getValue(), setupDateEndSelector.getValue())
);
};
long total = contractService.count(spec);
setStatus("合同:" + total + "");
while (true) {
if (isCloseRequested()) {
break;
}
Page<Contract> page = contractService.findAll(spec, pageRequest);
for (Contract contract : page) {
if (isCloseRequested()) {
break;
}
counter.incrementAndGet();
Model model = new Model();
viewTableDataSet.add(model);
Employee handler = contract.getHandler();
if (handler == null) {
model.getEmployee().set(contract.getEmployee());
} else {
model.getEmployee().set(handler);
}
model.getCode().set(contract.getCode());
model.getName().set(contract.getName());
model.getSetupDate().set(contract.getSetupDate());
comm.verify(contract, model);
setStatus("合同验证进度:" + counter.get() + " / " + total);
// 移除中间消息
if (!model.getMessages().isEmpty()) {
model.getMessages().removeIf(msg -> msg.getLevel().intValue() <= Level.INFO.intValue());
}
if (model.getMessages().isEmpty()) {
if (onlyShowVerifiedChecker.isSelected()) {
viewTableDataSet.remove(model);
}
}
}
if (!page.hasNext()) {
break;
}
pageRequest = page.nextPageable();
}
setStatus("合同验证完成");
}).exceptionally(e -> {
setStatus(e.getMessage());
logger.error(e.getMessage(), e);
return null;
});
}
public void onContractReVerifyAction(ActionEvent event) {
Model selectedItem = viewTable.getSelectionModel().getSelectedItem();
if (selectedItem == null) {
return;
}
reVerifyContract(selectedItem);
}
private void reVerifyContract(Model model) {
String contractCode = model.getCode().get();
if (!StringUtils.hasText(contractCode)) {
return;
}
runAsync(() -> {
Contract contract = contractService.findByCode(contractCode);
if (contract == null) {
return;
}
model.getMessages().clear();
try {
comm.verify(contract, model);
// 移除中间消息
if (!model.getMessages().isEmpty()) {
model.getMessages().removeIf(msg -> msg.getLevel().intValue() <= Level.INFO.intValue());
}
} catch (Exception e) {
logger.error(model.getCode().get(), e);
model.error(e.getMessage());
}
if (model.getMessages().isEmpty()) {
Platform.runLater(() -> {
viewTableDataSet.remove(model);
});
}
});
}
public void onShowContractDetailAction(ActionEvent event) {
Model selectedItem = viewTable.getSelectionModel().getSelectedItem();
if (selectedItem == null) {
return;
}
showContract(selectedItem);
}
private void showContract(Model model) {
String contractCode = model.getCode().get();
if (!StringUtils.hasText(contractCode)) {
return;
}
Contract contract = contractService.findByCode(contractCode);
if (contract == null) {
return;
}
ContractWindowController.show(contract, viewTable.getScene().getWindow());
}
public void onExportVerifyResultAsFileAction(ActionEvent e) {
FileChooser chooser = new FileChooser();
chooser.setTitle("导出核验结果");
chooser.setInitialFileName("核验结果.xlsx");
File selected = chooser.showSaveDialog(viewTable.getScene().getWindow());
if (selected != null) {
ContractVerifyResultExportAsExcelFile task = new ContractVerifyResultExportAsExcelFile();
task.setDestFile(selected);
task.setModels(new ArrayList<>(viewTableDataSet));
UITools.showTaskDialogAndWait("导出中...", task, null);
}
}
}

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