Compare commits
14 Commits
0.0.45
...
7d684a5006
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d684a5006 | |||
| 8139a45f06 | |||
| cca51c6fcc | |||
| 1514cb0f9f | |||
| cf73769ef2 | |||
| c793c0925e | |||
| c69d3f1af2 | |||
| f810532824 | |||
| fb28bac53a | |||
| 9ff84ebe8a | |||
| 6711657663 | |||
| 17e326b35c | |||
|
|
fa25130c9f | ||
|
|
b0b67b5d7f |
53
docs/project_fund_plan_table.sql
Normal file
53
docs/project_fund_plan_table.sql
Normal file
@@ -0,0 +1,53 @@
|
||||
-- 项目资金计划表结构
|
||||
CREATE TABLE `PROJECT_FUND_PLAN` (
|
||||
`ID` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`PROJECT_ID` int DEFAULT NULL COMMENT '项目ID',
|
||||
`PAY_DATE` date DEFAULT NULL COMMENT '付款日期',
|
||||
`PAY_WAY` int DEFAULT NULL COMMENT '付款方式',
|
||||
`PAY_RATIO` float DEFAULT NULL COMMENT '付款比例',
|
||||
`PAY_CURRENCY` double DEFAULT NULL COMMENT '付款金额',
|
||||
`PAY_TERM` varchar(255) DEFAULT NULL COMMENT '付款条件',
|
||||
`CONTRACT_PAY_PLAN_ID` int DEFAULT NULL COMMENT '合同付款计划ID',
|
||||
`UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期',
|
||||
PRIMARY KEY (`ID`),
|
||||
KEY `FK_PROJECT_FUND_PLAN_PROJECT` (`PROJECT_ID`),
|
||||
KEY `FK_PROJECT_FUND_PLAN_CONTRACT_PAY_PLAN` (`CONTRACT_PAY_PLAN_ID`),
|
||||
CONSTRAINT `FK_PROJECT_FUND_PLAN_PROJECT` FOREIGN KEY (`PROJECT_ID`) REFERENCES `PROJECT` (`ID`),
|
||||
CONSTRAINT `FK_PROJECT_FUND_PLAN_CONTRACT_PAY_PLAN` FOREIGN KEY (`CONTRACT_PAY_PLAN_ID`) REFERENCES `CONTRACT_PAY_PLAN` (`ID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='项目资金计划';
|
||||
|
||||
/** Alert 增加 PAY_WAY **/
|
||||
ALTER TABLE `PROJECT_FUND_PLAN`
|
||||
ADD COLUMN `PAY_WAY` int DEFAULT NULL COMMENT '付款方式';
|
||||
|
||||
-- 项目投标表结构 (参考)
|
||||
CREATE TABLE `PROJECT_BID` (
|
||||
`ID` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`PROJECT_ID` int DEFAULT NULL COMMENT '项目ID',
|
||||
`LEVEL` int NOT NULL COMMENT '客户资信等级',
|
||||
`AMOUNT` double DEFAULT NULL COMMENT '报价金额',
|
||||
`CUS_EVAL_FILE_ID` int DEFAULT NULL COMMENT '评价表单文件ID',
|
||||
`COST_ID` int DEFAULT NULL COMMENT '成本ID',
|
||||
`STANDARD_PAY_WAY` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否标准付款方式',
|
||||
`NO_STANDARD_PAY_WAY_TEXT` varchar(255) DEFAULT NULL COMMENT '非标准付款方式文本',
|
||||
`STANDARD_CONTRACT_TEXT` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否标准合同文本',
|
||||
`NO_STANDARD_CONTRACT_TEXT` varchar(255) DEFAULT NULL COMMENT '非标准合同文本',
|
||||
`AUTHORIZER_FILE` varchar(255) DEFAULT NULL COMMENT '审核文件',
|
||||
`BID_ACCEPTANCE_LETTER_FILE` varchar(255) DEFAULT NULL COMMENT '中标通知书文件',
|
||||
`APPLICANT_ID` int DEFAULT NULL COMMENT '申请人ID',
|
||||
`APPLY_DATE` datetime DEFAULT NULL COMMENT '申请日期',
|
||||
`AUTHORIZER_ID` int DEFAULT NULL COMMENT '审核人ID',
|
||||
`AUTHORIZER_DATE` datetime DEFAULT NULL COMMENT '审核时间',
|
||||
`DESCRIPTION` text COMMENT '说明',
|
||||
PRIMARY KEY (`ID`),
|
||||
KEY `FK_PROJECT_BID_PROJECT` (`PROJECT_ID`),
|
||||
KEY `FK_PROJECT_BID_CUS_EVAL_FILE` (`CUS_EVAL_FILE_ID`),
|
||||
KEY `FK_PROJECT_BID_COST` (`COST_ID`),
|
||||
KEY `FK_PROJECT_BID_APPLICANT` (`APPLICANT_ID`),
|
||||
KEY `FK_PROJECT_BID_AUTHORIZER` (`AUTHORIZER_ID`),
|
||||
CONSTRAINT `FK_PROJECT_BID_PROJECT` FOREIGN KEY (`PROJECT_ID`) REFERENCES `PROJECT` (`ID`),
|
||||
CONSTRAINT `FK_PROJECT_BID_CUS_EVAL_FILE` FOREIGN KEY (`CUS_EVAL_FILE_ID`) REFERENCES `COMPANY_CUSTOMER_EVALUATION_FORM_FILE` (`ID`),
|
||||
CONSTRAINT `FK_PROJECT_BID_COST` FOREIGN KEY (`COST_ID`) REFERENCES `PROJECT_COST` (`ID`),
|
||||
CONSTRAINT `FK_PROJECT_BID_APPLICANT` FOREIGN KEY (`APPLICANT_ID`) REFERENCES `EMPLOYEE` (`ID`),
|
||||
CONSTRAINT `FK_PROJECT_BID_AUTHORIZER` FOREIGN KEY (`AUTHORIZER_ID`) REFERENCES `EMPLOYEE` (`ID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='项目投标';
|
||||
2
pom.xml
2
pom.xml
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
<groupId>com.ecep.contract</groupId>
|
||||
<artifactId>Contract-Manager</artifactId>
|
||||
<version>0.0.45-SNAPSHOT</version>
|
||||
<version>0.0.47-SNAPSHOT</version>
|
||||
<name>Contract-Manager</name>
|
||||
<description>Contract-Manager</description>
|
||||
<url/>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ecep.contract.manager;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -8,22 +9,28 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.model.Employee;
|
||||
import com.ecep.contract.manager.ds.other.model.EmployeeRole;
|
||||
import com.ecep.contract.manager.ds.other.service.EmployeeService;
|
||||
import com.ecep.contract.manager.ds.other.vo.EmployeeViewModel;
|
||||
import com.ecep.contract.manager.util.MyDateTimeUtils;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.util.converter.CurrencyStringConverter;
|
||||
import javafx.util.converter.LocalDateStringConverter;
|
||||
import javafx.util.converter.LocalDateTimeStringConverter;
|
||||
import javafx.util.converter.NumberStringConverter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 当前登录用户
|
||||
*/
|
||||
@ToString(of = {"id", "name", "email", "phone", "roles"})
|
||||
@ToString(callSuper = false, exclude = "roles")
|
||||
public class CurrentEmployee extends EmployeeViewModel {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CurrentEmployee.class);
|
||||
/**
|
||||
@@ -34,24 +41,89 @@ public class CurrentEmployee extends EmployeeViewModel {
|
||||
* 角色
|
||||
*/
|
||||
private SimpleListProperty<EmployeeRole> roles = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||
|
||||
private DateTimeFormatter dateFormatter = DateTimeFormatter
|
||||
.ofPattern(MyDateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN);
|
||||
private DateTimeFormatter dateTimeFormatter = DateTimeFormatter
|
||||
.ofPattern(MyDateTimeUtils.DEFAULT_DATETIME_FORMAT_PATTERN);
|
||||
private DateTimeFormatter timeFormatter = DateTimeFormatter
|
||||
.ofPattern(MyDateTimeUtils.DEFAULT_TIME_FORMAT_PATTERN);
|
||||
|
||||
private LocalDateStringConverter localDateStringConverter = new LocalDateStringConverter(
|
||||
dateFormatter, null);
|
||||
private LocalDateTimeStringConverter localDateTimeStringConverter = new LocalDateTimeStringConverter(
|
||||
dateTimeFormatter, null);
|
||||
|
||||
private NumberStringConverter numberStringConverter = new NumberStringConverter("#,##0.00");
|
||||
private CurrencyStringConverter currencyStringConverter = new CurrencyStringConverter("#,##0.00");
|
||||
|
||||
/**
|
||||
* 是否系统管理员
|
||||
*/
|
||||
public boolean isSystemAdministrator() {
|
||||
return roles.stream().anyMatch(EmployeeRole::isSystemAdministrator);
|
||||
}
|
||||
|
||||
/**
|
||||
* 语言环境属性
|
||||
*/
|
||||
public SimpleObjectProperty<Locale> localeProperty() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色属性
|
||||
*/
|
||||
public SimpleListProperty<EmployeeRole> rolesProperty() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFrom(Employee v) {
|
||||
super.updateFrom(v);
|
||||
|
||||
// 根据用户的个人配置修改
|
||||
if (StringUtils.hasText(v.getLocale())) {
|
||||
try {
|
||||
localeProperty().set(Locale.forLanguageTag(v.getLocale()));
|
||||
} catch (Exception e) {
|
||||
handleException("解析设置用户区域设置失败," + v.getLocale(), e);
|
||||
}
|
||||
}
|
||||
if (StringUtils.hasText(v.getDateFormatter())) {
|
||||
try {
|
||||
dateFormatter = DateTimeFormatter.ofPattern(v.getDateFormatter());
|
||||
localDateStringConverter = new LocalDateStringConverter(dateFormatter, null);
|
||||
} catch (Exception e) {
|
||||
handleException("解析设置用户日期格式失败," + v.getDateFormatter(), e);
|
||||
}
|
||||
}
|
||||
if (StringUtils.hasText(v.getDateTimeFormatter())) {
|
||||
try {
|
||||
dateTimeFormatter = DateTimeFormatter.ofPattern(v.getDateTimeFormatter());
|
||||
localDateTimeStringConverter = new LocalDateTimeStringConverter(dateTimeFormatter, null);
|
||||
} catch (Exception e) {
|
||||
handleException("解析设置用户日期时间格式失败," + v.getDateTimeFormatter(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(v.getNumberFormatter())) {
|
||||
try {
|
||||
numberStringConverter = new NumberStringConverter(localeProperty().get(), v.getNumberFormatter());
|
||||
} catch (Exception e) {
|
||||
handleException("解析设置用户数字格式失败," + v.getNumberFormatter(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(v.getCurrencyFormatter())) {
|
||||
try {
|
||||
currencyStringConverter = new CurrencyStringConverter(localeProperty().get(), v.getCurrencyFormatter());
|
||||
} catch (Exception e) {
|
||||
handleException("解析设置用户货币格式失败," + v.getCurrencyFormatter(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
@@ -92,4 +164,24 @@ public class CurrentEmployee extends EmployeeViewModel {
|
||||
}, 10, 10, TimeUnit.SECONDS);
|
||||
return future;
|
||||
}
|
||||
|
||||
private void handleException(String msg, Exception e) {
|
||||
logger.warn(msg, e);
|
||||
}
|
||||
|
||||
public LocalDateStringConverter getLocalDateStringConverter() {
|
||||
return localDateStringConverter;
|
||||
}
|
||||
|
||||
public LocalDateTimeStringConverter getLocalDateTimeStringConverter() {
|
||||
return localDateTimeStringConverter;
|
||||
}
|
||||
|
||||
public NumberStringConverter getNumberStringConverter() {
|
||||
return numberStringConverter;
|
||||
}
|
||||
|
||||
public CurrencyStringConverter getCurrencyStringConverter() {
|
||||
return currencyStringConverter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
package com.ecep.contract.manager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.controller.LoginWidowController;
|
||||
import com.ecep.contract.manager.ui.BaseController;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.task.TaskMonitorCenter;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
@@ -19,18 +37,6 @@ import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import lombok.Getter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* JavaFx 应用程序
|
||||
@@ -122,6 +128,10 @@ public class Desktop extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> runAsync(Runnable runnable) {
|
||||
return CompletableFuture.runAsync(runnable, getExecutorService());
|
||||
}
|
||||
|
||||
private void startSpringApp(Stage primaryStage, Parent root, FXMLLoader loader) {
|
||||
System.out.println("Desktop.startSpringApp");
|
||||
// 更新窗口标题
|
||||
@@ -158,7 +168,7 @@ public class Desktop extends Application {
|
||||
|
||||
holder.info("启动中,请稍后...");
|
||||
|
||||
CompletableFuture.runAsync(() -> {
|
||||
runAsync(() -> {
|
||||
try {
|
||||
//
|
||||
holder.info("读取配置文件...");
|
||||
@@ -176,7 +186,7 @@ public class Desktop extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
CompletableFuture.runAsync(() -> {
|
||||
runAsync(() -> {
|
||||
SpringApp.launch(properties, holder);
|
||||
ConfigurableListableBeanFactory beanFactory = SpringApp.context.getBeanFactory();
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public class SpringApp {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
// 在这里调用 startup 性能分析
|
||||
analyzeStartupPerformance(startup);
|
||||
});
|
||||
}, Desktop.instance.getExecutorService());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.ecep.contract.manager.ds.company.repository.CompanyContactRepository;
|
||||
import com.ecep.contract.manager.ds.company.repository.CompanyOldNameRepository;
|
||||
import com.ecep.contract.manager.ds.contract.ContractFileType;
|
||||
import com.ecep.contract.manager.ds.other.repository.SysConfRepository;
|
||||
import com.ecep.contract.manager.ds.other.service.SysConfService;
|
||||
import com.ecep.contract.manager.ds.company.repository.CompanyFileRepository;
|
||||
import com.ecep.contract.manager.ds.contract.model.Contract;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractFile;
|
||||
@@ -73,7 +74,7 @@ public class OldVersionService {
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
@Autowired
|
||||
private SysConfRepository confRepository;
|
||||
private SysConfService confService;
|
||||
@Lazy
|
||||
@Autowired
|
||||
private CompanyService companyService;
|
||||
@@ -215,7 +216,7 @@ public class OldVersionService {
|
||||
logger.debug("createSyncTask");
|
||||
}
|
||||
|
||||
boolean autoSyncEnable = confRepository.get("cloud.old.auto_sync.enable", false);
|
||||
boolean autoSyncEnable = confService.getBoolean("cloud.old.auto_sync.enable");
|
||||
if (!autoSyncEnable) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ public class CloudRkService implements ViewModelService<CloudRk, CloudRkInfoView
|
||||
executorService.schedule(() -> {
|
||||
// 定时 30分钟 运行一次
|
||||
executorService.scheduleAtFixedRate(() -> {
|
||||
Desktop.instance.getTaskMonitorCenter().registerTask(new CloudRkSyncTask()).submit();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(new CloudRkSyncTask());
|
||||
}, 0, 30, TimeUnit.MINUTES);
|
||||
}, 1, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package com.ecep.contract.manager.cloud.tyc;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.cloud.CloudInfo;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.other.repository.SysConfRepository;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.ViewModelService;
|
||||
import com.ecep.contract.manager.util.MyStringUtils;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
import javafx.application.Platform;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -20,10 +16,16 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.cloud.CloudInfo;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.other.service.SysConfService;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.ViewModelService;
|
||||
import com.ecep.contract.manager.util.MyStringUtils;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
@@ -53,7 +55,6 @@ public class CloudTycService implements ViewModelService<CloudTyc, CloudTycInfoV
|
||||
@Autowired
|
||||
private CloudTycRepository cloudTycRepository;
|
||||
|
||||
|
||||
public CloudTyc getOrCreateCloudTyc(CloudInfo info) {
|
||||
Optional<CloudTyc> optional = cloudTycRepository.findById(info.getId());
|
||||
return optional.orElseGet(() -> getOrCreateCloudTyc(info.getCompany()));
|
||||
@@ -98,7 +99,6 @@ public class CloudTycService implements ViewModelService<CloudTyc, CloudTycInfoV
|
||||
return rk;
|
||||
}
|
||||
|
||||
|
||||
// 查询有 Score 的记录
|
||||
List<CloudTyc> hasLatestList = hasCouldIdList.stream().filter(v -> {
|
||||
return v.getScore() != null && v.getScore() > 0;
|
||||
@@ -148,7 +148,7 @@ public class CloudTycService implements ViewModelService<CloudTyc, CloudTycInfoV
|
||||
}
|
||||
|
||||
public void showInBrowse(String cloudId) {
|
||||
String baseUrl = SpringApp.getBean(SysConfRepository.class).get("cloud.tyc.company");
|
||||
String baseUrl = SpringApp.getBean(SysConfService.class).getString("cloud.tyc.company");
|
||||
if (!StringUtils.hasText(baseUrl)) {
|
||||
UITools.showAlertAndWait("系统参数 cloud.tyc.company 未配置");
|
||||
return;
|
||||
@@ -162,7 +162,6 @@ public class CloudTycService implements ViewModelService<CloudTyc, CloudTycInfoV
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void deleteByCompany(Company company) {
|
||||
int deleted = cloudTycRepository.deleteAllByCompany(company);
|
||||
if (deleted > 0) {
|
||||
@@ -192,7 +191,6 @@ public class CloudTycService implements ViewModelService<CloudTyc, CloudTycInfoV
|
||||
return cloudTycRepository.findAll(spec, pageable);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Specification<CloudTyc> getSpecification(String searchText) {
|
||||
if (!StringUtils.hasText(searchText)) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -12,14 +12,15 @@ import org.springframework.beans.BeansException;
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractGroup;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractGroupService;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.Tasker;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步合同分组
|
||||
*/
|
||||
public class ContractGroupSyncTask extends Task<Object> {
|
||||
public class ContractGroupSyncTask extends Tasker<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractGroupSyncTask.class);
|
||||
@Setter
|
||||
private ContractGroupService contractGroupService;
|
||||
@@ -36,29 +37,29 @@ public class ContractGroupSyncTask extends Task<Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object call() throws Exception {
|
||||
YongYouU8Repository repository = null;
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
YongYouU8Service service = null;
|
||||
try {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
service = SpringApp.getBean(YongYouU8Service.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Repository", e);
|
||||
logger.error("can't get bean of YongYouU8Service", e);
|
||||
holder.error("can't get bean of YongYouU8Service");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
updateMessage("读取 U8 系统 CM_Group 数据表...");
|
||||
List<Map<String, Object>> list = repository.queryAllContractGroup();
|
||||
logger.info("读取 U8 系统 CM_Group 数据表...");
|
||||
List<Map<String, Object>> list = service.queryAllContractGroup();
|
||||
int size = list.size();
|
||||
updateMessage("总共读取 CM_Group 数据 " + size + " 条");
|
||||
holder.debug("总共读取 CM_Group 数据 " + size + " 条");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
updateMessage("Cancelled");
|
||||
holder.info("Cancelled");
|
||||
return null;
|
||||
}
|
||||
sync(map, msg -> {
|
||||
updateMessage(counter.get() + "/" + size + ">" + msg);
|
||||
});
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">" );
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
@@ -66,7 +67,7 @@ public class ContractGroupSyncTask extends Task<Object> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sync(Map<String, Object> map, Consumer<String> consumer) {
|
||||
private void sync(Map<String, Object> map, MessageHolder holder) {
|
||||
boolean modified = false;
|
||||
|
||||
String groupCode = (String) map.get("cGroupID");
|
||||
@@ -77,26 +78,28 @@ public class ContractGroupSyncTask extends Task<Object> {
|
||||
ContractGroup contractGroup = service.findByCode(groupCode);
|
||||
if (contractGroup == null) {
|
||||
contractGroup = service.newContractGroup();
|
||||
consumer.accept("新建合同分组:" + groupCode);
|
||||
holder.info("新建合同分组:" + groupCode);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(contractGroup.getCode(), groupCode)) {
|
||||
contractGroup.setCode(groupCode);
|
||||
holder.info("合同分组代码:" + contractGroup.getCode() + " -> " + groupCode);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractGroup.getName(), groupName)) {
|
||||
contractGroup.setName(groupName);
|
||||
holder.info("合同分组名称:" + contractGroup.getName() + " -> " + groupName);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractGroup.getTitle(), groupTitle)) {
|
||||
contractGroup.setTitle(groupTitle);
|
||||
holder.info("合同分组标题:" + contractGroup.getTitle() + " -> " + groupTitle);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
service.save(contractGroup);
|
||||
consumer.accept("更新" + contractGroup.getName() + " 信息");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractKind;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractKindService;
|
||||
import javafx.concurrent.Task;
|
||||
import lombok.Setter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractKind;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractKindService;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.Tasker;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步合同分类
|
||||
*/
|
||||
public class ContractKindSyncTask extends Task<Object> {
|
||||
public class ContractKindSyncTask extends Tasker<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractKindSyncTask.class);
|
||||
@Setter
|
||||
private ContractKindService contractKindService;
|
||||
@@ -36,29 +37,29 @@ public class ContractKindSyncTask extends Task<Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object call() throws Exception {
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
YongYouU8Repository repository = null;
|
||||
try {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Repository", e);
|
||||
holder.error("can't get bean of YongYouU8Repository");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
updateMessage("读取 U8 系统 CM_Kind 数据表...");
|
||||
logger.info("读取 U8 系统 CM_Kind 数据表...");
|
||||
List<Map<String, Object>> list = repository.queryAllContractKind();
|
||||
int size = list.size();
|
||||
updateMessage("总共读取 CM_Kind 数据 " + size + " 条");
|
||||
holder.debug("总共读取 CM_Kind 数据 " + size + " 条");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
updateMessage("Cancelled");
|
||||
holder.info("Cancelled");
|
||||
return null;
|
||||
}
|
||||
sync(map, msg -> {
|
||||
updateMessage(counter.get() + "/" + size + ">" + msg);
|
||||
});
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">");
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
@@ -66,7 +67,7 @@ public class ContractKindSyncTask extends Task<Object> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sync(Map<String, Object> map, Consumer<String> consumer) {
|
||||
private void sync(Map<String, Object> map, MessageHolder holder) {
|
||||
boolean modified = false;
|
||||
|
||||
String typeCode = (String) map.get("KindID");
|
||||
@@ -77,26 +78,29 @@ public class ContractKindSyncTask extends Task<Object> {
|
||||
ContractKind contractKind = kindService.findByCode(typeCode);
|
||||
if (contractKind == null) {
|
||||
contractKind = new ContractKind();
|
||||
consumer.accept("新建合同分类:" + typeCode);
|
||||
holder.info("新建合同分类:" + typeCode);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(contractKind.getCode(), typeCode)) {
|
||||
contractKind.setCode(typeCode);
|
||||
holder.info("合同分类代码:" + contractKind.getCode() + " -> " + typeCode);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractKind.getName(), typeName)) {
|
||||
contractKind.setName(typeName);
|
||||
holder.info("合同分类名称:" + contractKind.getName() + " -> " + typeName);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractKind.getTitle(), typeTitle)) {
|
||||
contractKind.setTitle(typeTitle);
|
||||
holder.info("合同分类描述:" + contractKind.getTitle() + " -> " + typeTitle);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
kindService.save(contractKind);
|
||||
consumer.accept("更新" + contractKind.getName() + " 信息");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractService;
|
||||
import com.ecep.contract.manager.ds.contract.tasker.AbstContractRepairTasker;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import lombok.Setter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
@@ -16,21 +7,45 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.cloud.u8.ctx.ContractCtx;
|
||||
import com.ecep.contract.manager.ds.contract.tasker.AbstContractRepairTasker;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
|
||||
/**
|
||||
* 合同同步任务
|
||||
*/
|
||||
public class ContractSyncTask extends AbstContractRepairTasker {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractSyncTask.class);
|
||||
@Setter
|
||||
private boolean useLatestId = true;
|
||||
private YongYouU8Repository repository;
|
||||
|
||||
public ContractSyncTask() {
|
||||
updateTitle("用友U8系统-同步合同");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repair(MessageHolder holder) {
|
||||
updateTitle("用友U8系统-同步合同");
|
||||
try {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
} catch (BeansException e) {
|
||||
holder.error("无法获取 YongYouU8Repository " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
if (getConfService().getBoolean(ContractCtx.KEY_SYNC_USE_LATEST_ID)) {
|
||||
syncByLatestId(holder);
|
||||
} else {
|
||||
syncByLatestDate(holder);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncByLatestId(MessageHolder holder) {
|
||||
int latestId = getConfService().getInt(ContractService.CONTRACT_LATEST_ID);
|
||||
int latestId = getConfService().getInt(ContractCtx.KEY_SYNC_BY_LATEST_ID);
|
||||
updateTitle("用友U8系统-同步合同,从 " + latestId + " 开始");
|
||||
|
||||
Long total = repository.countAllContracts(latestId);
|
||||
@@ -66,11 +81,11 @@ public class ContractSyncTask extends AbstContractRepairTasker {
|
||||
updateProgress(counter.incrementAndGet(), total);
|
||||
});
|
||||
}
|
||||
getConfService().set(ContractService.CONTRACT_LATEST_ID, String.valueOf(reference.get()));
|
||||
getConfService().set(ContractCtx.KEY_SYNC_BY_LATEST_ID, String.valueOf(reference.get()));
|
||||
}
|
||||
|
||||
private void syncByLatestDate(MessageHolder holder) {
|
||||
String strDateTime = getConfService().getString(ContractService.CONTRACT_LATEST_DATE);
|
||||
String strDateTime = getConfService().getString(ContractCtx.KEY_SYNC_BY_LATEST_DATE);
|
||||
LocalDateTime latestDateTime = null;
|
||||
if (StringUtils.hasText(strDateTime)) {
|
||||
try {
|
||||
@@ -120,17 +135,7 @@ public class ContractSyncTask extends AbstContractRepairTasker {
|
||||
updateProgress(counter.incrementAndGet(), total);
|
||||
});
|
||||
}
|
||||
getConfService().set(ContractService.CONTRACT_LATEST_DATE, String.valueOf(reference.get()));
|
||||
getConfService().set(ContractCtx.KEY_SYNC_BY_LATEST_DATE, String.valueOf(reference.get()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void repair(MessageHolder holder) {
|
||||
updateTitle("用友U8系统-同步合同");
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
if (useLatestId) {
|
||||
syncByLatestId(holder);
|
||||
} else {
|
||||
syncByLatestDate(holder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractType;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractTypeService;
|
||||
import javafx.concurrent.Task;
|
||||
import lombok.Setter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractType;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractTypeService;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.Tasker;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步合同类型
|
||||
*/
|
||||
public class ContractTypeSyncTask extends Task<Object> {
|
||||
public class ContractTypeSyncTask extends Tasker<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractTypeSyncTask.class);
|
||||
@Setter
|
||||
private ContractTypeService contractTypeService;
|
||||
@@ -36,29 +37,29 @@ public class ContractTypeSyncTask extends Task<Object> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object call() throws Exception {
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
YongYouU8Repository repository = null;
|
||||
try {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Repository", e);
|
||||
logger.error("can't get bean of YongYouU8Service", e);
|
||||
holder.error("can't get bean of YongYouU8Service");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
updateMessage("读取 U8 系统 CM_Type,CM_TypeClass 数据表...");
|
||||
logger.info("读取 U8 系统 CM_Type,CM_TypeClass 数据表...");
|
||||
List<Map<String, Object>> list = repository.queryAllContractType();
|
||||
int size = list.size();
|
||||
updateMessage("总共读取 CM_Type,CM_TypeClass 数据 " + size + " 条");
|
||||
holder.debug("总共读取 CM_Type,CM_TypeClass 数据 " + size + " 条");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
updateMessage("Cancelled");
|
||||
holder.info("Cancelled");
|
||||
return null;
|
||||
}
|
||||
sync(map, msg -> {
|
||||
updateMessage(counter.get() + "/" + size + ">" + msg);
|
||||
});
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">" );
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
@@ -66,7 +67,7 @@ public class ContractTypeSyncTask extends Task<Object> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sync(Map<String, Object> map, Consumer<String> consumer) {
|
||||
private void sync(Map<String, Object> map, MessageHolder holder) {
|
||||
boolean modified = false;
|
||||
|
||||
String typeCode = (String) map.get("cTypeCode");
|
||||
@@ -79,34 +80,39 @@ public class ContractTypeSyncTask extends Task<Object> {
|
||||
ContractType contractType = typeService.findByCode(typeCode);
|
||||
if (contractType == null) {
|
||||
contractType = new ContractType();
|
||||
consumer.accept("新建合同类型:" + typeCode);
|
||||
holder.info("新建合同类型:" + typeCode);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(contractType.getCode(), typeCode)) {
|
||||
contractType.setCode(typeCode);
|
||||
holder.info("合同类型代码:" + contractType.getCode() + " -> " + typeCode);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractType.getName(), typeName)) {
|
||||
contractType.setName(typeName);
|
||||
holder.info("合同类型名称:" + contractType.getName() + " -> " + typeName);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractType.getTitle(), typeTitle)) {
|
||||
contractType.setTitle(typeTitle);
|
||||
holder.info("合同类型标题:" + contractType.getTitle() + " -> " + typeTitle);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractType.getCatalog(), typeCatalog)) {
|
||||
contractType.setTitle(typeTitle);
|
||||
contractType.setCatalog(typeCatalog);
|
||||
holder.info("合同类型分类:" + contractType.getCatalog() + " -> " + typeCatalog);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(contractType.getDirection(), typeDirection)) {
|
||||
contractType.setTitle(typeTitle);
|
||||
contractType.setDirection(typeDirection);
|
||||
holder.info("合同类型方向:" + contractType.getDirection() + " -> " + typeDirection);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
typeService.save(contractType);
|
||||
consumer.accept("更新" + contractType.getName() + " 信息");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,70 +1,99 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.customer.model.CustomerCatalog;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
|
||||
import javafx.concurrent.Task;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.customer.model.CustomerCatalog;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.Tasker;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步客户分类
|
||||
*/
|
||||
public class CustomerClassSyncTask extends Task<Object> {
|
||||
public class CustomerClassSyncTask extends Tasker<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CustomerClassSyncTask.class);
|
||||
@Setter
|
||||
private CompanyCustomerService companyCustomerService;
|
||||
|
||||
public CustomerClassSyncTask() {
|
||||
updateTitle("用友U8系统-同步客户分类信息");
|
||||
}
|
||||
|
||||
CompanyCustomerService getCompanyCustomerService() {
|
||||
if (companyCustomerService == null) {
|
||||
companyCustomerService = SpringApp.getBean(CompanyCustomerService.class);
|
||||
}
|
||||
return companyCustomerService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object call() throws Exception {
|
||||
YongYouU8Service service = SpringApp.getBean(YongYouU8Service.class);
|
||||
CompanyCustomerService customerService = SpringApp.getBean(CompanyCustomerService.class);
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
YongYouU8Repository repository = null;
|
||||
try {
|
||||
repository = SpringApp.getBean(YongYouU8Repository.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Repository", e);
|
||||
holder.error("can't get bean of YongYouU8Repository");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
updateMessage("读取 U8 系统 CustomerClass 数据表...");
|
||||
List<Map<String, Object>> list = service.queryAllCustomerClass();
|
||||
logger.info("读取 U8 系统 CustomerClass 数据表...");
|
||||
List<Map<String, Object>> list = repository.queryAllCustomerClass();
|
||||
int size = list.size();
|
||||
updateMessage("总共读取 CustomerClass 数据 " + size + " 条");
|
||||
holder.debug("总共读取 CustomerClass 数据 " + size + " 条");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
updateMessage("Cancelled");
|
||||
holder.info("Cancelled");
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean modified = false;
|
||||
|
||||
String code = (String) map.get("cCCCode");
|
||||
String name = (String) map.get("cCCName");
|
||||
|
||||
CustomerCatalog customerCatalog = customerService.findCatalogByCode(code);
|
||||
if (customerCatalog == null) {
|
||||
customerCatalog = new CustomerCatalog();
|
||||
updateMessage("新建客户分类:" + code);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(customerCatalog.getCode(), code)) {
|
||||
customerCatalog.setCode(code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(customerCatalog.getName(), name)) {
|
||||
customerCatalog.setName(name);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
customerService.save(customerCatalog);
|
||||
updateMessage("更新" + customerCatalog.getName() + " 信息");
|
||||
}
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">" );
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sync(Map<String, Object> map, MessageHolder holder) {
|
||||
boolean modified = false;
|
||||
|
||||
String code = (String) map.get("cCCCode");
|
||||
String name = (String) map.get("cCCName");
|
||||
|
||||
CompanyCustomerService customerService = getCompanyCustomerService();
|
||||
CustomerCatalog customerCatalog = customerService.findCatalogByCode(code);
|
||||
if (customerCatalog == null) {
|
||||
customerCatalog = new CustomerCatalog();
|
||||
holder.info("新建客户分类:" + code);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(customerCatalog.getCode(), code)) {
|
||||
customerCatalog.setCode(code);
|
||||
holder.info("客户分类代码:" + customerCatalog.getCode() + " -> " + code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(customerCatalog.getName(), name)) {
|
||||
customerCatalog.setName(name);
|
||||
holder.info("客户分类名称:" + customerCatalog.getName() + " -> " + name);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
customerService.save(customerCatalog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.cloud.CloudBaseInfo;
|
||||
import com.ecep.contract.manager.cloud.CloudInfo;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.Tasker;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 数据迁移任务,从CloudInfo迁移到CloudYu
|
||||
*/
|
||||
public class DateTransferTask extends Tasker<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DateTransferTask.class);
|
||||
@Setter
|
||||
private YongYouU8Service yongYouU8Service;
|
||||
|
||||
public DateTransferTask() {
|
||||
updateTitle("用友U8系统-数据迁移任务");
|
||||
}
|
||||
|
||||
YongYouU8Service getYongYouU8Service() {
|
||||
if (yongYouU8Service == null) {
|
||||
yongYouU8Service = SpringApp.getBean(YongYouU8Service.class);
|
||||
}
|
||||
return yongYouU8Service;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
YongYouU8Service u8Service = null;
|
||||
try {
|
||||
u8Service = getYongYouU8Service();
|
||||
} catch (BeansException e) {
|
||||
logger.error("获取用友U8服务失败", e);
|
||||
holder.error("获取用友U8服务失败");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
logger.info("开始数据迁移任务...");
|
||||
Iterable<CloudInfo> cloudInfos = u8Service.findAllCloudYu();
|
||||
|
||||
// 计算总数
|
||||
int total = 0;
|
||||
for (@SuppressWarnings("unused")
|
||||
CloudInfo info : cloudInfos) {
|
||||
total++;
|
||||
}
|
||||
holder.debug("总共需要迁移的数据量: " + total + " 条");
|
||||
|
||||
// 重新获取Iterable以进行遍历
|
||||
cloudInfos = u8Service.findAllCloudYu();
|
||||
|
||||
for (CloudInfo v : cloudInfos) {
|
||||
if (isCancelled()) {
|
||||
holder.info("迁移任务已取消");
|
||||
return null;
|
||||
}
|
||||
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + total + ">");
|
||||
try {
|
||||
sync(v, sub);
|
||||
} catch (Exception e) {
|
||||
sub.error("迁移失败: " + e.getMessage());
|
||||
logger.error("迁移数据失败", e);
|
||||
}
|
||||
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), total);
|
||||
}
|
||||
|
||||
holder.info("数据迁移任务完成");
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sync(CloudInfo v, MessageHolder holder) {
|
||||
YongYouU8Service u8Service = getYongYouU8Service();
|
||||
CloudYu cloudYu = u8Service.getOrCreateCloudYu(v);
|
||||
|
||||
if (copyTo(v, cloudYu)) {
|
||||
u8Service.save(cloudYu);
|
||||
holder.info("成功迁移数据: " + v.getCloudId());
|
||||
} else {
|
||||
holder.debug("数据未变更,无需迁移: " + v.getCloudId());
|
||||
}
|
||||
}
|
||||
|
||||
boolean copyTo(CloudInfo v, CloudBaseInfo cloudRk) {
|
||||
boolean modified = false;
|
||||
if (!Objects.equals(cloudRk.getLatestUpdate(), v.getLatestUpdate())) {
|
||||
cloudRk.setLatestUpdate(v.getLatestUpdate());
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(cloudRk.getCloudId(), v.getCloudId())) {
|
||||
cloudRk.setCloudId(v.getCloudId());
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(cloudRk.getCompany(), v.getCompany())) {
|
||||
cloudRk.setCompany(v.getCompany());
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +1,99 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.vendor.model.VendorCatalog;
|
||||
import com.ecep.contract.manager.ds.vendor.repository.VendorClassRepository;
|
||||
import javafx.concurrent.Task;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.vendor.model.VendorCatalog;
|
||||
import com.ecep.contract.manager.ds.vendor.repository.VendorClassRepository;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.ui.Tasker;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 同步供应商分类
|
||||
*/
|
||||
public class VendorClassSyncTask extends Task<Object> {
|
||||
public class VendorClassSyncTask extends Tasker<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(VendorClassSyncTask.class);
|
||||
@Setter
|
||||
private VendorClassRepository vendorClassRepository;
|
||||
|
||||
public VendorClassSyncTask() {
|
||||
updateTitle("用友U8系统-同步供应商分类信息");
|
||||
}
|
||||
|
||||
VendorClassRepository getVendorClassRepository() {
|
||||
if (vendorClassRepository == null) {
|
||||
vendorClassRepository = SpringApp.getBean(VendorClassRepository.class);
|
||||
}
|
||||
return vendorClassRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object call() throws Exception {
|
||||
YongYouU8Service service = SpringApp.getBean(YongYouU8Service.class);
|
||||
VendorClassRepository groupRepository = SpringApp.getBean(VendorClassRepository.class);
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
YongYouU8Service service = null;
|
||||
try {
|
||||
service = SpringApp.getBean(YongYouU8Service.class);
|
||||
} catch (BeansException e) {
|
||||
logger.error("can't get bean of YongYouU8Service", e);
|
||||
holder.error("can't get bean of YongYouU8Service");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
updateMessage("读取 U8 系统 VendorClass 数据表...");
|
||||
logger.info("读取 U8 系统 VendorClass 数据表...");
|
||||
List<Map<String, Object>> list = service.queryAllVendorClass();
|
||||
int size = list.size();
|
||||
updateMessage("总共读取 VendorClass 数据 " + size + " 条");
|
||||
holder.debug("总共读取 VendorClass 数据 " + size + " 条");
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
if (isCancelled()) {
|
||||
updateMessage("Cancelled");
|
||||
holder.info("Cancelled");
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean modified = false;
|
||||
|
||||
String code = (String) map.get("cVCCode");
|
||||
String name = (String) map.get("cVCName");
|
||||
|
||||
VendorCatalog vendorCatalog = groupRepository.findByCode(code).orElse(null);
|
||||
if (vendorCatalog == null) {
|
||||
vendorCatalog = new VendorCatalog();
|
||||
updateMessage("新建供应商分类:" + code);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(vendorCatalog.getCode(), code)) {
|
||||
vendorCatalog.setCode(code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(vendorCatalog.getName(), name)) {
|
||||
vendorCatalog.setName(name);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
groupRepository.save(vendorCatalog);
|
||||
updateMessage("更新" + vendorCatalog.getName() + " 信息");
|
||||
}
|
||||
MessageHolder sub = holder.sub(counter.get() + "/" + size + ">" );
|
||||
sync(map, sub);
|
||||
// 更新进度
|
||||
updateProgress(counter.incrementAndGet(), size);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sync(Map<String, Object> map, MessageHolder holder) {
|
||||
boolean modified = false;
|
||||
|
||||
String code = (String) map.get("cVCCode");
|
||||
String name = (String) map.get("cVCName");
|
||||
|
||||
VendorClassRepository repository = getVendorClassRepository();
|
||||
VendorCatalog vendorCatalog = repository.findByCode(code).orElse(null);
|
||||
if (vendorCatalog == null) {
|
||||
vendorCatalog = new VendorCatalog();
|
||||
holder.info("新建供应商分类:" + code);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(vendorCatalog.getCode(), code)) {
|
||||
vendorCatalog.setCode(code);
|
||||
holder.info("供应商分类代码:" + vendorCatalog.getCode() + " -> " + code);
|
||||
modified = true;
|
||||
}
|
||||
if (!Objects.equals(vendorCatalog.getName(), name)) {
|
||||
vendorCatalog.setName(name);
|
||||
holder.info("供应商分类名称:" + vendorCatalog.getName() + " -> " + name);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
repository.save(vendorCatalog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.ecep.contract.manager.cloud.u8.ctx.CompanyCtx;
|
||||
import com.ecep.contract.manager.cloud.u8.ctx.ContractCtx;
|
||||
import com.ecep.contract.manager.ds.other.BooleanConfig;
|
||||
import com.ecep.contract.manager.ds.other.LocalDateConfig;
|
||||
import com.ecep.contract.manager.ds.other.LocalDateTimeConfig;
|
||||
import com.ecep.contract.manager.ds.other.StringConfig;
|
||||
import com.ecep.contract.manager.ui.BaseController;
|
||||
import com.ecep.contract.manager.ui.FxmlPath;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.DatePicker;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.WindowEvent;
|
||||
|
||||
@Lazy
|
||||
@Scope("prototype")
|
||||
@Component
|
||||
@FxmlPath("/ui/cloud/u8_config.fxml")
|
||||
public class YongYouU8ConfigWindowController extends BaseController {
|
||||
@FXML
|
||||
private DatePicker auto_create_company_after;
|
||||
|
||||
@FXML
|
||||
private TextField contract_latest_date;
|
||||
|
||||
@FXML
|
||||
private TextField contract_latest_id;
|
||||
|
||||
@FXML
|
||||
private TextField sync_elapse;
|
||||
@FXML
|
||||
private ToggleSwitch use_latest_id;
|
||||
|
||||
LocalDateConfig config1 = new LocalDateConfig(CompanyCtx.AUTO_CREATE_COMPANY_AFTER);
|
||||
LocalDateTimeConfig config2 = new LocalDateTimeConfig(ContractCtx.KEY_SYNC_BY_LATEST_DATE);
|
||||
StringConfig config3 = new StringConfig(ContractCtx.KEY_SYNC_BY_LATEST_ID);
|
||||
StringConfig config4 = new StringConfig(ContractCtx.KEY_SYNC_ELAPSE);
|
||||
BooleanConfig config5 = new BooleanConfig(ContractCtx.KEY_SYNC_USE_LATEST_ID);
|
||||
|
||||
@Override
|
||||
public void onShown(WindowEvent windowEvent) {
|
||||
super.onShown(windowEvent);
|
||||
getTitle().set("用友U8配置");
|
||||
|
||||
auto_create_company_after.setConverter(getCurrentEmployee().getLocalDateStringConverter());
|
||||
config1.setControl(auto_create_company_after);
|
||||
config1.initialize();
|
||||
|
||||
config2.setControl(contract_latest_date);
|
||||
config2.setControlConverter(getCurrentEmployee().getLocalDateTimeStringConverter());
|
||||
config2.initialize();
|
||||
|
||||
config3.setControl(contract_latest_id);
|
||||
config3.initialize();
|
||||
|
||||
config4.setControl(sync_elapse);
|
||||
config4.initialize();
|
||||
|
||||
config5.setControl(use_latest_id);
|
||||
config5.initialize();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +1,23 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.cloud.CloudBaseInfo;
|
||||
import com.ecep.contract.manager.cloud.CloudInfo;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ui.AbstManagerWindowController;
|
||||
import com.ecep.contract.manager.ui.FxmlPath;
|
||||
import com.ecep.contract.manager.ui.Message;
|
||||
import com.ecep.contract.manager.ui.ViewModelService;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.stage.Stage;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
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.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.function.Consumer;
|
||||
import com.ecep.contract.manager.Desktop;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ui.AbstManagerWindowController;
|
||||
import com.ecep.contract.manager.ui.BaseController;
|
||||
import com.ecep.contract.manager.ui.FxmlPath;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@Lazy
|
||||
@Scope("prototype")
|
||||
@@ -38,9 +31,6 @@ public class YongYouU8ManagerWindowController
|
||||
show(YongYouU8ManagerWindowController.class, null);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
public TableColumn<CloudYuInfoViewModel, Number> idColumn;
|
||||
public TableColumn<CloudYuInfoViewModel, LocalDateTime> latestUpdateColumn;
|
||||
public TableColumn<CloudYuInfoViewModel, Company> companyColumn;
|
||||
@@ -58,73 +48,25 @@ public class YongYouU8ManagerWindowController
|
||||
return new YongYouU8ManagerSkin(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void show(Stage stage) {
|
||||
super.show(stage);
|
||||
getTitle().set("数据源:用友U8");
|
||||
getTitle().set("用友U8");
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开配置窗口
|
||||
*/
|
||||
public void onConfigAction(ActionEvent event) {
|
||||
BaseController.show(YongYouU8ConfigWindowController.class, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据迁移,从 CloudInfo 迁移到 CloudRk
|
||||
*/
|
||||
public void onDateTransferAction(ActionEvent event) {
|
||||
|
||||
CompletableFuture.runAsync(() -> {
|
||||
com.ecep.contract.manager.cloud.CloudInfoRepository cloudInfoRepository = SpringApp.getBean(com.ecep.contract.manager.cloud.CloudInfoRepository.class);
|
||||
YongYouU8Service u8Service = SpringApp.getBean(YongYouU8Service.class);
|
||||
|
||||
cloudInfoRepository.findAll().forEach(v -> {
|
||||
try {
|
||||
CloudYu cloudYu = u8Service.getOrCreateCloudYu(v);
|
||||
if (copyTo(v, cloudYu)) {
|
||||
u8Service.save(cloudYu);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
setStatus(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
boolean copyTo(CloudInfo v, CloudBaseInfo cloudRk) {
|
||||
boolean modified = false;
|
||||
if (!Objects.equals(cloudRk.getLatestUpdate(), v.getLatestUpdate())) {
|
||||
cloudRk.setLatestUpdate(v.getLatestUpdate());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(cloudRk.getCloudId(), v.getCloudId())) {
|
||||
cloudRk.setCloudId(v.getCloudId());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(cloudRk.getCompany(), v.getCompany())) {
|
||||
cloudRk.setCompany(v.getCompany());
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
private <T extends Task<Object>> void initializeTask(T task, String prefix, Consumer<String> consumer) {
|
||||
task.setOnScheduled(e -> {
|
||||
consumer.accept("正在从用友U8同步" + prefix + ",请稍后...");
|
||||
});
|
||||
task.setOnRunning(e -> {
|
||||
consumer.accept("开始同步" + prefix + "...");
|
||||
});
|
||||
task.setOnSucceeded(e -> {
|
||||
consumer.accept(prefix + "同步完成...");
|
||||
});
|
||||
task.exceptionProperty().addListener((observable, oldValue, newValue) -> {
|
||||
consumer.accept(newValue.getMessage());
|
||||
logger.error("同步{}发生异常", prefix, newValue);
|
||||
});
|
||||
scheduledExecutorService.submit(task);
|
||||
consumer.accept("同步任务已创建...");
|
||||
DateTransferTask task = new DateTransferTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onPersonSyncAction(ActionEvent event) {
|
||||
@@ -153,39 +95,28 @@ public class YongYouU8ManagerWindowController
|
||||
}
|
||||
|
||||
public void onContractGroupSyncAction(ActionEvent event) {
|
||||
Task<Object> task = new ContractGroupSyncTask();
|
||||
UITools.showTaskDialogAndWait("合同分组数据同步", task, consumer -> {
|
||||
initializeTask(task, "合同分组数据", msg -> consumer.accept(Message.info(msg)));
|
||||
});
|
||||
ContractGroupSyncTask task = new ContractGroupSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onContractTypeSyncAction(ActionEvent event) {
|
||||
Task<Object> task = new ContractTypeSyncTask();
|
||||
UITools.showTaskDialogAndWait("合同分类数据同步", task, consumer -> {
|
||||
initializeTask(task, "合同分类数据", msg -> consumer.accept(Message.info(msg)));
|
||||
});
|
||||
ContractTypeSyncTask task = new ContractTypeSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onContractKindSyncAction(ActionEvent event) {
|
||||
Task<Object> task = new ContractKindSyncTask();
|
||||
UITools.showTaskDialogAndWait("合同类型数据同步", task, consumer -> {
|
||||
initializeTask(task, "合同类型数据", msg -> consumer.accept(Message.info(msg)));
|
||||
});
|
||||
ContractKindSyncTask task = new ContractKindSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onVendorClassSyncAction(ActionEvent event) {
|
||||
Task<Object> task = new VendorClassSyncTask();
|
||||
UITools.showTaskDialogAndWait("供应商分类数据同步", task, consumer -> {
|
||||
initializeTask(task, "供应商分类数据", msg -> consumer.accept(Message.info(msg)));
|
||||
});
|
||||
VendorClassSyncTask task = new VendorClassSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
public void onCustomerClassSyncAction(ActionEvent event) {
|
||||
Task<Object> task = new CustomerClassSyncTask();
|
||||
UITools.showTaskDialogAndWait("客户分类数据同步", task, consumer -> {
|
||||
initializeTask(task, "客户分类数据", msg -> consumer.accept(Message.info(msg)));
|
||||
});
|
||||
CustomerClassSyncTask task = new CustomerClassSyncTask();
|
||||
Desktop.instance.getTaskMonitorCenter().registerAndStartTask(task);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
package com.ecep.contract.manager.cloud.u8;
|
||||
|
||||
import com.ecep.contract.manager.Desktop;
|
||||
import com.ecep.contract.manager.cloud.CloudInfo;
|
||||
import com.ecep.contract.manager.cloud.u8.ctx.AbstractYongYouU8Ctx;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
|
||||
import com.ecep.contract.manager.ds.other.service.EmployeeService;
|
||||
import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
|
||||
import com.ecep.contract.manager.ui.ViewModelService;
|
||||
import com.ecep.contract.manager.ui.task.MonitoredTask;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.concurrent.Task;
|
||||
import org.controlsfx.control.TaskProgressView;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -25,12 +19,19 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
import com.ecep.contract.manager.Desktop;
|
||||
import com.ecep.contract.manager.cloud.CloudInfo;
|
||||
import com.ecep.contract.manager.cloud.CloudInfoRepository;
|
||||
import com.ecep.contract.manager.cloud.u8.ctx.AbstractYongYouU8Ctx;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
|
||||
import com.ecep.contract.manager.ds.other.service.EmployeeService;
|
||||
import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
|
||||
import com.ecep.contract.manager.ui.ViewModelService;
|
||||
import com.ecep.contract.manager.ui.task.MonitoredTask;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
@@ -39,9 +40,17 @@ public class YongYouU8Service implements ViewModelService<CloudYu, CloudYuInfoVi
|
||||
private static final Logger logger = LoggerFactory.getLogger(YongYouU8Service.class);
|
||||
public static final String NAME = "用友U8";
|
||||
|
||||
public static final String KEY_HOST_IP = "u8.db.server.ip";
|
||||
public static final String KEY_DATABASE = "u8.db.database";
|
||||
public static final String KEY_USER_NAME = "u8.db.server.name";
|
||||
public static final String KEY_PASSWORD = "u8.db.server.password";
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private YongYouU8Repository repository;
|
||||
@Lazy
|
||||
@Autowired
|
||||
private CloudInfoRepository cloudInfoRepository;
|
||||
@Lazy
|
||||
@Autowired
|
||||
private CompanyService companyService;
|
||||
@@ -230,4 +239,8 @@ public class YongYouU8Service implements ViewModelService<CloudYu, CloudYuInfoVi
|
||||
ctx.setCompanyVendorService(companyVendorService);
|
||||
ctx.setCompanyCustomerService(companyCustomerService);
|
||||
}
|
||||
|
||||
public Iterable<CloudInfo> findAllCloudYu() {
|
||||
return cloudInfoRepository.findAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
package com.ecep.contract.manager.cloud.u8.ctx;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
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.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.other.service.SysConfService;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import static com.ecep.contract.manager.SpringApp.getBean;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.ecep.contract.manager.SpringApp.getBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
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.CompanyOldName;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyOldNameService;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.manager.ui.MessageHolder;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
public class CompanyCtx extends AbstractYongYouU8Ctx {
|
||||
/**
|
||||
* 自动创建公司的时间
|
||||
*/
|
||||
public static final String AUTO_CREATE_COMPANY_AFTER = "cloud.u8.auto-create-company-after";
|
||||
|
||||
@Setter
|
||||
@@ -111,7 +114,7 @@ public class CompanyCtx extends AbstractYongYouU8Ctx {
|
||||
return null;
|
||||
}
|
||||
CompanyService companyService = getCompanyService();
|
||||
String autoCreateAfter = SpringApp.getBean(SysConfService.class).getString(AUTO_CREATE_COMPANY_AFTER);
|
||||
String autoCreateAfter = getConfService().getString(AUTO_CREATE_COMPANY_AFTER);
|
||||
// 当配置存在,且开发时间小于指定时间,不创建
|
||||
if (StringUtils.hasText(autoCreateAfter)) {
|
||||
LocalDate miniDate = LocalDate.parse(autoCreateAfter);
|
||||
|
||||
@@ -1,11 +1,42 @@
|
||||
package com.ecep.contract.manager.cloud.u8.ctx;
|
||||
|
||||
import static com.ecep.contract.manager.SpringApp.getBean;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
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.contract.ContractFileType;
|
||||
import com.ecep.contract.manager.ds.contract.ContractPayWay;
|
||||
import com.ecep.contract.manager.ds.contract.model.*;
|
||||
import com.ecep.contract.manager.ds.contract.model.Contract;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractCatalog;
|
||||
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.ContractGroup;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractItem;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractKind;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractPayPlan;
|
||||
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.service.ContractItemService;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractPayPlanService;
|
||||
@@ -27,24 +58,31 @@ import com.ecep.contract.manager.ui.MessageHolder;
|
||||
import com.ecep.contract.manager.util.MyDateTimeUtils;
|
||||
import com.ecep.contract.manager.util.NumberUtils;
|
||||
import com.ecep.contract.manager.util.TaxRateUtils;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.NumberFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.ecep.contract.manager.SpringApp.getBean;
|
||||
|
||||
/**
|
||||
* 合同上下文
|
||||
*/
|
||||
public class ContractCtx extends AbstractYongYouU8Ctx {
|
||||
public static final String KEY_PREFIX = "cloud.u8.contract.";
|
||||
/**
|
||||
* 合同同步后的最后一个日期
|
||||
*/
|
||||
public static final String KEY_SYNC_BY_LATEST_DATE = KEY_PREFIX + "latestDate";
|
||||
/**
|
||||
* 合同同步后的最后一个合同ID
|
||||
*/
|
||||
public static final String KEY_SYNC_BY_LATEST_ID = KEY_PREFIX + "latestId";
|
||||
/**
|
||||
* 合同同步时是否使用最后更新的Id来判断更新范围,否则使用最后更新的合同日期来判断更新范围
|
||||
*/
|
||||
public static final String KEY_SYNC_USE_LATEST_ID = KEY_PREFIX + "sync.use-latest-id";
|
||||
/**
|
||||
* 合同同步时的时间间隔,单位:秒
|
||||
*/
|
||||
public static final String KEY_SYNC_ELAPSE = KEY_PREFIX + "sync.elapse";
|
||||
|
||||
@Setter
|
||||
private ContractService contractService;
|
||||
@@ -66,21 +104,18 @@ public class ContractCtx extends AbstractYongYouU8Ctx {
|
||||
private InventoryCtx inventoryCtx;
|
||||
@Setter
|
||||
private ProjectCtx projectCtx;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int vendorEntityUpdateDelayDays = 1;
|
||||
@Getter
|
||||
@Setter
|
||||
private int customerEntityUpdateDelayDays = 1;
|
||||
|
||||
public ContractService getContractService() {
|
||||
if (contractService == null) {
|
||||
contractService = getBean(ContractService.class);
|
||||
}
|
||||
return contractService;
|
||||
}
|
||||
|
||||
ContractItemService getContractItemService() {
|
||||
if (contractItemService == null) {
|
||||
contractItemService = getBean(ContractItemService.class);
|
||||
@@ -656,7 +691,7 @@ public class ContractCtx extends AbstractYongYouU8Ctx {
|
||||
contract.setGuid(guid);
|
||||
contract.setCode(contractId);
|
||||
contract = service.save(contract);
|
||||
holder.info("新建合同:" + contractId+", GUID: "+guid);
|
||||
holder.info("新建合同:" + contractId + ", GUID: " + guid);
|
||||
}
|
||||
}
|
||||
return contract;
|
||||
|
||||
@@ -78,7 +78,11 @@ public enum ContractFileType {
|
||||
/**
|
||||
* 重大项目决策记录单
|
||||
*/
|
||||
CriticalProjectDecisionRecord(true, true)
|
||||
CriticalProjectDecisionRecord(true, true),
|
||||
/**
|
||||
* 顾客满意度调查表
|
||||
*/
|
||||
CustomerSatisfactionSurvey(true, false),
|
||||
;
|
||||
|
||||
final boolean supportCustomer;
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
package com.ecep.contract.manager.ds.contract.controller;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.controlsfx.control.textfield.TextFields;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.company.CompanyFileUtils;
|
||||
import com.ecep.contract.manager.ds.company.CompanyStringConverter;
|
||||
@@ -26,8 +39,8 @@ 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.tab.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;
|
||||
@@ -36,34 +49,13 @@ 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 class ContractTabSkinBase extends AbstContractBasedTabSkin {
|
||||
|
||||
public ContractTabSkinBase(ContractWindowController controller) {
|
||||
super(controller);
|
||||
@@ -88,7 +80,8 @@ public class ContractTabSkinBase
|
||||
return v == null ? "关联" : "打开";
|
||||
}));
|
||||
|
||||
Glyph linkContractProjectBtnIcon = new Glyph("FontAwesome", viewModel.getProject().get() == null ? "UNLINK" : "LINK");
|
||||
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";
|
||||
@@ -124,7 +117,8 @@ public class ContractTabSkinBase
|
||||
if (!Hibernate.isInitialized(type)) {
|
||||
type = getContractService().findTypeById(type.getId());
|
||||
}
|
||||
return type.getCode() + " " + type.getCatalog() + " " + type.getName() + " " + type.getTitle() + "(" + type.getDirection() + ")";
|
||||
return type.getCode() + " " + type.getCatalog() + " " + type.getName() + " " + type.getTitle() + "("
|
||||
+ type.getDirection() + ")";
|
||||
}));
|
||||
|
||||
controller.kindField.textProperty().bind(viewModel.getKind().map(kind -> {
|
||||
@@ -150,8 +144,10 @@ public class ContractTabSkinBase
|
||||
}
|
||||
return !Objects.equals(type.getDirection(), "收");
|
||||
}, viewModel.getType()));
|
||||
controller.openRelativeCompanyCustomerBtn.managedProperty().bind(controller.openRelativeCompanyCustomerBtn.disabledProperty().not());
|
||||
controller.openRelativeCompanyCustomerBtn.visibleProperty().bind(controller.openRelativeCompanyCustomerBtn.managedProperty());
|
||||
controller.openRelativeCompanyCustomerBtn.managedProperty()
|
||||
.bind(controller.openRelativeCompanyCustomerBtn.disabledProperty().not());
|
||||
controller.openRelativeCompanyCustomerBtn.visibleProperty()
|
||||
.bind(controller.openRelativeCompanyCustomerBtn.managedProperty());
|
||||
|
||||
// as vendor
|
||||
controller.openRelativeCompanyVendorBtn.setOnAction(this::onContractOpenRelativeCompanyVendorAction);
|
||||
@@ -169,10 +165,13 @@ public class ContractTabSkinBase
|
||||
}
|
||||
return !Objects.equals(type.getDirection(), "付");
|
||||
}, viewModel.getType()));
|
||||
controller.openRelativeCompanyVendorBtn.managedProperty().bind(controller.openRelativeCompanyVendorBtn.disabledProperty().not());
|
||||
controller.openRelativeCompanyVendorBtn.visibleProperty().bind(controller.openRelativeCompanyVendorBtn.managedProperty());
|
||||
controller.openRelativeCompanyVendorBtn.managedProperty()
|
||||
.bind(controller.openRelativeCompanyVendorBtn.disabledProperty().not());
|
||||
controller.openRelativeCompanyVendorBtn.visibleProperty()
|
||||
.bind(controller.openRelativeCompanyVendorBtn.managedProperty());
|
||||
|
||||
LocalDateStringConverter localDateStringConverter = controller.localDateStringConverter;
|
||||
LocalDateStringConverter localDateStringConverter = controller.getCurrentEmployee()
|
||||
.getLocalDateStringConverter();
|
||||
|
||||
controller.setupDateField.setConverter(localDateStringConverter);
|
||||
controller.setupDateField.valueProperty().bindBidirectional(viewModel.getSetupDate());
|
||||
@@ -202,21 +201,23 @@ public class ContractTabSkinBase
|
||||
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.createdField.textProperty().bindBidirectional(viewModel.getCreated(),
|
||||
controller.getCurrentEmployee().getLocalDateTimeStringConverter());
|
||||
controller.guidField.textProperty().bind(viewModel.getGuid());
|
||||
controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());
|
||||
|
||||
|
||||
NumberStringConverter numberStringConverter = new NumberStringConverter(controller.getLocale(), "#,##0.00");
|
||||
NumberStringConverter numberStringConverter = controller.getCurrentEmployee().getNumberStringConverter();
|
||||
controller.amountField.textProperty().bindBidirectional(viewModel.getAmount(), numberStringConverter);
|
||||
controller.totalQuantityField.textProperty().bindBidirectional(viewModel.getTotalQuantity(), 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.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.execUnTaxAmountField.textProperty().bindBidirectional(viewModel.getExecUnTaxAmount(),
|
||||
numberStringConverter);
|
||||
|
||||
controller.versionLabel.textProperty().bind(viewModel.getVersion().asString());
|
||||
}
|
||||
@@ -264,7 +265,6 @@ public class ContractTabSkinBase
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
project = new Project();
|
||||
|
||||
String name = viewModel.getName().get();
|
||||
@@ -327,7 +327,6 @@ public class ContractTabSkinBase
|
||||
ContractWindowController.show(parent, controller.root.getScene().getWindow());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建合同存储目录
|
||||
*/
|
||||
@@ -470,7 +469,6 @@ public class ContractTabSkinBase
|
||||
CompanyVendorWindowController.show(companyVendor, null);
|
||||
}
|
||||
|
||||
|
||||
private void initializeBaseTabCompanyFieldAutoCompletion(TextField textField) {
|
||||
CompanyStringConverter converter = SpringApp.getBean(CompanyStringConverter.class);
|
||||
UITools.autoCompletion(textField, viewModel.getCompany(), converter);
|
||||
@@ -498,12 +496,8 @@ public class ContractTabSkinBase
|
||||
UITools.autoCompletion(textField, viewModel.getProject(), converter::suggest, stringConverter);
|
||||
}
|
||||
|
||||
|
||||
public CompanyCustomerService getCompanyCustomerService() {
|
||||
if (companyCustomerService == null) {
|
||||
companyCustomerService = SpringApp.getBean(CompanyCustomerService.class);
|
||||
}
|
||||
return companyCustomerService;
|
||||
return controller.getCachedBean(CompanyCustomerService.class);
|
||||
}
|
||||
|
||||
public ProjectService getProjectService() {
|
||||
@@ -511,23 +505,14 @@ public class ContractTabSkinBase
|
||||
}
|
||||
|
||||
public SaleTypeService getSaleTypeService() {
|
||||
if (saleTypeService == null) {
|
||||
saleTypeService = SpringApp.getBean(SaleTypeService.class);
|
||||
}
|
||||
return saleTypeService;
|
||||
return controller.getCachedBean(SaleTypeService.class);
|
||||
}
|
||||
|
||||
public ExtendVendorInfoService getExtendVendorInfoService() {
|
||||
if (extendVendorInfoService == null) {
|
||||
extendVendorInfoService = SpringApp.getBean(ExtendVendorInfoService.class);
|
||||
}
|
||||
return extendVendorInfoService;
|
||||
return controller.getCachedBean(ExtendVendorInfoService.class);
|
||||
}
|
||||
|
||||
public VendorGroupService getVendorGroupService() {
|
||||
if (vendorGroupService == null) {
|
||||
vendorGroupService = SpringApp.getBean(VendorGroupService.class);
|
||||
}
|
||||
return vendorGroupService;
|
||||
return controller.getCachedBean(VendorGroupService.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package com.ecep.contract.manager.ds.contract.controller;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
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 com.ecep.contract.manager.ds.company.controller.CompanyWindowController;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyService;
|
||||
@@ -13,21 +21,19 @@ import com.ecep.contract.manager.ui.AbstEntityController;
|
||||
import com.ecep.contract.manager.ui.FxmlPath;
|
||||
import com.ecep.contract.manager.util.DesktopUtils;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.DatePicker;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.stage.Window;
|
||||
import javafx.stage.WindowEvent;
|
||||
import javafx.util.converter.LocalDateStringConverter;
|
||||
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.time.format.DateTimeFormatter;
|
||||
|
||||
@Lazy
|
||||
@Scope("prototype")
|
||||
@@ -70,9 +76,6 @@ public class ContractWindowController
|
||||
@Autowired
|
||||
ProjectService projectService;
|
||||
|
||||
LocalDateStringConverter localDateStringConverter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
|
||||
|
||||
|
||||
public TextField nameField;
|
||||
public TextField guidField;
|
||||
public TextField codeField;
|
||||
|
||||
@@ -19,6 +19,9 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 合同支付计划服务
|
||||
*/
|
||||
@Lazy
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "contract-pay-plan")
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.ecep.contract.manager.cloud.u8.ctx.ContractCtx;
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.contract.ContractPayWay;
|
||||
import com.ecep.contract.manager.ds.contract.repository.ContractRepository;
|
||||
@@ -52,9 +53,6 @@ import com.ecep.contract.manager.ui.ViewModelService;
|
||||
public class ContractService implements ViewModelService<Contract, ContractViewModel> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ContractService.class);
|
||||
public static final String CONTRACT_BASE_PATH = "contract.base.path";
|
||||
public static final String CONTRACT_LATEST_ID = "cloud.u8.contract.latestId";
|
||||
public static final String CONTRACT_LATEST_DATE = "cloud.u8.contract.latestDate";
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ContractCatalogService contractCatalogService;
|
||||
@@ -147,18 +145,6 @@ public class ContractService implements ViewModelService<Contract, ContractViewM
|
||||
return contractRepository.findByProjectIdAndPayWay(project.getId(), ContractPayWay.RECEIVE).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新合同最新ID和日期
|
||||
*/
|
||||
public void updateLatestIdAndDate(Integer latestId, LocalDateTime latestDate) {
|
||||
if (latestId != null) {
|
||||
confService.set(CONTRACT_LATEST_ID, String.valueOf(latestId));
|
||||
}
|
||||
if (latestDate != null) {
|
||||
confService.set(CONTRACT_LATEST_DATE, latestDate.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public File getBasePath() {
|
||||
return new File(confService.getString(CONTRACT_BASE_PATH));
|
||||
}
|
||||
|
||||
@@ -42,13 +42,15 @@ import java.util.stream.Collectors;
|
||||
@Lazy
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "company-customer")
|
||||
public class CompanyCustomerService extends CompanyBasicService implements ViewModelService<CompanyCustomer, CompanyCustomerViewModel> {
|
||||
public class CompanyCustomerService extends CompanyBasicService
|
||||
implements ViewModelService<CompanyCustomer, CompanyCustomerViewModel> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CompanyCustomerService.class);
|
||||
|
||||
private static final String EVALUATION_FORM_NAME1 = "评定表";
|
||||
public static final String EVALUATION_FORM_NAME2 = "评估表";
|
||||
|
||||
public static final String KEY_BASE_PATH = "customer.base.path";
|
||||
public static final String KEY_SALEBOOK_PATH = "customer.salebook.path";
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
@@ -78,20 +80,16 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
return companyCustomerRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
@Caching(
|
||||
evict = {
|
||||
@CacheEvict(key = "#p0.id")
|
||||
}
|
||||
)
|
||||
@Caching(evict = {
|
||||
@CacheEvict(key = "#p0.id")
|
||||
})
|
||||
public CompanyCustomer save(CompanyCustomer companyCustomer) {
|
||||
return companyCustomerRepository.save(companyCustomer);
|
||||
}
|
||||
|
||||
@Caching(
|
||||
evict = {
|
||||
@CacheEvict(key = "#p0")
|
||||
}
|
||||
)
|
||||
@Caching(evict = {
|
||||
@CacheEvict(key = "#p0")
|
||||
})
|
||||
@Override
|
||||
public void delete(CompanyCustomer entity) {
|
||||
companyCustomerRepository.delete(entity);
|
||||
@@ -164,7 +162,7 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
List<CompanyCustomerFile> retrieveFiles = new ArrayList<>();
|
||||
List<File> needMoveToCompanyPath = new ArrayList<>();
|
||||
|
||||
//TODO 客户有曾用名,可能存在多个目录
|
||||
// TODO 客户有曾用名,可能存在多个目录
|
||||
fetchFiles(companyCustomer.getPath(), needMoveToCompanyPath, retrieveFiles, map, status);
|
||||
|
||||
// 移动文件到公司目录下 to company path
|
||||
@@ -173,7 +171,7 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
status.accept("导入 " + retrieveFiles.size() + " 个文件");
|
||||
|
||||
if (!retrieveFiles.isEmpty()) {
|
||||
//update db
|
||||
// update db
|
||||
retrieveFiles.forEach(v -> v.setCustomer(companyCustomer));
|
||||
companyCustomerFileService.saveAll(retrieveFiles);
|
||||
modified = true;
|
||||
@@ -182,9 +180,9 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file, Consumer<String> status) {
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsDefaultType(F dbFile, File file,
|
||||
Consumer<String> status) {
|
||||
dbFile.setType((T) CompanyCustomerFileType.General);
|
||||
fillFile(dbFile, file, null, status);
|
||||
companyCustomerFileService.save((CompanyCustomerFile) dbFile);
|
||||
@@ -192,7 +190,8 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsEvaluationFile(F customerFile, File file, List<File> fileList, Consumer<String> status) {
|
||||
protected <T, F extends CompanyBasicFile<T>> boolean fillFileAsEvaluationFile(F customerFile, File file,
|
||||
List<File> fileList, Consumer<String> status) {
|
||||
boolean modified = super.fillFileAsEvaluationFile(customerFile, file, fileList, status);
|
||||
|
||||
if (fileList != null) {
|
||||
@@ -225,7 +224,8 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
return modified;
|
||||
}
|
||||
|
||||
private <T, F extends CompanyBasicFile<T>> void updateEvaluationFileByJsonFile(F customerFile, File jsonFile, Consumer<String> status) throws IOException {
|
||||
private <T, F extends CompanyBasicFile<T>> void updateEvaluationFileByJsonFile(F customerFile, File jsonFile,
|
||||
Consumer<String> status) throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode root = objectMapper.readTree(jsonFile);
|
||||
if (!root.isObject()) {
|
||||
@@ -237,19 +237,21 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
data.remove("valid");
|
||||
JsonNode type = data.remove("type");
|
||||
|
||||
CompanyCustomerEvaluationFormFile formFile = companyCustomerFileService.findCustomerEvaluationFormFileByCustomerFile((CompanyCustomerFile) customerFile);
|
||||
CompanyCustomerEvaluationFormFile formFile = companyCustomerFileService
|
||||
.findCustomerEvaluationFormFileByCustomerFile((CompanyCustomerFile) customerFile);
|
||||
objectMapper.updateValue(formFile, data);
|
||||
logger.info("load json data from {}", jsonFile.getName());
|
||||
formFile.setCatalog(type.asText());
|
||||
companyCustomerEvaluationFormFileRepository.save(formFile);
|
||||
// companyCustomerEvaluationFormFileRepository.save(formFile);
|
||||
// companyCustomerEvaluationFormFileRepository.save(formFile);
|
||||
if (jsonFile.delete()) {
|
||||
logger.info("delete json file {}", jsonFile.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList, Consumer<String> status) {
|
||||
protected <T, F extends CompanyBasicFile<T>> F fillFileType(File file, List<File> fileList,
|
||||
Consumer<String> status) {
|
||||
CompanyCustomerFile customerFile = new CompanyCustomerFile();
|
||||
customerFile.setType(CompanyCustomerFileType.General);
|
||||
if (fillFile(customerFile, file, fileList, status)) {
|
||||
@@ -271,7 +273,8 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
protected boolean isEvaluationFile(String fileName) {
|
||||
return (fileName.contains(EVALUATION_FORM_NAME1)
|
||||
|| fileName.contains(EVALUATION_FORM_NAME2))
|
||||
&& (CompanyFileUtils.withExtensions(fileName, CompanyFileUtils.JPG, CompanyFileUtils.JPEG, CompanyFileUtils.PDF));
|
||||
&& (CompanyFileUtils.withExtensions(fileName, CompanyFileUtils.JPG, CompanyFileUtils.JPEG,
|
||||
CompanyFileUtils.PDF));
|
||||
}
|
||||
|
||||
public boolean makePathAbsent(CompanyCustomer companyCustomer) {
|
||||
@@ -302,7 +305,8 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
}
|
||||
|
||||
String companyName = company.getName();
|
||||
String fileName = formatCompanyVendorId(companyCustomer.getId()) + "-" + CompanyFileUtils.escapeFileName(companyName);
|
||||
String fileName = formatCompanyVendorId(companyCustomer.getId()) + "-"
|
||||
+ CompanyFileUtils.escapeFileName(companyName);
|
||||
|
||||
File dir = new File(basePath, fileName);
|
||||
if (!dir.exists()) {
|
||||
@@ -313,7 +317,6 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
public Page<CompanyCustomer> findAll(Specification<CompanyCustomer> spec, Pageable pageable) {
|
||||
return companyCustomerRepository.findAll(spec, pageable);
|
||||
}
|
||||
@@ -347,8 +350,9 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
|
||||
/***
|
||||
* 合并两个CompanyCustomer对象,并将fromCustomer的信息合并到toCustomer中,并保存到数据库中。
|
||||
*
|
||||
* @param from 源客户对象
|
||||
* @param to 目标客户对象
|
||||
* @param to 目标客户对象
|
||||
*/
|
||||
public void resetTo(CompanyCustomer from, CompanyCustomer to) {
|
||||
// file
|
||||
@@ -359,7 +363,6 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
companyCustomerRepository.delete(from);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除 company 的 客户
|
||||
*/
|
||||
@@ -386,12 +389,10 @@ public class CompanyCustomerService extends CompanyBasicService implements ViewM
|
||||
return customerCatalogRepository.findByCode(code).orElse(null);
|
||||
}
|
||||
|
||||
@Caching(
|
||||
evict = {
|
||||
@CacheEvict(key = "'catalog-'+#p0.id"),
|
||||
@CacheEvict(key = "'catalog-code-'+#p0.code")
|
||||
}
|
||||
)
|
||||
@Caching(evict = {
|
||||
@CacheEvict(key = "'catalog-'+#p0.id"),
|
||||
@CacheEvict(key = "'catalog-code-'+#p0.code")
|
||||
})
|
||||
public CustomerCatalog save(CustomerCatalog catalog) {
|
||||
return customerCatalogRepository.save(catalog);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.ecep.contract.manager.ds.other;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.ecep.contract.manager.Desktop;
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.other.model.SysConf;
|
||||
import com.ecep.contract.manager.ds.other.service.SysConfService;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.Control;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public abstract class AbstractConfigBounder<T> implements ConfigBounder {
|
||||
@Setter
|
||||
private SysConfService confService;
|
||||
String key;
|
||||
SysConf conf;
|
||||
@Getter
|
||||
@Setter
|
||||
Control control;
|
||||
@Getter
|
||||
@Setter
|
||||
javafx.util.StringConverter<T> converter;
|
||||
@Setter
|
||||
Property<T> property;
|
||||
ObjectProperty<LocalDateTime> modified = new SimpleObjectProperty<>(this, "modified");
|
||||
ObjectProperty<LocalDateTime> created = new SimpleObjectProperty<>(this, "created");
|
||||
|
||||
public AbstractConfigBounder(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> runAsync(Runnable runnable) {
|
||||
return CompletableFuture.runAsync(runnable, Desktop.instance.getExecutorService()).exceptionally(ex -> {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysConfService getConfService() {
|
||||
if (confService == null) {
|
||||
confService = SpringApp.getBean(SysConfService.class);
|
||||
}
|
||||
return confService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
getControl().setDisable(true);
|
||||
runAsync(this::asyncHandle);
|
||||
}
|
||||
|
||||
protected void asyncHandle() {
|
||||
conf = getConfService().findById(key);
|
||||
if (conf == null) {
|
||||
conf = new SysConf();
|
||||
conf.setId(key);
|
||||
conf.setCreated(LocalDateTime.now());
|
||||
conf.setModified(LocalDateTime.now());
|
||||
conf = getConfService().save(conf);
|
||||
}
|
||||
Property<T> property = getProperty();
|
||||
property.addListener(this::propertyChanged);
|
||||
bindBidirectional(property);
|
||||
modified.set(conf.getModified());
|
||||
created.set(conf.getCreated());
|
||||
getControl().setDisable(false);
|
||||
}
|
||||
|
||||
public Property<T> getProperty() {
|
||||
if (property == null) {
|
||||
T value = getConverter().fromString(conf.getValue());
|
||||
property = createProperty(value);
|
||||
setProperty(property);
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
public ObjectProperty<LocalDateTime> getModifiedProperty() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public ObjectProperty<LocalDateTime> getCreatedProperty() {
|
||||
return created;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Property<T> createProperty(T value) {
|
||||
if (value instanceof Boolean b) {
|
||||
return (Property<T>) new SimpleBooleanProperty(b);
|
||||
} else if (value instanceof Integer i) {
|
||||
return (Property<T>) new SimpleIntegerProperty(i);
|
||||
} else if (value instanceof Double d) {
|
||||
return (Property<T>) new SimpleDoubleProperty(d);
|
||||
} else if (value instanceof String s) {
|
||||
return (Property<T>) new SimpleStringProperty(s);
|
||||
}
|
||||
return new SimpleObjectProperty<>(value);
|
||||
}
|
||||
|
||||
abstract void bindBidirectional(Property<T> property);
|
||||
|
||||
void propertyChanged(ObservableValue<? extends T> observable, T oldValue,
|
||||
T newValue) {
|
||||
conf.setValue(getConverter().toString(newValue));
|
||||
conf.setModified(LocalDateTime.now());
|
||||
save();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
SysConf saved = getConfService().save(conf);
|
||||
modified.set(saved.getModified());
|
||||
created.set(saved.getCreated());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ public class BankStringConverter extends EntityStringConverter<Bank> {
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
// #2
|
||||
setInitialized(project -> service.findById(project.getId()));
|
||||
setSuggestion(service::search);
|
||||
setFromString(service::findByName);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ecep.contract.manager.ds.other;
|
||||
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.util.StringConverter;
|
||||
import javafx.util.converter.BooleanStringConverter;
|
||||
|
||||
public class BooleanConfig extends AbstractConfigBounder<Boolean> {
|
||||
public BooleanConfig(String key) {
|
||||
super(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToggleSwitch getControl() {
|
||||
return (ToggleSwitch) super.getControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringConverter<Boolean> getConverter() {
|
||||
StringConverter<Boolean> converter = super.getConverter();
|
||||
if (converter == null) {
|
||||
converter = new BooleanStringConverter();
|
||||
setConverter(converter);
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Property<Boolean> createProperty(Boolean value) {
|
||||
// fixbug when value is null
|
||||
value = value == null ? false : value;
|
||||
return super.createProperty(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
void bindBidirectional(Property<Boolean> property) {
|
||||
getControl().selectedProperty().bindBidirectional(property);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.ecep.contract.manager.ds.other;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.service.SysConfService;
|
||||
|
||||
public interface ConfigBounder {
|
||||
|
||||
void setConfService(SysConfService confService);
|
||||
|
||||
void initialize();
|
||||
|
||||
CompletableFuture<Void> runAsync(Runnable runnable);
|
||||
|
||||
SysConfService getConfService();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ecep.contract.manager.ds.other;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.scene.control.DatePicker;
|
||||
import javafx.util.StringConverter;
|
||||
import javafx.util.converter.LocalDateStringConverter;
|
||||
|
||||
public class LocalDateConfig extends AbstractConfigBounder<LocalDate> {
|
||||
|
||||
public LocalDateConfig(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatePicker getControl() {
|
||||
return (DatePicker) super.getControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringConverter<LocalDate> getConverter() {
|
||||
StringConverter<LocalDate> converter = super.getConverter();
|
||||
if (converter == null) {
|
||||
converter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
|
||||
setConverter(converter);
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Override
|
||||
void bindBidirectional(Property<LocalDate> property) {
|
||||
getControl().valueProperty().bindBidirectional(property);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ecep.contract.manager.ds.other;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.util.StringConverter;
|
||||
import javafx.util.converter.LocalDateTimeStringConverter;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class LocalDateTimeConfig extends AbstractConfigBounder<LocalDateTime> {
|
||||
@Getter
|
||||
@Setter
|
||||
private javafx.util.StringConverter<LocalDateTime> controlConverter;
|
||||
|
||||
public LocalDateTimeConfig(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextField getControl() {
|
||||
return (TextField) super.getControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public javafx.util.StringConverter<LocalDateTime> getConverter() {
|
||||
javafx.util.StringConverter<LocalDateTime> converter = super.getConverter();
|
||||
if (converter == null) {
|
||||
converter = new LocalDateTimeStringConverter(DateTimeFormatter.ISO_LOCAL_DATE_TIME, null);
|
||||
setConverter(converter);
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Override
|
||||
void bindBidirectional(Property<LocalDateTime> property) {
|
||||
StringConverter<LocalDateTime> converter = getControlConverter();
|
||||
if (converter == null) {
|
||||
converter = getConverter();
|
||||
}
|
||||
getControl().textProperty().bindBidirectional(property, converter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.ecep.contract.manager.ds.other;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.scene.control.Control;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
public class StringConfig extends AbstractConfigBounder<String> {
|
||||
|
||||
public StringConfig(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public TextField getControl() {
|
||||
// return (TextField) super.getControl();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public StringConverter<String> getConverter() {
|
||||
StringConverter<String> converter = super.getConverter();
|
||||
if (converter == null) {
|
||||
converter = new StringConverter<String>() {
|
||||
@Override
|
||||
public String toString(String object) {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fromString(String string) {
|
||||
return string;
|
||||
}
|
||||
};
|
||||
setConverter(converter);
|
||||
}
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Override
|
||||
void bindBidirectional(Property<String> property) {
|
||||
Control ctrl = getControl();
|
||||
if (ctrl == null) {
|
||||
return;
|
||||
}
|
||||
if (ctrl instanceof TextField textField) {
|
||||
textField.textProperty().bindBidirectional(property);
|
||||
} else if (ctrl instanceof Label label) {
|
||||
label.textProperty().bindBidirectional(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,13 +220,4 @@ public class HomeWindowController extends BaseController {
|
||||
public void onShowTaskMonitorWindowAction(ActionEvent event) {
|
||||
showInOwner(TaskMonitorViewController.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行任务监控演示
|
||||
*/
|
||||
public void onRunTaskMonitorDemo(ActionEvent event) {
|
||||
com.ecep.contract.manager.ui.task.DemoTask.runDemo();
|
||||
// 自动打开任务监控窗口
|
||||
showInOwner(TaskMonitorViewController.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
package com.ecep.contract.manager.ds.other.controller;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.ecep.contract.manager.cloud.u8.YongYouU8Service;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractService;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerFileService;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
|
||||
import com.ecep.contract.manager.ds.other.StringConfig;
|
||||
import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
|
||||
import com.ecep.contract.manager.ds.contract.service.ContractService;
|
||||
import com.ecep.contract.manager.ds.other.repository.SysConfRepository;
|
||||
import com.ecep.contract.manager.ui.BaseController;
|
||||
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.event.ActionEvent;
|
||||
@@ -14,14 +24,7 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
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.io.File;
|
||||
@Lazy
|
||||
@Scope("prototype")
|
||||
@Component
|
||||
@@ -42,90 +45,76 @@ public class SysConfWindowController extends BaseController {
|
||||
public Label customerEvaluationFormTemplateLabel;
|
||||
public Label customerSaleBookPathLabel;
|
||||
|
||||
StringConfig contractPathConfig = new StringConfig(ContractService.CONTRACT_BASE_PATH);
|
||||
StringConfig vendorPathConfig = new StringConfig(CompanyVendorService.KEY_BASE_PATH);
|
||||
StringConfig vendorEvaluationFormTemplateConfig = new StringConfig(
|
||||
CompanyVendorService.KEY_EVALUATION_FORM_TEMPLATE);
|
||||
StringConfig customerPathConfig = new StringConfig(CompanyCustomerService.KEY_BASE_PATH);
|
||||
StringConfig customerEvaluationFormTemplateConfig = new StringConfig(
|
||||
CompanyCustomerFileService.KEY_EVALUATION_FORM_TEMPLATE);
|
||||
StringConfig customerSaleBookPathConfig = new StringConfig(CompanyCustomerService.KEY_SALEBOOK_PATH);
|
||||
|
||||
@Autowired
|
||||
private SysConfRepository confRepository;
|
||||
|
||||
private final SimpleStringProperty companyContractPath = new SimpleStringProperty();
|
||||
|
||||
private final SimpleStringProperty u8DataBaseServerHost = new SimpleStringProperty();
|
||||
private final SimpleStringProperty u8DataBaseCatalog = new SimpleStringProperty();
|
||||
private final SimpleStringProperty u8DataBaseUserName = new SimpleStringProperty();
|
||||
private final SimpleStringProperty u8DataBasePassword = new SimpleStringProperty();
|
||||
|
||||
|
||||
private final SimpleStringProperty vendorPath = new SimpleStringProperty();
|
||||
private final SimpleStringProperty vendorEvaluationFormTemplate = new SimpleStringProperty();
|
||||
|
||||
private final SimpleStringProperty customerPath = new SimpleStringProperty();
|
||||
private final SimpleStringProperty customerEvaluationFormTemplate = new SimpleStringProperty();
|
||||
private final SimpleStringProperty customerSaleBookPath = new SimpleStringProperty();
|
||||
StringConfig u8DataBaseServerHostConfig = new StringConfig(YongYouU8Service.KEY_HOST_IP);
|
||||
StringConfig u8DataBaseCatalogConfig = new StringConfig(YongYouU8Service.KEY_DATABASE);
|
||||
StringConfig u8DataBaseUserNameConfig = new StringConfig(YongYouU8Service.KEY_USER_NAME);
|
||||
StringConfig u8DataBasePasswordConfig = new StringConfig(YongYouU8Service.KEY_PASSWORD);
|
||||
|
||||
public void initialize() {
|
||||
contractPathConfig.setControl(companyContractPathLabel);
|
||||
contractPathConfig.initialize();
|
||||
|
||||
initializeDirectory(companyContractPathLabel, companyContractPath, ContractService.CONTRACT_BASE_PATH);
|
||||
vendorPathConfig.setControl(vendorPathLabel);
|
||||
vendorPathConfig.initialize();
|
||||
vendorEvaluationFormTemplateConfig.setControl(vendorEvaluationFormTemplateLabel);
|
||||
vendorEvaluationFormTemplateConfig.initialize();
|
||||
|
||||
initializeDirectory(vendorPathLabel, vendorPath, CompanyVendorService.KEY_BASE_PATH);
|
||||
initializeFile(vendorEvaluationFormTemplateLabel, vendorEvaluationFormTemplate, CompanyVendorService.KEY_EVALUATION_FORM_TEMPLATE);
|
||||
customerPathConfig.setControl(customerPathLabel);
|
||||
customerPathConfig.initialize();
|
||||
customerEvaluationFormTemplateConfig.setControl(customerEvaluationFormTemplateLabel);
|
||||
customerEvaluationFormTemplateConfig.initialize();
|
||||
customerSaleBookPathConfig.setControl(customerSaleBookPathLabel);
|
||||
customerSaleBookPathConfig.initialize();
|
||||
|
||||
initializeDirectory(customerPathLabel, customerPath, CompanyCustomerService.KEY_BASE_PATH);
|
||||
initializeFile(customerEvaluationFormTemplateLabel, customerEvaluationFormTemplate, CompanyCustomerFileService.KEY_EVALUATION_FORM_TEMPLATE);
|
||||
initializeDirectory(customerSaleBookPathLabel, customerSaleBookPath, "customer.salebook.path");
|
||||
|
||||
initializeField(u8DataBaseServerHostField, u8DataBaseServerHost, "u8.db.server.ip");
|
||||
initializeField(u8DataBaseCatalogField, u8DataBaseCatalog, "u8.db.database");
|
||||
initializeField(u8DataBaseUserNameField, u8DataBaseUserName, "u8.db.server.name");
|
||||
initializeField(u8DataBasePasswordField, u8DataBasePassword, "u8.db.server.password");
|
||||
u8DataBaseServerHostConfig.setControl(u8DataBaseServerHostField);
|
||||
u8DataBaseServerHostConfig.initialize();
|
||||
u8DataBaseCatalogConfig.setControl(u8DataBaseCatalogField);
|
||||
u8DataBaseCatalogConfig.initialize();
|
||||
u8DataBaseUserNameConfig.setControl(u8DataBaseUserNameField);
|
||||
u8DataBaseUserNameConfig.initialize();
|
||||
u8DataBasePasswordConfig.setControl(u8DataBasePasswordField);
|
||||
u8DataBasePasswordConfig.initialize();
|
||||
|
||||
logger.debug("#initialize()");
|
||||
}
|
||||
|
||||
private void initializeFile(Label label, SimpleStringProperty property, String key) {
|
||||
label.textProperty().bind(property);
|
||||
property.set(confRepository.get(key, ""));
|
||||
}
|
||||
|
||||
private void initializeDirectory(Label label, SimpleStringProperty property, String key) {
|
||||
label.textProperty().bind(property);
|
||||
property.set(confRepository.get(key, ""));
|
||||
}
|
||||
|
||||
private void initializeField(TextField field, SimpleStringProperty property, String key) {
|
||||
field.textProperty().bindBidirectional(property);
|
||||
property.set(confRepository.get(key, ""));
|
||||
property.addListener((observable, oldValue, newValue) -> {
|
||||
confRepository.set(key, newValue);
|
||||
});
|
||||
}
|
||||
|
||||
private void directoryChoose(SimpleStringProperty property, String title, String key, ActionEvent event) {
|
||||
private void directoryChoose(StringConfig config, String title, String key, ActionEvent event) {
|
||||
DirectoryChooser chooser = new DirectoryChooser();
|
||||
chooser.setTitle(title);
|
||||
File value = new File(property.get());
|
||||
File value = new File(config.getProperty().getValue());
|
||||
chooser.setInitialDirectory(value);
|
||||
|
||||
Node node = (Node) event.getSource();
|
||||
File selected = chooser.showDialog(node.getScene().getWindow());
|
||||
if (selected != null) {
|
||||
property.set(selected.getAbsolutePath());
|
||||
confRepository.set(key, property.get());
|
||||
config.getProperty().setValue(selected.getAbsolutePath());
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
|
||||
public void changeCompanyContractPath(ActionEvent actionEvent) {
|
||||
directoryChoose(companyContractPath, "请选择合同目录", ContractService.CONTRACT_BASE_PATH, actionEvent);
|
||||
directoryChoose(contractPathConfig, "请选择合同目录", ContractService.CONTRACT_BASE_PATH, actionEvent);
|
||||
}
|
||||
|
||||
public void changeVendorPath(ActionEvent actionEvent) {
|
||||
directoryChoose(vendorPath, "请选择供应商目录", CompanyVendorService.KEY_BASE_PATH, actionEvent);
|
||||
directoryChoose(vendorPathConfig, "请选择供应商目录", CompanyVendorService.KEY_BASE_PATH, actionEvent);
|
||||
}
|
||||
|
||||
public void changeCustomerPath(ActionEvent actionEvent) {
|
||||
directoryChoose(customerPath, "请选择客户目录", CompanyCustomerService.KEY_BASE_PATH, actionEvent);
|
||||
directoryChoose(customerPathConfig, "请选择客户目录", CompanyCustomerService.KEY_BASE_PATH, actionEvent);
|
||||
}
|
||||
|
||||
public void changeCustomerSaleBookPath(ActionEvent actionEvent) {
|
||||
directoryChoose(customerSaleBookPath, "请选择销售台账目录", "customer.salebook.path", actionEvent);
|
||||
directoryChoose(customerSaleBookPathConfig, "请选择销售台账目录", "customer.salebook.path", actionEvent);
|
||||
}
|
||||
|
||||
// 模拟销毁方法
|
||||
@@ -134,28 +123,29 @@ public class SysConfWindowController extends BaseController {
|
||||
|
||||
}
|
||||
|
||||
private void fileChoose(SimpleStringProperty property, String title, String key, ActionEvent event) {
|
||||
private void fileChoose(StringConfig config, String title, String key, ActionEvent event) {
|
||||
FileChooser chooser = new FileChooser();
|
||||
chooser.setTitle(title);
|
||||
File value = new File(property.get());
|
||||
File value = new File(config.getProperty().getValue());
|
||||
chooser.setInitialDirectory(value.getParentFile());
|
||||
chooser.setInitialFileName(value.getName());
|
||||
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(" 模板文件(*.xlsx)", "*.xlsx"));
|
||||
Node node = (Node) event.getSource();
|
||||
File selected = chooser.showOpenDialog(node.getScene().getWindow());
|
||||
if (selected != null) {
|
||||
property.set(selected.getAbsolutePath());
|
||||
confRepository.set(key, property.get());
|
||||
config.getProperty().setValue(selected.getAbsolutePath());
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void changeCustomerEvaluationFormTemplate(ActionEvent actionEvent) {
|
||||
fileChoose(customerEvaluationFormTemplate, "请选择客户资信评估表模板", CompanyCustomerFileService.KEY_EVALUATION_FORM_TEMPLATE, actionEvent);
|
||||
fileChoose(customerEvaluationFormTemplateConfig, "请选择客户资信评估表模板",
|
||||
CompanyCustomerFileService.KEY_EVALUATION_FORM_TEMPLATE, actionEvent);
|
||||
}
|
||||
|
||||
|
||||
public void changeVendorEvaluationFormTemplate(ActionEvent actionEvent) {
|
||||
fileChoose(vendorEvaluationFormTemplate, "请选择供方调查评价表模板", CompanyVendorService.KEY_EVALUATION_FORM_TEMPLATE, actionEvent);
|
||||
fileChoose(vendorEvaluationFormTemplateConfig, "请选择供方调查评价表模板",
|
||||
CompanyVendorService.KEY_EVALUATION_FORM_TEMPLATE,
|
||||
actionEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.ecep.contract.manager.ds.other.controller.inventory;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.EntityStringConverter;
|
||||
import com.ecep.contract.manager.ds.other.model.Inventory;
|
||||
import com.ecep.contract.manager.ds.other.model.InventoryCatalog;
|
||||
@@ -7,10 +9,9 @@ import com.ecep.contract.manager.ds.other.service.InventoryCatalogService;
|
||||
import com.ecep.contract.manager.ds.other.service.InventoryService;
|
||||
import com.ecep.contract.manager.ds.other.vo.InventoryViewModel;
|
||||
import com.ecep.contract.manager.ui.AbstEntityManagerSkin;
|
||||
import com.ecep.contract.manager.ui.table.EditableEntityTableTabSkin;
|
||||
import com.ecep.contract.manager.ui.ManagerSkin;
|
||||
import com.ecep.contract.manager.ui.util.LocalDateFieldTableCell;
|
||||
import com.ecep.contract.manager.ui.table.cell.LocalDateTimeTableCell;
|
||||
import com.ecep.contract.manager.ui.util.LocalDateFieldTableCell;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.TableColumn;
|
||||
@@ -19,11 +20,8 @@ import javafx.util.converter.CurrencyStringConverter;
|
||||
import javafx.util.converter.NumberStringConverter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class InventoryManagerSkin
|
||||
extends AbstEntityManagerSkin<Inventory, InventoryViewModel, InventoryManagerSkin, InventoryManagerWindowController>
|
||||
implements ManagerSkin, EditableEntityTableTabSkin<Inventory, InventoryViewModel> {
|
||||
public class InventoryManagerSkin extends
|
||||
AbstEntityManagerSkin<Inventory, InventoryViewModel, InventoryManagerSkin, InventoryManagerWindowController> {
|
||||
|
||||
@Setter
|
||||
private InventoryCatalogService catalogService;
|
||||
@@ -69,7 +67,8 @@ public class InventoryManagerSkin
|
||||
|
||||
controller.specificationColumn.setCellValueFactory(param -> param.getValue().getSpecification());
|
||||
controller.specificationColumn.setCellFactory(TextFieldTableCell.forTableColumn());
|
||||
controller.specificationColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getSpecification));
|
||||
controller.specificationColumn
|
||||
.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getSpecification));
|
||||
|
||||
controller.unitColumn.setCellValueFactory(param -> param.getValue().getUnit());
|
||||
controller.unitColumn.setCellFactory(TextFieldTableCell.forTableColumn());
|
||||
@@ -77,44 +76,48 @@ public class InventoryManagerSkin
|
||||
|
||||
controller.purchaseTaxRateColumn.setCellValueFactory(param -> param.getValue().getPurchaseTaxRate());
|
||||
controller.purchaseTaxRateColumn.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter()));
|
||||
controller.purchaseTaxRateColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getPurchaseTaxRate));
|
||||
controller.purchaseTaxRateColumn
|
||||
.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getPurchaseTaxRate));
|
||||
|
||||
controller.purchasePriceColumn.setCellValueFactory(param -> param.getValue().getPurchasePrice());
|
||||
controller.purchasePriceColumn.setCellFactory(TextFieldTableCell.forTableColumn(new CurrencyStringConverter()));
|
||||
// controller.purchasePriceColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getPurchasePrice));
|
||||
|
||||
// controller.purchasePriceColumn.setOnEditCommit(event ->
|
||||
// onColumnEditCommit(event, InventoryViewModel::getPurchasePrice));
|
||||
|
||||
controller.saleTaxRateColumn.setCellValueFactory(param -> param.getValue().getSaleTaxRate());
|
||||
controller.saleTaxRateColumn.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter()));
|
||||
controller.saleTaxRateColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getSaleTaxRate));
|
||||
controller.saleTaxRateColumn
|
||||
.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getSaleTaxRate));
|
||||
|
||||
controller.salePriceColumn.setCellValueFactory(param -> param.getValue().getSalePrice());
|
||||
controller.salePriceColumn.setCellFactory(TextFieldTableCell.forTableColumn(new CurrencyStringConverter()));
|
||||
// controller.salePriceColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getSalePrice));
|
||||
// controller.salePriceColumn.setOnEditCommit(event -> onColumnEditCommit(event,
|
||||
// InventoryViewModel::getSalePrice));
|
||||
|
||||
controller.createTimeColumn.setCellValueFactory(param -> param.getValue().getCreateTime());
|
||||
controller.createTimeColumn.setCellFactory(LocalDateFieldTableCell.forTableColumn());
|
||||
controller.createTimeColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getCreateTime));
|
||||
controller.createTimeColumn
|
||||
.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getCreateTime));
|
||||
|
||||
controller.updateDateColumn.setCellValueFactory(param -> param.getValue().getUpdateDate());
|
||||
controller.updateDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
|
||||
controller.updateDateColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getUpdateDate));
|
||||
controller.updateDateColumn
|
||||
.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getUpdateDate));
|
||||
|
||||
controller.descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
|
||||
controller.descriptionColumn.setCellFactory(TextFieldTableCell.forTableColumn());
|
||||
controller.descriptionColumn.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getDescription));
|
||||
controller.descriptionColumn
|
||||
.setOnEditCommit(event -> onColumnEditCommit(event, InventoryViewModel::getDescription));
|
||||
}
|
||||
|
||||
private <T> void onColumnEditCommit(
|
||||
TableColumn.CellEditEvent<InventoryViewModel, T> event,
|
||||
Function<InventoryViewModel, Property<T>> supplier
|
||||
) {
|
||||
Function<InventoryViewModel, Property<T>> supplier) {
|
||||
InventoryViewModel row = event.getRowValue();
|
||||
supplier.apply(row).setValue(event.getNewValue());
|
||||
saveRowData(row);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onTableRowDoubleClickedAction(InventoryViewModel item) {
|
||||
showInOwner(InventoryWindowController.class, item);
|
||||
|
||||
@@ -56,19 +56,36 @@ public class Employee implements Entity, IdentityEntity, NamedEntity {
|
||||
@Column(name = "LEAVE_DATE")
|
||||
private LocalDate leaveDate;
|
||||
|
||||
@Column(name = "LOCALE")
|
||||
private String locale;
|
||||
|
||||
@Column(name = "DATE_FORMATTER")
|
||||
private String dateFormatter;
|
||||
|
||||
@Column(name = "DATETIME_FORMATTER")
|
||||
private String dateTimeFormatter;
|
||||
|
||||
@Column(name = "TIME_FORMATTER")
|
||||
private String timeFormatter;
|
||||
|
||||
@Column(name = "TIME_ZONE")
|
||||
private String timeZone;
|
||||
|
||||
@Column(name = "NUMBER_FORMATTER")
|
||||
private String numberFormatter;
|
||||
|
||||
@Column(name = "CURRENCY_FORMATTER")
|
||||
private String currencyFormatter;
|
||||
|
||||
/**
|
||||
* 员工是否活跃的状态
|
||||
*/
|
||||
@Column(name = "IS_ACTIVE", nullable = false)
|
||||
private boolean isActive;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
|
||||
@JoinTable(
|
||||
name = "EMPLOYEE_ROLES",
|
||||
joinColumns = @JoinColumn(name = "EMPLOYEE_ID"),
|
||||
inverseJoinColumns = @JoinColumn(name = "ROLE_ID")
|
||||
)
|
||||
private java.util.List<EmployeeRole> roles = new java.util.ArrayList<>();
|
||||
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
|
||||
@JoinTable(name = "EMPLOYEE_ROLES", joinColumns = @JoinColumn(name = "EMPLOYEE_ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
|
||||
private java.util.List<EmployeeRole> roles = new java.util.ArrayList<>();
|
||||
|
||||
@Override
|
||||
public String toPrettyString() {
|
||||
@@ -80,17 +97,26 @@ public class Employee implements Entity, IdentityEntity, NamedEntity {
|
||||
|
||||
@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;
|
||||
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;
|
||||
Employee employee = (Employee) object;
|
||||
return getId() != null && Objects.equals(getId(), employee.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
|
||||
return this instanceof HibernateProxy
|
||||
? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode()
|
||||
: getClass().hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package com.ecep.contract.manager.ds.other.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@@ -24,9 +25,9 @@ public class SysConf {
|
||||
|
||||
@ColumnDefault("CURRENT_TIMESTAMP")
|
||||
@Column(name = "MODIFIED")
|
||||
private Instant modified;
|
||||
private LocalDateTime modified;
|
||||
|
||||
@Column(name = "CREATED")
|
||||
private Instant created;
|
||||
private LocalDateTime created;
|
||||
|
||||
}
|
||||
@@ -1,85 +1,11 @@
|
||||
package com.ecep.contract.manager.ds.other.repository;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.model.SysConf;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import com.ecep.contract.manager.ds.MyRepository;
|
||||
import com.ecep.contract.manager.ds.other.model.SysConf;
|
||||
|
||||
@Repository
|
||||
public interface SysConfRepository extends CrudRepository<SysConf, String>, PagingAndSortingRepository<SysConf, String> {
|
||||
default String get(String key) {
|
||||
return get(key, null);
|
||||
}
|
||||
public interface SysConfRepository extends MyRepository<SysConf, String> {
|
||||
|
||||
/**
|
||||
* 读取配置值
|
||||
*
|
||||
* @param key 配置项
|
||||
* @param defaultValue 没有配置时的默认值
|
||||
* @return 配置值
|
||||
*/
|
||||
default String get(String key, String defaultValue) {
|
||||
Optional<SysConf> optional = findById(key);
|
||||
if (optional.isPresent()) {
|
||||
return optional.get().getValue();
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
default long get(String key, long defaultValue) {
|
||||
Optional<SysConf> optional = findById(key);
|
||||
return optional.map(sysConf -> Long.parseLong(sysConf.getValue())).orElse(defaultValue);
|
||||
}
|
||||
|
||||
default int get(String key, int defaultValue) {
|
||||
Optional<SysConf> optional = findById(key);
|
||||
return optional.map(sysConf -> Integer.parseInt(sysConf.getValue())).orElse(defaultValue);
|
||||
}
|
||||
|
||||
default boolean get(String key, boolean defaultValue) {
|
||||
Optional<SysConf> optional = findById(key);
|
||||
return optional.map(sysConf -> {
|
||||
String value = sysConf.getValue();
|
||||
if (Boolean.parseBoolean(value)) {
|
||||
return true;
|
||||
}
|
||||
return "1".equalsIgnoreCase(value);
|
||||
}).orElse(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存配置值
|
||||
*
|
||||
* @param key 配置项
|
||||
* @param value 配置值
|
||||
* @return 配置值对象
|
||||
*/
|
||||
default SysConf set(String key, String value) {
|
||||
SysConf conf;
|
||||
Optional<SysConf> optional = findById(key);
|
||||
if (optional.isPresent()) {
|
||||
conf = optional.get();
|
||||
} else {
|
||||
conf = new SysConf();
|
||||
conf.setId(key);
|
||||
conf.setCreated(Instant.now());
|
||||
}
|
||||
conf.setValue(value);
|
||||
conf.setModified(Instant.now());
|
||||
save(conf);
|
||||
return conf;
|
||||
}
|
||||
|
||||
default CompletableFuture<Optional<SysConf>> value(String key) {
|
||||
return CompletableFuture.supplyAsync(() -> findById(key));
|
||||
}
|
||||
|
||||
default CompletableFuture<SysConf> value(String key, String value) {
|
||||
return CompletableFuture.supplyAsync(() -> set(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.ecep.contract.manager.ds.other.service;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.model.SysConf;
|
||||
import com.ecep.contract.manager.ds.other.repository.SysConfRepository;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
@@ -9,12 +9,14 @@ import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
import com.ecep.contract.manager.ds.other.model.SysConf;
|
||||
import com.ecep.contract.manager.ds.other.repository.SysConfRepository;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "sys_conf")
|
||||
public class SysConfService {
|
||||
@Lazy
|
||||
@Autowired
|
||||
private SysConfRepository repository;
|
||||
|
||||
@@ -22,16 +24,21 @@ public class SysConfService {
|
||||
return repository.findById(key).orElse(null);
|
||||
}
|
||||
|
||||
@CacheEvict(key = "#p0.id")
|
||||
public SysConf save(SysConf conf) {
|
||||
return repository.save(conf);
|
||||
}
|
||||
|
||||
@CacheEvict(key = "#p0")
|
||||
public SysConf set(String key, String value) {
|
||||
SysConf conf = findById(key);
|
||||
if (conf == null) {
|
||||
conf = new SysConf();
|
||||
conf.setId(key);
|
||||
conf.setCreated(Instant.now());
|
||||
conf.setCreated(LocalDateTime.now());
|
||||
}
|
||||
conf.setValue(value);
|
||||
conf.setModified(Instant.now());
|
||||
conf.setModified(LocalDateTime.now());
|
||||
repository.save(conf);
|
||||
return conf;
|
||||
}
|
||||
@@ -94,6 +101,4 @@ public class SysConfService {
|
||||
return "1".equalsIgnoreCase(conf.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.ecep.contract.manager.ds.project.controller;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.customer.model.CompanyCustomerEvaluationFormFile;
|
||||
import com.ecep.contract.manager.ds.customer.model.CompanyCustomerFile;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerFileService;
|
||||
import com.ecep.contract.manager.ds.project.vo.ProjectBidViewModel;
|
||||
import javafx.scene.control.TableCell;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
class EvaluationFileTableCell extends TableCell<ProjectBidViewModel, CompanyCustomerEvaluationFormFile> {
|
||||
private CompanyCustomerFileService fileService;
|
||||
|
||||
public CompanyCustomerFileService getFileService() {
|
||||
if (fileService == null) {
|
||||
fileService = SpringApp.getBean(CompanyCustomerFileService.class);
|
||||
}
|
||||
return fileService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(CompanyCustomerEvaluationFormFile item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty || item == null) {
|
||||
setText("");
|
||||
return;
|
||||
}
|
||||
if (!Hibernate.isInitialized(item)) {
|
||||
item = getFileService().findCustomerEvaluationFormFileById(item.getId());
|
||||
}
|
||||
CompanyCustomerFile customerFile = item.getCustomerFile();
|
||||
String path = customerFile.getFilePath();
|
||||
if (StringUtils.hasText(path)) {
|
||||
File file = new File(path);
|
||||
setText(file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,33 @@
|
||||
package com.ecep.contract.manager.ds.project.controller;
|
||||
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import com.ecep.contract.manager.ds.company.CompanyStringConverter;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.manager.ds.customer.model.CompanyCustomerEvaluationFormFile;
|
||||
import com.ecep.contract.manager.ds.customer.model.CompanyCustomerFile;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerFileService;
|
||||
import com.ecep.contract.manager.ds.customer.service.CompanyCustomerService;
|
||||
import com.ecep.contract.manager.ds.other.EmployeeStringConverter;
|
||||
import com.ecep.contract.manager.ui.table.cell.EmployeeTableCell;
|
||||
import com.ecep.contract.manager.ds.other.model.Employee;
|
||||
import com.ecep.contract.manager.ds.project.controller.bid.ProjectBidWindowController;
|
||||
import com.ecep.contract.manager.ds.project.model.Project;
|
||||
import com.ecep.contract.manager.ds.project.model.ProjectBid;
|
||||
import com.ecep.contract.manager.ds.project.service.ProjectBidService;
|
||||
import com.ecep.contract.manager.ds.project.vo.ProjectBidViewModel;
|
||||
import com.ecep.contract.manager.ui.*;
|
||||
import com.ecep.contract.manager.ui.FxmlPath;
|
||||
import com.ecep.contract.manager.ui.RefreshableSkin;
|
||||
import com.ecep.contract.manager.ui.tab.TabSkin;
|
||||
import com.ecep.contract.manager.ui.table.EditableEntityTableTabSkin;
|
||||
import javafx.scene.control.*;
|
||||
import com.ecep.contract.manager.ui.table.cell.EmployeeTableCell;
|
||||
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.util.converter.LocalDateStringConverter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@FxmlPath("/ui/project/project-tab-bid.fxml")
|
||||
public class ProjectTabSkinBid
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
package com.ecep.contract.manager.ds.project.controller;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.ecep.contract.manager.ds.contract.model.Contract;
|
||||
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.service.ContractService;
|
||||
import com.ecep.contract.manager.ds.project.model.Project;
|
||||
import com.ecep.contract.manager.ds.project.model.ProjectFundPlan;
|
||||
import com.ecep.contract.manager.ds.project.service.ProjectFundPlanService;
|
||||
import com.ecep.contract.manager.ds.project.vo.ProjectFundPlanViewModel;
|
||||
import com.ecep.contract.manager.ui.FxmlPath;
|
||||
import com.ecep.contract.manager.ui.RefreshableSkin;
|
||||
import com.ecep.contract.manager.ui.tab.TabSkin;
|
||||
import com.ecep.contract.manager.ui.table.EditableEntityTableTabSkin;
|
||||
import com.ecep.contract.manager.util.NumberUtils;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 项目资金计划
|
||||
* 工单 #2
|
||||
* fxml 文件在 /src/main/resources/ui/ 目录
|
||||
*/
|
||||
@FxmlPath("/ui/project/project-tab-fund-plan.fxml")
|
||||
public class ProjectTabSkinFundPlan
|
||||
extends AbstProjectTableTabSkin<ProjectFundPlan, ProjectFundPlanViewModel>
|
||||
implements TabSkin, EditableEntityTableTabSkin<ProjectFundPlan, ProjectFundPlanViewModel>, RefreshableSkin {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProjectTabSkinFundPlan.class);
|
||||
|
||||
public TableColumn<ProjectFundPlanViewModel, Number> idColumn;
|
||||
public TableColumn<ProjectFundPlanViewModel, Number> versionColumn;
|
||||
public TableColumn<ProjectFundPlanViewModel, LocalDate> payDateColumn;
|
||||
public TableColumn<ProjectFundPlanViewModel, Number> payRatioColumn;
|
||||
public TableColumn<ProjectFundPlanViewModel, Number> payCurrencyColumn;
|
||||
public TableColumn<ProjectFundPlanViewModel, String> payTermColumn;
|
||||
public TableColumn<ProjectFundPlanViewModel, LocalDateTime> updateDateColumn;
|
||||
public TableColumn<ProjectFundPlanViewModel, String> payWayColumn;
|
||||
public Button updatePlanBtn;
|
||||
|
||||
@Setter
|
||||
private ProjectFundPlanService projectFundPlanService;
|
||||
|
||||
public ProjectTabSkinFundPlan(ProjectWindowController controller) {
|
||||
super(controller);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProjectFundPlanService getViewModelService() {
|
||||
if (projectFundPlanService == null) {
|
||||
projectFundPlanService = getBean(ProjectFundPlanService.class);
|
||||
}
|
||||
return projectFundPlanService;
|
||||
}
|
||||
|
||||
public ContractPayPlanService getContractPayPlanService() {
|
||||
return controller.getCachedBean(ContractPayPlanService.class);
|
||||
}
|
||||
|
||||
private ContractService getContractService() {
|
||||
return controller.getCachedBean(ContractService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tab getTab() {
|
||||
return controller.fundPlanTab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTable() {
|
||||
super.initializeTable();
|
||||
// 关闭所有的排序功能
|
||||
idColumn.setSortable(false);
|
||||
versionColumn.setSortable(false);
|
||||
payDateColumn.setSortable(false);
|
||||
payRatioColumn.setSortable(false);
|
||||
payCurrencyColumn.setSortable(false);
|
||||
payTermColumn.setSortable(false);
|
||||
updateDateColumn.setSortable(false);
|
||||
payWayColumn.setSortable(false);
|
||||
|
||||
bindNumberColumn(idColumn, ProjectFundPlanViewModel::getId);
|
||||
bindLocalDateColumn(payDateColumn, ProjectFundPlanViewModel::getPayDate);
|
||||
bindColumn(payWayColumn, model -> {
|
||||
javafx.beans.property.SimpleStringProperty property = new javafx.beans.property.SimpleStringProperty();
|
||||
property.set(model.getPayWay().get() != null ? model.getPayWay().get().getText() : "");
|
||||
return property;
|
||||
});
|
||||
bindNumberColumn(payRatioColumn, ProjectFundPlanViewModel::getPayRatio);
|
||||
bindNumberColumn(payCurrencyColumn, ProjectFundPlanViewModel::getPayCurrency);
|
||||
bindColumn(payTermColumn, ProjectFundPlanViewModel::getPayTerm);
|
||||
bindLocalDateTimeColumn(updateDateColumn, ProjectFundPlanViewModel::getUpdateDate);
|
||||
updatePlanBtn.setOnAction(this::onUpdatePlanAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectFundPlanViewModel> loadTableData(Project parent) {
|
||||
List<ProjectFundPlanViewModel> rows = super.loadTableData(parent);
|
||||
if (rows == null) {
|
||||
return null;
|
||||
}
|
||||
// TODO 按付款日期排序
|
||||
// rows.stream().sorted(Comparator.comparing(ProjectFundPlanViewModel::getPayDate)).collect(Collectors.toList());
|
||||
|
||||
return rows;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从合同的付款计划中更新项目的资金计划
|
||||
* 1. 从项目相关的合同中获取付款计划
|
||||
* 2. 更新项目的资金计划
|
||||
*/
|
||||
private void onUpdatePlanAction(ActionEvent event) {
|
||||
try {
|
||||
// 获取当前项目
|
||||
Project project = getParent();
|
||||
if (project == null || project.getId() == null) {
|
||||
setStatus("提示, 无法获取项目信息");
|
||||
return;
|
||||
}
|
||||
|
||||
List<ProjectFundPlan> fundPlans = getViewModelService().findAllByProject(project);
|
||||
// 将现有的项目资金计划转为以 ContractPayPlan 的id为key的map
|
||||
java.util.Map<Number, ProjectFundPlan> fundPlansMap = fundPlans.stream()
|
||||
.filter(plan -> plan.getContractPayPlan() != null && plan.getContractPayPlan().getId() != null)
|
||||
.collect(Collectors.toMap(
|
||||
plan -> plan.getContractPayPlan().getId(),
|
||||
plan -> plan));
|
||||
|
||||
// 获取项目关联的所有合同
|
||||
List<Contract> contracts = getContractService().findAllByProject(project);
|
||||
if (contracts == null || contracts.isEmpty()) {
|
||||
setStatus("提示, 未找到与项目关联的合同");
|
||||
return;
|
||||
}
|
||||
|
||||
// 遍历所有合同
|
||||
for (Contract contract : contracts) {
|
||||
// 获取合同的付款计划
|
||||
List<ContractPayPlan> payPlans = getContractPayPlanService().findAllByContract(contract);
|
||||
|
||||
// 遍历每个付款计划
|
||||
for (ContractPayPlan payPlan : payPlans) {
|
||||
// 检查是否已存在相同的合同付款计划
|
||||
if (fundPlansMap.containsKey(payPlan.getId())) {
|
||||
// 更新
|
||||
ProjectFundPlan fundPlan = fundPlansMap.remove(payPlan.getId());
|
||||
// 检查是否需要更新
|
||||
boolean needsUpdate = false;
|
||||
if (!Objects.equals(fundPlan.getPayWay(), contract.getPayWay())) {
|
||||
fundPlan.setPayWay(contract.getPayWay());
|
||||
needsUpdate = true;
|
||||
}
|
||||
if (!Objects.equals(fundPlan.getPayDate(), payPlan.getPayDate())) {
|
||||
fundPlan.setPayDate(payPlan.getPayDate());
|
||||
needsUpdate = true;
|
||||
}
|
||||
if (!NumberUtils.equals(fundPlan.getPayRatio(), payPlan.getPayRatio())) {
|
||||
fundPlan.setPayRatio(payPlan.getPayRatio());
|
||||
needsUpdate = true;
|
||||
}
|
||||
if (!Objects.equals(fundPlan.getPayTerm(), payPlan.getPayTerm())) {
|
||||
fundPlan.setPayTerm(payPlan.getPayTerm());
|
||||
needsUpdate = true;
|
||||
}
|
||||
if (!NumberUtils.equals(fundPlan.getPayCurrency(), payPlan.getPayCurrency())) {
|
||||
fundPlan.setPayCurrency(payPlan.getPayCurrency());
|
||||
needsUpdate = true;
|
||||
}
|
||||
if (needsUpdate) {
|
||||
fundPlan.setContractPayPlan(payPlan);
|
||||
fundPlan.setUpdateDate(LocalDateTime.now());
|
||||
saveRowData(fundPlan);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建新的项目资金计划
|
||||
ProjectFundPlan fundPlan = getViewModelService().newInstanceByProject(project);
|
||||
// 设置资金计划的属性
|
||||
fundPlan.setPayDate(payPlan.getPayDate());
|
||||
fundPlan.setPayWay(contract.getPayWay());
|
||||
fundPlan.setPayRatio(payPlan.getPayRatio());
|
||||
fundPlan.setPayTerm(payPlan.getPayTerm());
|
||||
fundPlan.setPayCurrency(payPlan.getPayCurrency());
|
||||
fundPlan.setContractPayPlan(payPlan);
|
||||
fundPlan.setUpdateDate(LocalDateTime.now());
|
||||
saveRowData(fundPlan);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除
|
||||
if (!fundPlansMap.isEmpty()) {
|
||||
for (ProjectFundPlan fundPlan : fundPlansMap.values()) {
|
||||
getViewModelService().delete(fundPlan);
|
||||
}
|
||||
}
|
||||
// 刷新表格数据
|
||||
refresh();
|
||||
} catch (Exception e) {
|
||||
logger.error("更新项目资金计划失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProjectFundPlanViewModel createNewViewModel() {
|
||||
ProjectFundPlanViewModel model = new ProjectFundPlanViewModel();
|
||||
Project project = getParent();
|
||||
model.getProject().set(project);
|
||||
model.getUpdateDate().set(LocalDateTime.now());
|
||||
saveRow(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTableRowDoubleClickedAction(ProjectFundPlanViewModel item) {
|
||||
// 可以在这里实现双击打开详情窗口的逻辑
|
||||
// 目前暂不实现具体的窗口
|
||||
}
|
||||
|
||||
private ProjectFundPlanService getProjectFundPlanService() {
|
||||
if (projectFundPlanService == null) {
|
||||
projectFundPlanService = getBean(ProjectFundPlanService.class);
|
||||
}
|
||||
return projectFundPlanService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRowData(ProjectFundPlan entity) {
|
||||
getProjectFundPlanService().delete(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectFundPlan loadRowData(ProjectFundPlanViewModel row) {
|
||||
return getProjectFundPlanService().findById(row.getId().get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectFundPlan saveRowData(ProjectFundPlan entity) {
|
||||
return getProjectFundPlanService().save(entity);
|
||||
}
|
||||
}
|
||||
@@ -108,6 +108,13 @@ public class ProjectWindowController extends AbstEntityController<Project, Proje
|
||||
* 投标 Bid Tab
|
||||
*/
|
||||
public Tab bidTab;
|
||||
/**
|
||||
* 资金计划 Tab
|
||||
*/
|
||||
public Tab fundPlanTab;
|
||||
/**
|
||||
* 顾客满意度 Tab
|
||||
*/
|
||||
public Tab satisfactionTab;
|
||||
|
||||
@Autowired
|
||||
@@ -144,6 +151,7 @@ public class ProjectWindowController extends AbstEntityController<Project, Proje
|
||||
registerTabSkin(costTab, tab -> new ProjectTabSkinCost(this));
|
||||
registerTabSkin(quotationApprovalTab, tab -> new ProjectTabSkinQuotation(this));
|
||||
registerTabSkin(bidTab, tab -> new ProjectTabSkinBid(this));
|
||||
registerTabSkin(fundPlanTab, tab -> new ProjectTabSkinFundPlan(this));
|
||||
// registerTabSkin(costItemTab, this::createCostItemTabSkin);
|
||||
registerTabSkin(satisfactionTab, tab -> new ProjectTabSkinCustomerSatisfactionSurvey(this));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.ecep.contract.manager.ds.project.model;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.ecep.contract.manager.ds.contract.ContractPayWay;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractPayPlan;
|
||||
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 项目投标
|
||||
* <p>
|
||||
* Approval 审批
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "PROJECT_FUND_PLAN")
|
||||
@ToString
|
||||
public class ProjectFundPlan implements IdentityEntity, ProjectBasedEntity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "ID", nullable = false)
|
||||
private Integer id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "PROJECT_ID")
|
||||
private Project project;
|
||||
/**
|
||||
* 付款日期
|
||||
*/
|
||||
@Column(name = "PAY_DATE")
|
||||
private LocalDate payDate;
|
||||
/**
|
||||
* 付款方式
|
||||
*/
|
||||
@Column(name = "PAY_WAY")
|
||||
@Enumerated(EnumType.ORDINAL)
|
||||
private ContractPayWay payWay;
|
||||
/**
|
||||
* 付款比例
|
||||
*/
|
||||
@Column(name = "PAY_RATIO")
|
||||
private float payRatio;
|
||||
/**
|
||||
* 付款金额
|
||||
*/
|
||||
@Column(name = "PAY_CURRENCY")
|
||||
private double payCurrency;
|
||||
/**
|
||||
* 付款条件
|
||||
*/
|
||||
@Column(name = "PAY_TERM")
|
||||
private String payTerm;
|
||||
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "CONTRACT_PAY_PLAN_ID")
|
||||
private ContractPayPlan contractPayPlan;
|
||||
|
||||
/**
|
||||
* 更新日期,从销售合同和采购合同中更新
|
||||
*/
|
||||
@Column(name = "UPDATE_TIME")
|
||||
private LocalDateTime updateDate;
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.ecep.contract.manager.ds.project.repository;
|
||||
|
||||
import com.ecep.contract.manager.ds.project.model.Project;
|
||||
import com.ecep.contract.manager.ds.project.model.ProjectBid;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ecep.contract.manager.ds.MyRepository;
|
||||
import com.ecep.contract.manager.ds.project.model.Project;
|
||||
import com.ecep.contract.manager.ds.project.model.ProjectBid;
|
||||
|
||||
@Repository
|
||||
public interface ProjectBidRepository
|
||||
extends JpaRepository<ProjectBid, Integer>, JpaSpecificationExecutor<ProjectBid> {
|
||||
public interface ProjectBidRepository extends MyRepository<ProjectBid, Integer> {
|
||||
|
||||
/**
|
||||
* 根据项目查询
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ecep.contract.manager.ds.project.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ecep.contract.manager.ds.MyRepository;
|
||||
import com.ecep.contract.manager.ds.project.model.Project;
|
||||
import com.ecep.contract.manager.ds.project.model.ProjectFundPlan;
|
||||
|
||||
@Repository
|
||||
public interface ProjectFundPlanRepository extends MyRepository<ProjectFundPlan, Integer> {
|
||||
/**
|
||||
* 根据项目查询
|
||||
*
|
||||
* @param project 项目
|
||||
* @return ProjectFundPlan list
|
||||
*/
|
||||
List<ProjectFundPlan> findAllByProject(Project project);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.ecep.contract.manager.ds.project.service;
|
||||
|
||||
import com.ecep.contract.manager.ds.project.model.Project;
|
||||
import com.ecep.contract.manager.ds.project.model.ProjectFundPlan;
|
||||
import com.ecep.contract.manager.ds.project.repository.ProjectFundPlanRepository;
|
||||
import com.ecep.contract.manager.ds.project.vo.ProjectFundPlanViewModel;
|
||||
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 java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
public class ProjectFundPlanService implements ViewModelService<ProjectFundPlan, ProjectFundPlanViewModel> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProjectFundPlanService.class);
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ProjectFundPlanRepository repository;
|
||||
|
||||
public ProjectFundPlan findById(Integer id) {
|
||||
return repository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<ProjectFundPlan> findAll(Specification<ProjectFundPlan> spec, Pageable pageable) {
|
||||
return repository.findAll(spec, pageable);
|
||||
}
|
||||
|
||||
public List<ProjectFundPlan> findAllByProject(Project project) {
|
||||
return repository.findAllByProject(project);
|
||||
}
|
||||
|
||||
public ProjectFundPlan save(ProjectFundPlan fundPlan) {
|
||||
return repository.save(fundPlan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specification<ProjectFundPlan> getSpecification(String searchText) {
|
||||
return (root, query, builder) -> {
|
||||
return builder.or(
|
||||
builder.like(root.get("payTerm"), "%" + searchText + "%"),
|
||||
builder.like(builder.toString(root.get("payRatio")), "%" + searchText + "%"),
|
||||
builder.like(builder.toString(root.get("payCurrency")), "%" + searchText + "%")
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
public void delete(ProjectFundPlan fundPlan) {
|
||||
repository.delete(fundPlan);
|
||||
}
|
||||
|
||||
public ProjectFundPlan newInstanceByProject(Project project) {
|
||||
ProjectFundPlan fundPlan = new ProjectFundPlan();
|
||||
fundPlan.setProject(project);
|
||||
fundPlan.setUpdateDate(LocalDateTime.now());
|
||||
return fundPlan;
|
||||
}
|
||||
|
||||
public List<ProjectFundPlan> findAll(Specification<ProjectFundPlan> spec, Sort sort) {
|
||||
return repository.findAll(spec, sort);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.ecep.contract.manager.ds.project.vo;
|
||||
|
||||
import com.ecep.contract.manager.ds.contract.ContractPayWay;
|
||||
import com.ecep.contract.manager.ds.contract.model.ContractPayPlan;
|
||||
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
|
||||
import com.ecep.contract.manager.ds.project.model.Project;
|
||||
import com.ecep.contract.manager.ds.project.model.ProjectFundPlan;
|
||||
import com.ecep.contract.manager.util.NumberUtils;
|
||||
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleFloatProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 项目资金计划视图模型
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ProjectFundPlanViewModel extends IdentityViewModel<ProjectFundPlan> implements ProjectBasedViewModel {
|
||||
/**
|
||||
* 关联的项目
|
||||
*/
|
||||
private SimpleObjectProperty<Project> project = new SimpleObjectProperty<>();
|
||||
|
||||
/**
|
||||
* 付款日期
|
||||
*/
|
||||
private SimpleObjectProperty<LocalDate> payDate = new SimpleObjectProperty<>();
|
||||
|
||||
/**
|
||||
* 付款比例
|
||||
*/
|
||||
private SimpleFloatProperty payRatio = new SimpleFloatProperty();
|
||||
|
||||
/**
|
||||
* 付款金额
|
||||
*/
|
||||
private SimpleDoubleProperty payCurrency = new SimpleDoubleProperty();
|
||||
/**
|
||||
* 余额
|
||||
*/
|
||||
private SimpleDoubleProperty balance = new SimpleDoubleProperty();
|
||||
/**
|
||||
* 付款条件
|
||||
*/
|
||||
private SimpleStringProperty payTerm = new SimpleStringProperty();
|
||||
|
||||
/**
|
||||
* 合同付款计划
|
||||
*/
|
||||
private SimpleObjectProperty<ContractPayPlan> contractPayPlan = new SimpleObjectProperty<>();
|
||||
|
||||
/**
|
||||
* 更新日期
|
||||
*/
|
||||
private SimpleObjectProperty<LocalDateTime> updateDate = new SimpleObjectProperty<>();
|
||||
|
||||
/**
|
||||
* 付款方式
|
||||
*/
|
||||
private SimpleObjectProperty<ContractPayWay> payWay = new SimpleObjectProperty<>();
|
||||
|
||||
/**
|
||||
* 从实体对象创建视图模型
|
||||
*/
|
||||
public static ProjectFundPlanViewModel from(ProjectFundPlan entity) {
|
||||
ProjectFundPlanViewModel model = new ProjectFundPlanViewModel();
|
||||
model.update(entity);
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFrom(ProjectFundPlan entity) {
|
||||
super.updateFrom(entity);
|
||||
|
||||
// 设置项目关联
|
||||
getProject().set(entity.getProject());
|
||||
|
||||
// 设置付款相关信息
|
||||
getPayDate().set(entity.getPayDate());
|
||||
getPayRatio().set(entity.getPayRatio());
|
||||
getPayCurrency().set(entity.getPayCurrency());
|
||||
getPayTerm().set(entity.getPayTerm());
|
||||
|
||||
// 设置合同付款计划关联
|
||||
getContractPayPlan().set(entity.getContractPayPlan());
|
||||
|
||||
// 设置更新日期
|
||||
getUpdateDate().set(entity.getUpdateDate());
|
||||
|
||||
// 设置付款方式
|
||||
getPayWay().set(entity.getPayWay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean copyTo(ProjectFundPlan entity) {
|
||||
boolean modified = super.copyTo(entity);
|
||||
|
||||
// 复制项目关联
|
||||
if (!Objects.equals(getProject().get(), entity.getProject())) {
|
||||
entity.setProject(getProject().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// 复制付款相关信息
|
||||
if (!Objects.equals(getPayDate().get(), entity.getPayDate())) {
|
||||
entity.setPayDate(getPayDate().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!NumberUtils.equals(getPayRatio().get(), entity.getPayRatio())) {
|
||||
entity.setPayRatio(getPayRatio().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!NumberUtils.equals(getPayCurrency().get(), entity.getPayCurrency())) {
|
||||
entity.setPayCurrency(getPayCurrency().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!Objects.equals(getPayTerm().get(), entity.getPayTerm())) {
|
||||
entity.setPayTerm(getPayTerm().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// 复制合同付款计划关联
|
||||
if (!Objects.equals(getContractPayPlan().get(), entity.getContractPayPlan())) {
|
||||
entity.setContractPayPlan(getContractPayPlan().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// 复制更新日期
|
||||
if (!Objects.equals(getUpdateDate().get(), entity.getUpdateDate())) {
|
||||
entity.setUpdateDate(getUpdateDate().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// 复制付款方式
|
||||
if (!Objects.equals(getPayWay().get(), entity.getPayWay())) {
|
||||
entity.setPayWay(getPayWay().get());
|
||||
modified = true;
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,11 +14,13 @@ import com.ecep.contract.manager.ds.vendor.service.CompanyVendorService;
|
||||
import com.ecep.contract.manager.ds.vendor.vo.CompanyVendorViewModel;
|
||||
import com.ecep.contract.manager.ui.tab.AbstEntityBasedTabSkin;
|
||||
import com.ecep.contract.manager.ui.ComboBoxUtils;
|
||||
import com.ecep.contract.manager.util.MyDateTimeUtils;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.util.converter.LocalDateStringConverter;
|
||||
import javafx.util.converter.LocalDateTimeStringConverter;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
@@ -36,7 +38,7 @@ public class CompanyVendorTabSkinBase
|
||||
return controller.baseInfoTab;
|
||||
}
|
||||
|
||||
CompanyContactService getCompanyContactService(){
|
||||
CompanyContactService getCompanyContactService() {
|
||||
if (companyContactService == null) {
|
||||
companyContactService = SpringApp.getBean(CompanyContactService.class);
|
||||
}
|
||||
@@ -45,14 +47,15 @@ public class CompanyVendorTabSkinBase
|
||||
|
||||
@Override
|
||||
public void initializeTab() {
|
||||
// initializeBaseTabCompanyFieldAutoCompletion(controller.companyField);
|
||||
// initializeBaseTabCompanyFieldAutoCompletion(controller.companyField);
|
||||
|
||||
LocalDateStringConverter converter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);
|
||||
|
||||
controller.developDateField.setConverter(converter);
|
||||
controller.developDateField.valueProperty().bindBidirectional(viewModel.getDevelopDate());
|
||||
|
||||
List<VendorTypeLocal> vendorTypeLocals = getCompanyVendorService().findAllTypes(controller.getLocale().toLanguageTag());
|
||||
List<VendorTypeLocal> vendorTypeLocals = getCompanyVendorService()
|
||||
.findAllTypes(controller.getLocale().toLanguageTag());
|
||||
ComboBoxUtils.initialComboBox(controller.catalogField, vendorTypeLocals, true);
|
||||
ComboBoxUtils.bindComboBox(controller.catalogField, viewModel.getType(), vendorTypeLocals);
|
||||
|
||||
@@ -62,7 +65,10 @@ public class CompanyVendorTabSkinBase
|
||||
|
||||
controller.pathField.textProperty().bind(viewModel.getPath());
|
||||
controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());
|
||||
controller.createdField.textProperty().bind(createStringBinding(viewModel.getCreated()));
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter
|
||||
.ofPattern(MyDateTimeUtils.DEFAULT_DATETIME_FORMAT_PATTERN);
|
||||
controller.createdField.textProperty().bindBidirectional(viewModel.getCreated(),
|
||||
new LocalDateTimeStringConverter(dateTimeFormatter, null));
|
||||
controller.versionLabel.textProperty().bind(viewModel.getVersion().asString());
|
||||
|
||||
controller.relativeCompanyBtn.disableProperty().bind(viewModel.getCompany().isNull());
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.ecep.contract.manager.ui.table.EditableEntityTableTabSkin;
|
||||
import com.ecep.contract.manager.ui.table.TableTabSkin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -20,6 +18,8 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
|
||||
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
|
||||
import com.ecep.contract.manager.ui.table.EditableEntityTableTabSkin;
|
||||
import com.ecep.contract.manager.ui.table.TableTabSkin;
|
||||
import com.ecep.contract.manager.util.TableViewUtils;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
|
||||
@@ -43,12 +43,15 @@ import javafx.scene.input.KeyEvent;
|
||||
import javafx.util.converter.NumberStringConverter;
|
||||
|
||||
/**
|
||||
* 实体管理器皮肤
|
||||
* 提供了实体管理器的基本功能,如查询、新增、删除、修改、分页等
|
||||
*
|
||||
* @param <T> Entity 的类型
|
||||
* @param <TV> Entity 对应的ViewModel
|
||||
* @param <Skin> Skin 的类型
|
||||
* @param <SKIN> Skin 的类型
|
||||
* @param <C>
|
||||
*/
|
||||
public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends IdentityViewModel<T>, Skin extends ManagerSkin, C extends AbstManagerWindowController<T, TV, Skin>>
|
||||
public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends IdentityViewModel<T>, SKIN extends ManagerSkin, C extends AbstManagerWindowController<T, TV, SKIN>>
|
||||
implements ManagerSkin, TableTabSkin<T, TV>, EditableEntityTableTabSkin<T, TV> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstEntityManagerSkin.class);
|
||||
/**
|
||||
@@ -61,6 +64,10 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
|
||||
protected PageRequest currentPageable = PageRequest.ofSize(25);
|
||||
protected final SimpleIntegerProperty currentPageNumber = new SimpleIntegerProperty();
|
||||
// 是否允许调整表格高度
|
||||
private boolean allowResize = true;
|
||||
// 记录延时任务信息
|
||||
private ScheduledFuture<?> loadTableDataSetFuture;
|
||||
|
||||
public AbstEntityManagerSkin(C controller) {
|
||||
this.controller = controller;
|
||||
@@ -199,6 +206,9 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
* 根据表格高度重新计算分页的页大小
|
||||
*/
|
||||
private void resizeTable(Object observable, Bounds old, Bounds newBounds) {
|
||||
if (!allowResize) {
|
||||
return;
|
||||
}
|
||||
double tableHeight = newBounds.getHeight();
|
||||
if (tableHeight <= 0) {
|
||||
return;
|
||||
@@ -208,8 +218,13 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
if (lookup != null) {
|
||||
double rowHeight = lookup.prefHeight(-1);
|
||||
int rows = (int) Math.round(table.getHeight() / rowHeight) - 1;
|
||||
int pageNumber = (int) Math.abs(currentPageable.getOffset() / rows);
|
||||
// 只有当行数变化超过一定阈值时才重新加载数据
|
||||
int currentRows = currentPageable.getPageSize();
|
||||
if (Math.abs(rows - currentRows) <= 2) {
|
||||
return; // 避免微小变化导致频繁刷新
|
||||
}
|
||||
|
||||
int pageNumber = (int) Math.abs(currentPageable.getOffset() / rows);
|
||||
if (currentPageable.getPageNumber() == pageNumber && currentPageable.getPageSize() == rows) {
|
||||
return;
|
||||
}
|
||||
@@ -259,9 +274,17 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
}
|
||||
}
|
||||
|
||||
protected <K> void acceptCellEditEvent(TableColumn.CellEditEvent<TV, K> event, Function<TV, Property<K>> function) {
|
||||
/**
|
||||
* 处理单元格编辑事件
|
||||
*
|
||||
* @param <K>
|
||||
* @param event
|
||||
* @param propGetter
|
||||
*/
|
||||
protected <K> void acceptCellEditEvent(TableColumn.CellEditEvent<TV, K> event,
|
||||
Function<TV, Property<K>> propGetter) {
|
||||
TV row = event.getRowValue();
|
||||
Property<K> property = function.apply(row);
|
||||
Property<K> property = propGetter.apply(row);
|
||||
property.setValue(event.getNewValue());
|
||||
try {
|
||||
saveRowData(row);
|
||||
@@ -317,21 +340,47 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
row.saveInFxApplicationThread(service);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载行数据
|
||||
*
|
||||
* @param row
|
||||
* @return
|
||||
*/
|
||||
public T loadRowData(TV row) {
|
||||
return getViewModelService().findById(row.getId().get());
|
||||
if (row.getId() == null) {
|
||||
return null;
|
||||
}
|
||||
T entity = getViewModelService().findById(row.getId().get());
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除行数据
|
||||
*
|
||||
* @param entity
|
||||
*/
|
||||
public void deleteRowData(T entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
ViewModelService<T, TV> service = getViewModelService();
|
||||
getViewModelService().delete(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存行数据
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public T saveRowData(T entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
ViewModelService<T, TV> service = getViewModelService();
|
||||
return getViewModelService().save(entity);
|
||||
}
|
||||
|
||||
// 记录延时任务信息
|
||||
private ScheduledFuture<?> loadTableDataSetFuture;
|
||||
|
||||
@Override
|
||||
public void loadTableDataSet() {
|
||||
loadTableDataSet(false);
|
||||
@@ -359,6 +408,7 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
private CompletableFuture<Void> _reloadTableData() {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
Platform.runLater(() -> {
|
||||
allowResize = false; // 禁用调整
|
||||
dataSet.clear();
|
||||
runAsync(() -> {
|
||||
controller.setStatus("载入中...");
|
||||
@@ -366,8 +416,10 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
updateTableDataSet(models);
|
||||
allowResize = true; // 恢复调整
|
||||
future.complete(null);
|
||||
} catch (Exception e) {
|
||||
allowResize = true; // 恢复调整
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
@@ -379,15 +431,41 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新表格数据
|
||||
*
|
||||
* @param models
|
||||
*/
|
||||
protected void updateTableDataSet(List<TV> models) {
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
dataSet.setAll(models);
|
||||
// 清除所有选择状态,避免选择状态混乱
|
||||
if (getTableView() != null && getTableView().getSelectionModel() != null) {
|
||||
getTableView().getSelectionModel().clearSelection();
|
||||
}
|
||||
|
||||
// 先清空再设置新数据,避免数据叠加
|
||||
dataSet.clear();
|
||||
if (models != null) {
|
||||
dataSet.addAll(models);
|
||||
}
|
||||
|
||||
// 强制刷新表格布局
|
||||
if (getTableView() != null) {
|
||||
getTableView().requestLayout();
|
||||
getTableView().refresh();
|
||||
}
|
||||
|
||||
long timeCost = System.currentTimeMillis() - timeMillis;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("update table dataSet cost: {} ms", timeCost);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载表格数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected List<TV> loadTableData() {
|
||||
Specification<T> spec = getSpecification();
|
||||
ViewModelService<T, TV> service = getViewModelService();
|
||||
@@ -404,16 +482,24 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
return page.map(service::from).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ViewModelService
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected ViewModelService<T, TV> getViewModelService() {
|
||||
ViewModelService<T, TV> service = controller.getViewModelService();
|
||||
if (service == null) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("ViewModelService is null");
|
||||
}
|
||||
throw new IllegalArgumentException("ViewModelService is null");
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Specification<T> getSpecification() {
|
||||
TextField field = controller.searchKeyField;
|
||||
if (field != null) {
|
||||
@@ -422,8 +508,14 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
*
|
||||
* @param searchText
|
||||
* @return
|
||||
*/
|
||||
protected Specification<T> getSpecification(String searchText) {
|
||||
return controller.getViewModelService().getSpecification(searchText);
|
||||
return getViewModelService().getSpecification(searchText);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -434,6 +526,11 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
protected void onTableRowDoubleClickedAction(TV item) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新页脚
|
||||
*
|
||||
* @param page
|
||||
*/
|
||||
protected void updateFooter(Page<T> page) {
|
||||
Platform.runLater(() -> {
|
||||
controller.previousPageBtn.setDisable(!page.hasPrevious());
|
||||
@@ -444,19 +541,44 @@ public abstract class AbstEntityManagerSkin<T extends IdentityEntity, TV extends
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表格排序
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Sort.Order> getTableOrders() {
|
||||
return TableViewUtils.getOrders(getTableView());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表格排序
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Sort getSortByTable() {
|
||||
if (getTableView() == null) {
|
||||
return Sort.unsorted();
|
||||
}
|
||||
return Sort.by(getTableOrders());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分页参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Pageable getPageable() {
|
||||
Sort sort = getSortByTable();
|
||||
return currentPageable.withSort(sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示在当前窗口为父窗口的新窗口
|
||||
*
|
||||
* @param <Controller> 控制器类型
|
||||
* @param clz 控制器类
|
||||
* @param model 数据
|
||||
*/
|
||||
protected <Controller extends AbstEntityController<T, TV>> void showInOwner(Class<Controller> clz, TV model) {
|
||||
BaseController.show(clz, model, getTableView().getScene().getWindow());
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.ecep.contract.manager.ui;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.manager.ui.tab.TabSkin;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class AbstGenericTabSkin<C extends BaseController> implements TabSkin {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstGenericTabSkin.class);
|
||||
@@ -18,6 +20,10 @@ public abstract class AbstGenericTabSkin<C extends BaseController> implements Ta
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
public <T> T getCachedBean(Class<T> requiredType) throws BeansException {
|
||||
return controller.getCachedBean(requiredType);
|
||||
}
|
||||
|
||||
protected void setStatus(String status) {
|
||||
controller.setStatus(status);
|
||||
}
|
||||
@@ -38,4 +44,5 @@ public abstract class AbstGenericTabSkin<C extends BaseController> implements Ta
|
||||
}
|
||||
UITools.showExceptionAndWait(message, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
package com.ecep.contract.manager.ui;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.manager.CurrentEmployee;
|
||||
import com.ecep.contract.manager.Desktop;
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import com.ecep.contract.manager.ds.other.model.Employee;
|
||||
@@ -9,6 +25,7 @@ import com.ecep.contract.manager.ds.other.service.SysConfService;
|
||||
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
|
||||
import com.ecep.contract.manager.util.FxmlUtils;
|
||||
import com.ecep.contract.manager.util.UITools;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
@@ -21,21 +38,6 @@ import javafx.stage.Stage;
|
||||
import javafx.stage.Window;
|
||||
import javafx.stage.WindowEvent;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BaseController {
|
||||
private static final Logger logger = LoggerFactory.getLogger(BaseController.class);
|
||||
@@ -45,7 +47,8 @@ public class BaseController {
|
||||
return show(clz, owner, null);
|
||||
}
|
||||
|
||||
public static <T extends BaseController> CompletableFuture<Void> show(Class<T> clz, Window owner, Consumer<T> consumer) {
|
||||
public static <T extends BaseController> CompletableFuture<Void> show(Class<T> clz, Window owner,
|
||||
Consumer<T> consumer) {
|
||||
String key = clz.getName();
|
||||
if (toFront(key)) {
|
||||
return null;
|
||||
@@ -63,10 +66,10 @@ public class BaseController {
|
||||
controller.show(loader, owner, Modality.NONE, key);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K extends IdentityEntity, M extends IdentityViewModel<K>, T extends BaseController>
|
||||
void show(Class<T> clz, M viewModel, Window owner) {
|
||||
public static <K extends IdentityEntity, M extends IdentityViewModel<K>, T extends BaseController> void show(
|
||||
Class<T> clz, M viewModel, Window owner) {
|
||||
String key = getKey(clz, viewModel);
|
||||
if (toFront(key)) {
|
||||
return;
|
||||
@@ -76,7 +79,6 @@ public class BaseController {
|
||||
throw new RuntimeException("@FxmlPath is required");
|
||||
}
|
||||
|
||||
|
||||
FxmlUtils.newLoaderAsyncWithRunLater(annotation.value(), null, loader -> {
|
||||
T controller = loader.getController();
|
||||
if (controller instanceof AbstEntityController<?, ?>) {
|
||||
@@ -114,7 +116,6 @@ public class BaseController {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static boolean toFront(String key) {
|
||||
Stage stage = stages.get(key);
|
||||
if (stage != null) {
|
||||
@@ -161,6 +162,11 @@ public class BaseController {
|
||||
return future;
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> runAsync(Runnable runnable) {
|
||||
return CompletableFuture.runAsync(runnable, Desktop.instance.getExecutorService())
|
||||
.exceptionally(this::handleException);
|
||||
}
|
||||
|
||||
/**
|
||||
* 窗口标题
|
||||
*/
|
||||
@@ -177,33 +183,30 @@ public class BaseController {
|
||||
private String stageKey;
|
||||
public Label leftStatusLabel;
|
||||
public Label rightStatusLabel;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Locale locale = Locale.getDefault();
|
||||
|
||||
@Setter
|
||||
private SysConfService confService;
|
||||
@Setter
|
||||
private EmployeeService employeeService;
|
||||
private Employee currentUser;
|
||||
|
||||
private HashMap<Class<?>, Object> cachedBeans = new HashMap<>();
|
||||
|
||||
protected <T> T getBean(Class<T> requiredType) throws BeansException {
|
||||
return SpringApp.getBean(requiredType);
|
||||
}
|
||||
|
||||
public SysConfService getConfService() {
|
||||
if (confService == null) {
|
||||
confService = getBean(SysConfService.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getCachedBean(Class<T> requiredType) throws BeansException {
|
||||
Object object = cachedBeans.get(requiredType);
|
||||
if (object == null) {
|
||||
object = getBean(requiredType);
|
||||
cachedBeans.put(requiredType, object);
|
||||
}
|
||||
return confService;
|
||||
return (T) object;
|
||||
}
|
||||
|
||||
public SysConfService getConfService() {
|
||||
return getCachedBean(SysConfService.class);
|
||||
}
|
||||
|
||||
public EmployeeService getEmployeeService() {
|
||||
if (employeeService == null) {
|
||||
employeeService = getBean(EmployeeService.class);
|
||||
}
|
||||
return employeeService;
|
||||
return getCachedBean(EmployeeService.class);
|
||||
}
|
||||
|
||||
public Employee getCurrentUser() {
|
||||
@@ -213,6 +216,18 @@ public class BaseController {
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
public CurrentEmployee getCurrentEmployee() {
|
||||
return Desktop.instance.getActiveEmployee();
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
CurrentEmployee currentEmployee = getCurrentEmployee();
|
||||
if (currentEmployee == null) {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
return currentEmployee.localeProperty().get();
|
||||
}
|
||||
|
||||
public String getMessage(String code, Object... args) {
|
||||
return SpringApp.getMessage(code, args, getLocale());
|
||||
}
|
||||
|
||||
@@ -6,6 +6,13 @@ import com.ecep.contract.manager.ds.other.model.IdentityEntity;
|
||||
import com.ecep.contract.manager.ds.other.service.IEntityService;
|
||||
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
|
||||
|
||||
/**
|
||||
* 视图模型服务接口
|
||||
*
|
||||
* @param <T> 实体类型
|
||||
* @param <TV> 视图模型类型
|
||||
* @author 2025-08-02
|
||||
*/
|
||||
public interface ViewModelService<T extends IdentityEntity, TV extends IdentityViewModel<T>>
|
||||
extends IEntityService<T> {
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
package com.ecep.contract.manager.ui.tab;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
|
||||
import com.ecep.contract.manager.ds.other.vo.IdentityViewModel;
|
||||
import com.ecep.contract.manager.ui.AbstEntityController;
|
||||
@@ -7,26 +15,15 @@ import com.ecep.contract.manager.ui.AbstGenericTabSkin;
|
||||
import com.ecep.contract.manager.ui.BaseController;
|
||||
import com.ecep.contract.manager.ui.FxmlPath;
|
||||
import com.ecep.contract.manager.util.FxmlUtils;
|
||||
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.beans.binding.StringBinding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Tab;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class AbstEntityBasedTabSkin<C extends AbstEntityController<T, V>, T extends IdentityEntity, V extends IdentityViewModel<T>>
|
||||
extends AbstGenericTabSkin<C> {
|
||||
@@ -184,20 +181,4 @@ public abstract class AbstEntityBasedTabSkin<C extends AbstEntityController<T, V
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String localDateTimeFormatter(Property<LocalDateTime> property) {
|
||||
LocalDateTime dateTime = property.getValue();
|
||||
if (dateTime == null) {
|
||||
return "";
|
||||
}
|
||||
return MyDateTimeUtils.format(dateTime);
|
||||
}
|
||||
|
||||
protected StringBinding createStringBinding(Property<LocalDateTime> property) {
|
||||
return Bindings.createStringBinding(
|
||||
() -> localDateTimeFormatter(property),
|
||||
property);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.ecep.contract.manager.ui.table.cell;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.ecep.contract.manager.Desktop;
|
||||
import com.ecep.contract.manager.ds.other.model.IdentityEntity;
|
||||
@@ -18,6 +20,8 @@ import javafx.application.Platform;
|
||||
* @param <T>
|
||||
*/
|
||||
public class AsyncUpdateTableCell<V, T extends IdentityEntity> extends javafx.scene.control.TableCell<V, T> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AsyncUpdateTableCell.class);
|
||||
|
||||
/**
|
||||
* 转换为文本
|
||||
*/
|
||||
@@ -32,6 +36,20 @@ public class AsyncUpdateTableCell<V, T extends IdentityEntity> extends javafx.sc
|
||||
}
|
||||
|
||||
private IEntityService<T> service;
|
||||
Future<?> syncFuture;
|
||||
|
||||
/**
|
||||
* 通过 #setService 设置服务类,或者子类实现, 提供服务类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected IEntityService<T> getServiceBean() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String format(T entity) {
|
||||
return toString(entity);
|
||||
}
|
||||
|
||||
public void setService(IEntityService<T> service) {
|
||||
this.service = service;
|
||||
@@ -44,13 +62,15 @@ public class AsyncUpdateTableCell<V, T extends IdentityEntity> extends javafx.sc
|
||||
return service;
|
||||
}
|
||||
|
||||
protected IEntityService<T> getServiceBean() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(T item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
// 取消之前的异步任务
|
||||
if (syncFuture != null) {
|
||||
syncFuture.cancel(true);
|
||||
syncFuture = null;
|
||||
}
|
||||
|
||||
if (empty || item == null) {
|
||||
setText(null);
|
||||
return;
|
||||
@@ -59,23 +79,45 @@ public class AsyncUpdateTableCell<V, T extends IdentityEntity> extends javafx.sc
|
||||
setText(format(item));
|
||||
return;
|
||||
}
|
||||
|
||||
setText("# " + item.getId());
|
||||
submit(this::asyncLoadAndUpdate);
|
||||
syncFuture = submit(this::asyncLoadAndUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查实体是否已初始化
|
||||
*
|
||||
* @param proxy
|
||||
* @return
|
||||
*/
|
||||
protected boolean isInitialized(T proxy) {
|
||||
return Hibernate.isInitialized(proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化实体
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected T initialize() {
|
||||
return getService().findById(getItem().getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交异步任务
|
||||
*
|
||||
* @param var1 异步任务
|
||||
* @return
|
||||
*/
|
||||
Future<?> submit(Runnable var1) {
|
||||
return Desktop.instance.getExecutorService().submit(var1);
|
||||
}
|
||||
|
||||
public String format(T entity) {
|
||||
return toString(entity);
|
||||
}
|
||||
|
||||
protected void asyncLoadAndUpdate() {
|
||||
if (getItem() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
T entity = initialize();
|
||||
String formated;
|
||||
try {
|
||||
@@ -84,14 +126,26 @@ public class AsyncUpdateTableCell<V, T extends IdentityEntity> extends javafx.sc
|
||||
formated = e.getMessage();
|
||||
}
|
||||
String texted = formated;
|
||||
|
||||
// 保存当前需要更新的项目信息,避免闭包引用导致的问题
|
||||
final T updatedEntity = entity;
|
||||
final String updatedText = texted;
|
||||
final T finalCurrentLoadingItem = getItem();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
setText(texted);
|
||||
setItem(entity);
|
||||
// 检查单元格是否仍然显示相同的项目
|
||||
// 如果单元格已被重用或当前项目已改变,则不更新
|
||||
if (isEmpty() || getItem() == null) {
|
||||
logger.debug("Skipping async update - cell reused ");
|
||||
return;
|
||||
}
|
||||
if (getItem().getId() != finalCurrentLoadingItem.getId()) {
|
||||
logger.debug("Skipping async update - cell item changed");
|
||||
return;
|
||||
}
|
||||
setItem(updatedEntity);
|
||||
setText(updatedText);
|
||||
});
|
||||
}
|
||||
|
||||
protected T initialize() {
|
||||
return getService().findById(getItem().getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.ecep.contract.manager.ui.table.cell;
|
||||
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyService;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import static com.ecep.contract.manager.SpringApp.getBean;
|
||||
|
||||
import com.ecep.contract.manager.ds.company.model.Company;
|
||||
import com.ecep.contract.manager.ds.company.service.CompanyService;
|
||||
|
||||
import lombok.NoArgsConstructor;
|
||||
/**
|
||||
* 公司单元格
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public class CompanyTableCell<V> extends AsyncUpdateTableCell<V, Company> {
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ecep.contract.manager.ui.table.cell;
|
||||
|
||||
import com.ecep.contract.manager.ds.other.model.EmployeeRole;
|
||||
import com.ecep.contract.manager.ds.other.service.EmployeeRoleService;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import static com.ecep.contract.manager.SpringApp.getBean;
|
||||
|
||||
/**
|
||||
* 角色表格列
|
||||
*
|
||||
* @param <V>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
public class EmployeeRoleTableCell<V> extends AsyncUpdateTableCell<V, EmployeeRole> {
|
||||
|
||||
public EmployeeRoleTableCell(EmployeeRoleService service) {
|
||||
setService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EmployeeRoleService getServiceBean() {
|
||||
return getBean(EmployeeRoleService.class);
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ public class TaskMonitorCenter {
|
||||
tooltip.setText("当前运行任务数: " + activeTasks.size());
|
||||
});
|
||||
monitorLabel.setOnMouseClicked(event -> {
|
||||
BaseController.show(TaskMonitorViewController.class, monitorLabel.getScene().getWindow());
|
||||
BaseController.show(TaskMonitorViewController.class, monitorLabel.getScene().getWindow());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.ecep.contract.manager.ui.task;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
@@ -13,6 +17,7 @@ import com.ecep.contract.manager.ui.Message;
|
||||
import com.ecep.contract.manager.util.MyDateTimeUtils;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
@@ -30,6 +35,7 @@ import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.WindowEvent;
|
||||
|
||||
@@ -69,10 +75,47 @@ public class TaskMonitorViewController extends BaseController {
|
||||
private Button cancelTaskButton;
|
||||
@FXML
|
||||
private Button clearHistoryButton;
|
||||
@FXML
|
||||
private Button refreshExecutorInfoButton;
|
||||
@FXML
|
||||
private TableView<ExecutorInfo> executorInfoTable;
|
||||
@FXML
|
||||
private TableColumn<ExecutorInfo, String> executorFieldColumn;
|
||||
@FXML
|
||||
private TableColumn<ExecutorInfo, String> executorValueColumn;
|
||||
@FXML
|
||||
private TableColumn<ExecutorInfo, String> executorDescriptionColumn;
|
||||
|
||||
public TaskMonitorViewController() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于存储ExecutorService信息的内部类
|
||||
*/
|
||||
public static class ExecutorInfo {
|
||||
private final String field;
|
||||
private final String value;
|
||||
private final String description;
|
||||
|
||||
public ExecutorInfo(String field, String value, String description) {
|
||||
this.field = field;
|
||||
this.value = value;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShown(WindowEvent windowEvent) {
|
||||
super.onShown(windowEvent);
|
||||
@@ -144,6 +187,94 @@ public class TaskMonitorViewController extends BaseController {
|
||||
});
|
||||
|
||||
cancelTaskButton.disableProperty().bind(activeTasksTable.getSelectionModel().selectedItemProperty().isNull());
|
||||
// 初始化Executor信息表格
|
||||
initializeExecutorInfoTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Executor信息表格
|
||||
*/
|
||||
private void initializeExecutorInfoTable() {
|
||||
executorFieldColumn.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getField()));
|
||||
executorValueColumn.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getValue()));
|
||||
executorDescriptionColumn
|
||||
.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getDescription()));
|
||||
|
||||
// 初始加载Executor信息
|
||||
refreshExecutorInfo();
|
||||
// 绑定刷新按钮事件
|
||||
refreshExecutorInfoButton.setOnAction(event -> refreshExecutorInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新Executor信息
|
||||
*/
|
||||
@FXML
|
||||
private void refreshExecutorInfo() {
|
||||
executorInfoTable.getItems().clear();
|
||||
|
||||
try {
|
||||
ExecutorService executorService = Desktop.instance.getExecutorService();
|
||||
if (executorService instanceof ThreadPoolExecutor threadPoolExecutor) {
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"PoolSize",
|
||||
String.valueOf(threadPoolExecutor.getPoolSize()),
|
||||
"PoolSize"));
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"活动线程数",
|
||||
String.valueOf(threadPoolExecutor.getActiveCount()),
|
||||
"当前正在执行任务的线程数"));
|
||||
// 添加线程池信息
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"核心线程数",
|
||||
String.valueOf(threadPoolExecutor.getCorePoolSize()),
|
||||
"线程池维护的最小线程数"));
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"最大线程数",
|
||||
String.valueOf(threadPoolExecutor.getMaximumPoolSize()),
|
||||
"线程池允许的最大线程数"));
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"KeepAliveTime",
|
||||
String.valueOf(threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS)),
|
||||
"the thread keep-alive time, which is the amount of time that threads may remain idle before being terminated. Threads that wait this amount of time without processing a task will be terminated if there are more than the core number of threads currently in the pool, or if this pool allows core thread timeout."));
|
||||
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"任务队列大小",
|
||||
String.valueOf(threadPoolExecutor.getQueue().size()),
|
||||
"等待执行的任务数量"));
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"已完成任务数",
|
||||
String.valueOf(threadPoolExecutor.getCompletedTaskCount()),
|
||||
"已完成执行的任务总数"));
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"LargestPoolSize",
|
||||
String.valueOf(threadPoolExecutor.getLargestPoolSize()),
|
||||
"线程池当前状态"));
|
||||
|
||||
// 如果是ScheduledExecutorService,添加额外信息
|
||||
if (executorService instanceof ScheduledExecutorService) {
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"线程池类型",
|
||||
"ScheduledExecutorService",
|
||||
"可调度的线程池"));
|
||||
} else {
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"线程池类型",
|
||||
"ThreadPoolExecutor",
|
||||
"普通线程池"));
|
||||
}
|
||||
} else {
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"错误",
|
||||
"未知的ExecutorService类型",
|
||||
"无法获取线程池详细信息"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
executorInfoTable.getItems().add(new ExecutorInfo(
|
||||
"异常",
|
||||
e.getMessage(),
|
||||
"获取ExecutorService信息时发生错误"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,7 +336,7 @@ public class TaskMonitorViewController extends BaseController {
|
||||
text.setFill(Color.ORANGE);
|
||||
} else if (msg.getLevel() == Level.SEVERE) {
|
||||
text.setFill(Color.RED);
|
||||
}else if (msg.getLevel()== Level.CONFIG) {
|
||||
} else if (msg.getLevel() == Level.CONFIG) {
|
||||
text.setFill(Color.GRAY);
|
||||
}
|
||||
vBox.getChildren().add(text);
|
||||
@@ -218,4 +349,11 @@ public class TaskMonitorViewController extends BaseController {
|
||||
alert.getDialogPane().setContent(scrollPane);
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行任务监控演示
|
||||
*/
|
||||
public void onRunTaskMonitorDemo(ActionEvent event) {
|
||||
com.ecep.contract.manager.ui.task.DemoTask.runDemo();
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,12 @@ import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
public class MyDateTimePropertyUtils {
|
||||
/**
|
||||
* 本地日期时间转换为时间戳
|
||||
*
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public static Instant localDateTimeToInstant(SimpleObjectProperty<LocalDateTime> property) {
|
||||
LocalDateTime dateTime = property.get();
|
||||
if (dateTime != null) {
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package com.ecep.contract.manager.util;
|
||||
|
||||
import com.ecep.contract.manager.AppV2;
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.ecep.contract.manager.AppV2;
|
||||
import com.ecep.contract.manager.Desktop;
|
||||
import com.ecep.contract.manager.SpringApp;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
||||
public class FxmlUtils {
|
||||
|
||||
public static FXMLLoader newLoader(String path) {
|
||||
@@ -22,8 +24,8 @@ public class FxmlUtils {
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
||||
public static CompletableFuture<FXMLLoader> newLoaderAsync(String path, java.util.function.Consumer<FXMLLoader> consumer) {
|
||||
public static CompletableFuture<FXMLLoader> newLoaderAsync(String path,
|
||||
java.util.function.Consumer<FXMLLoader> consumer) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
FXMLLoader loader = newLoader(path);
|
||||
try {
|
||||
@@ -43,16 +45,15 @@ public class FxmlUtils {
|
||||
/**
|
||||
* 异步载入显示界面
|
||||
*
|
||||
* @param path fxml文件路径,类地址 / 开头 根路径
|
||||
* @param path fxml文件路径,类地址 / 开头 根路径
|
||||
* @param initializeLoader fxml 文件加载完毕后,回调函数
|
||||
* @param runLater 在JavaFx线程中执行的回调函数
|
||||
* @param runLater 在JavaFx线程中执行的回调函数
|
||||
* @return CompletableFuture
|
||||
*/
|
||||
public static CompletableFuture<Void> newLoaderAsyncWithRunLater(
|
||||
String path,
|
||||
java.util.function.Consumer<FXMLLoader> initializeLoader,
|
||||
java.util.function.Consumer<FXMLLoader> runLater
|
||||
) {
|
||||
java.util.function.Consumer<FXMLLoader> runLater) {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
@@ -72,7 +73,7 @@ public class FxmlUtils {
|
||||
} catch (IOException e) {
|
||||
future.completeExceptionally(new RuntimeException("Unable open " + path, e));
|
||||
}
|
||||
}).whenComplete((v, ex) -> {
|
||||
}, Desktop.instance.getExecutorService()).whenComplete((v, ex) -> {
|
||||
if (ex != null) {
|
||||
future.completeExceptionally(ex);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<logger name="com.ecep.contract.manager.ui.service" level="info"/>
|
||||
|
||||
<logger name="com.ecep.contract.manager.ui.table.AbstEntityTableTabSkin" level="debug"/>
|
||||
<logger name="com.ecep.contract.manager.ui.table.cell.AsyncUpdateTableCell" level="warn"/>
|
||||
<logger name="com.ecep.contract.manager.ui.AbstEntityManagerSkin" level="debug"/>
|
||||
<logger name="com.ecep.contract.manager.ui.BaseController" level="debug"/>
|
||||
<logger name="com.ecep.contract.manager.ui.controller" level="info"/>
|
||||
|
||||
46
src/main/resources/ui/cloud/u8_config.fxml
Normal file
46
src/main/resources/ui/cloud/u8_config.fxml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.DatePicker?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import org.controlsfx.control.ToggleSwitch?>
|
||||
|
||||
<VBox prefHeight="400.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ecep.contract.manager.cloud.u8.YongYouU8ConfigWindowController">
|
||||
<children>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" minWidth="50.0" prefWidth="250.0" />
|
||||
<ColumnConstraints fillWidth="false" halignment="RIGHT" hgrow="NEVER" maxWidth="5.0" minWidth="5.0" prefWidth="5.0" />
|
||||
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints fillHeight="false" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints fillHeight="false" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints fillHeight="false" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints fillHeight="false" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label text="同步时公司未创建时, 公司开发日期在此之后的自动创建" GridPane.columnIndex="2" GridPane.rowIndex="1" />
|
||||
<DatePicker fx:id="auto_create_company_after" GridPane.columnIndex="2" />
|
||||
<Label text="cloud.u8.contract.latestDate" GridPane.rowIndex="4" />
|
||||
<TextField fx:id="contract_latest_date" GridPane.columnIndex="2" GridPane.rowIndex="4" />
|
||||
<Label text="cloud.u8.contract.latestId" GridPane.rowIndex="5" />
|
||||
<TextField fx:id="contract_latest_id" GridPane.columnIndex="2" GridPane.rowIndex="5" />
|
||||
<Label text="cloud.u8.sync.elapse" GridPane.rowIndex="6" />
|
||||
<TextField fx:id="sync_elapse" GridPane.columnIndex="2" GridPane.rowIndex="6" />
|
||||
<Label text="创建在此之后日期的公司" />
|
||||
<ToggleSwitch fx:id="use_latest_id" GridPane.columnIndex="2" GridPane.rowIndex="2" />
|
||||
<Label text="使用latestId同步" GridPane.rowIndex="2" />
|
||||
<Label text="合同同步时是否使用最后更新的Id来判断更新范围,否则使用最后更新的合同日期来判断更新范围" GridPane.columnIndex="2" GridPane.rowIndex="3" />
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</VBox>
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
<VBox prefHeight="400.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.ecep.contract.manager.cloud.u8.YongYouU8ManagerWindowController">
|
||||
<children>
|
||||
<MenuBar VBox.vgrow="NEVER">
|
||||
@@ -18,7 +18,7 @@
|
||||
<MenuItem mnemonicParsing="false" text="Save As…"/>
|
||||
<MenuItem mnemonicParsing="false" text="Revert"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem mnemonicParsing="false" text="Preferences…"/>
|
||||
<MenuItem mnemonicParsing="false" text="配置…" onAction="#onConfigAction"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem mnemonicParsing="false" text="Quit"/>
|
||||
</items>
|
||||
|
||||
@@ -1,212 +1,192 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import org.controlsfx.control.TaskProgressView?>
|
||||
|
||||
<VBox fx:id="root" prefHeight="468.0" prefWidth="737.0" xmlns="http://javafx.com/javafx/22"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="com.ecep.contract.manager.ds.other.controller.HomeWindowController">
|
||||
<children>
|
||||
<MenuBar>
|
||||
<menus>
|
||||
<Menu text="文件(_F)">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="Action 1"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openConfigWindow" text="选项…"/>
|
||||
<Menu text="数据源">
|
||||
<MenuItem mnemonicParsing="false" onAction="#openGroupRKResourceWindow" text="集团相关方…"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openTycResourceWindow" text="天眼查…"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openYongYouResourceWindow" text="用友U8…"/>
|
||||
</Menu>
|
||||
<children>
|
||||
<MenuBar>
|
||||
<menus>
|
||||
<Menu text="文件(_F)">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" text="Action 1"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openConfigWindow" text="选项…"/>
|
||||
<Menu text="数据源">
|
||||
<MenuItem mnemonicParsing="false" onAction="#openGroupRKResourceWindow" text="集团相关方…"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openTycResourceWindow" text="天眼查…"/>
|
||||
</Menu>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu mnemonicParsing="false" text="公司">
|
||||
<items>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu mnemonicParsing="false" text="公司">
|
||||
<items>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu mnemonicParsing="false" text="用友U8">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" onAction="#createNewU8ContractSyncTaskAction"
|
||||
text="同步合同"/>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu text="设置(_S)">
|
||||
<items>
|
||||
<MenuItem onAction="#onShowEmployeeManagerWindowAction" text="员工管理(_E)"/>
|
||||
<MenuItem onAction="#onShowDepartmentManagerWindowAction" text="部门管理(_D)"/>
|
||||
<MenuItem onAction="#onShowRolesManagerWindowAction" text="角色管理(_R)"/>
|
||||
<MenuItem onAction="#onShowFunctionManagerWindowAction" text="功能管理(_R)"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem onAction="#onShowBankManagerWindowAction" text="银行管理(_B)"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem onAction="#onShowTaskMonitorWindowAction" text="任务监控(_M)"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem onAction="#onShowInventoryManagerWindowAction" text="存货管理(_I)"/>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu text="帮助(_H)">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openInBrowse" text="国家企业信用信息公示系统"
|
||||
userData="https://www.gsxt.gov.cn/"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openInBrowse" text="天眼查-商业查询平台"
|
||||
userData="https://www.tianyancha.com/"/>
|
||||
<MenuItem mnemonicParsing="false" text="关于"/>
|
||||
</items>
|
||||
</Menu>
|
||||
</menus>
|
||||
</MenuBar>
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0">
|
||||
<items>
|
||||
<Button fx:id="openCompanyManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;"
|
||||
userData="com.ecep.contract.manager.ds.company.controller.CompanyManagerWindowController">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
<image>
|
||||
<Image url="@img/f4.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<Label text="公司">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button fx:id="openProjectManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f0.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="项目">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button fx:id="openContractManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f1.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="合同">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button fx:id="openVendorManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f2.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="供应商">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<!-- 客户 -->
|
||||
<Button fx:id="openCustomManagerWindow" layoutX="138.0" layoutY="10.0" mnemonicParsing="false"
|
||||
style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f3.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="客户">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
|
||||
<!-- 任务监控演示 -->
|
||||
<Button mnemonicParsing="false" style="-fx-padding: 6px;" onAction="#onRunTaskMonitorDemo">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="任务监控演示">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
</items>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<padding>
|
||||
<Insets bottom="6.0" left="6.0" right="6.0" top="6.0"/>
|
||||
</padding>
|
||||
</ToolBar>
|
||||
<AnchorPane prefHeight="248.0" prefWidth="2239.0" VBox.vgrow="ALWAYS"/>
|
||||
<TaskProgressView fx:id="taskProgressView"/>
|
||||
<HBox fx:id="statusBar" spacing="5.0">
|
||||
<children>
|
||||
<Label fx:id="leftStatusLabel" text="Label" wrapText="true"/>
|
||||
<Pane prefHeight="12.0" prefWidth="12.0" HBox.hgrow="ALWAYS"/>
|
||||
<Label fx:id="rightStatusLabel" layoutX="10.0" layoutY="10.0" text="-" wrapText="true"
|
||||
HBox.hgrow="SOMETIMES">
|
||||
<HBox.margin>
|
||||
<Insets left="6.0"/>
|
||||
</HBox.margin>
|
||||
</Menu>
|
||||
<Menu mnemonicParsing="false" text="用友U8">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" onAction="#createNewU8ContractSyncTaskAction"
|
||||
text="同步合同"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openYongYouResourceWindow" text="用友U8…"/>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu text="设置(_S)">
|
||||
<items>
|
||||
<MenuItem onAction="#onShowEmployeeManagerWindowAction" text="员工管理(_E)"/>
|
||||
<MenuItem onAction="#onShowDepartmentManagerWindowAction" text="部门管理(_D)"/>
|
||||
<MenuItem onAction="#onShowRolesManagerWindowAction" text="角色管理(_R)"/>
|
||||
<MenuItem onAction="#onShowFunctionManagerWindowAction" text="功能管理(_R)"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem onAction="#onShowBankManagerWindowAction" text="银行管理(_B)"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem onAction="#onShowTaskMonitorWindowAction" text="任务监控(_M)"/>
|
||||
<SeparatorMenuItem mnemonicParsing="false"/>
|
||||
<MenuItem onAction="#onShowInventoryManagerWindowAction" text="存货管理(_I)"/>
|
||||
</items>
|
||||
</Menu>
|
||||
<Menu text="帮助(_H)">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openInBrowse" text="国家企业信用信息公示系统"
|
||||
userData="https://www.gsxt.gov.cn/"/>
|
||||
<MenuItem mnemonicParsing="false" onAction="#openInBrowse" text="天眼查-商业查询平台"
|
||||
userData="https://www.tianyancha.com/"/>
|
||||
<MenuItem mnemonicParsing="false" text="关于"/>
|
||||
</items>
|
||||
</Menu>
|
||||
</menus>
|
||||
</MenuBar>
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0">
|
||||
<items>
|
||||
<Button fx:id="openCompanyManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;"
|
||||
userData="com.ecep.contract.manager.ds.company.controller.CompanyManagerWindowController">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
<image>
|
||||
<Image url="@img/f4.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<Label text="公司">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<Label fx:id="taskMonitorLabel" text="任务监控"></Label>
|
||||
<Label fx:id="employeeStatusLabel" layoutX="711.0" layoutY="10.0" text="管理员" wrapText="true"
|
||||
HBox.hgrow="SOMETIMES">
|
||||
<HBox.margin>
|
||||
<Insets left="6.0"/>
|
||||
</HBox.margin>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button fx:id="openProjectManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f0.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="项目">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button fx:id="openContractManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f1.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="合同">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<Button fx:id="openVendorManagerWindow" mnemonicParsing="false" style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f2.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="供应商">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
<!-- 客户 -->
|
||||
<Button fx:id="openCustomManagerWindow" layoutX="138.0" layoutY="10.0" mnemonicParsing="false"
|
||||
style="-fx-padding: 6px;">
|
||||
<graphic>
|
||||
<VBox alignment="CENTER">
|
||||
<children>
|
||||
<ImageView fitHeight="46.0" fitWidth="64.0">
|
||||
<Image url="@img/f3.png"/>
|
||||
<viewport>
|
||||
<Rectangle2D height="46.0" width="64.0"/>
|
||||
</viewport>
|
||||
</ImageView>
|
||||
<Label text="客户">
|
||||
<VBox.margin>
|
||||
<Insets top="5.0"/>
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
</graphic>
|
||||
</Button>
|
||||
</items>
|
||||
<opaqueInsets>
|
||||
<Insets/>
|
||||
</opaqueInsets>
|
||||
<padding>
|
||||
<Insets bottom="6.0" left="6.0" right="6.0" top="6.0"/>
|
||||
</padding>
|
||||
</ToolBar>
|
||||
<AnchorPane prefHeight="248.0" prefWidth="2239.0" VBox.vgrow="ALWAYS"/>
|
||||
<TaskProgressView fx:id="taskProgressView"/>
|
||||
<HBox fx:id="statusBar" spacing="5.0">
|
||||
<children>
|
||||
<Label fx:id="leftStatusLabel" text="Label" wrapText="true"/>
|
||||
<Pane prefHeight="12.0" prefWidth="12.0" HBox.hgrow="ALWAYS"/>
|
||||
<Label fx:id="rightStatusLabel" layoutX="10.0" layoutY="10.0" text="-" wrapText="true"
|
||||
HBox.hgrow="SOMETIMES">
|
||||
<HBox.margin>
|
||||
<Insets left="6.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<Label fx:id="taskMonitorLabel" text="任务监控"/>
|
||||
<Label fx:id="employeeStatusLabel" layoutX="711.0" layoutY="10.0" text="管理员" wrapText="true"
|
||||
HBox.hgrow="SOMETIMES">
|
||||
<HBox.margin>
|
||||
<Insets left="6.0"/>
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
|
||||
37
src/main/resources/ui/project/project-tab-fund-plan.fxml
Normal file
37
src/main/resources/ui/project/project-tab-fund-plan.fxml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ecep.contract.manager.ds.project.controller.ProjectTabSkinFundPlan">
|
||||
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<HBox spacing="3.0">
|
||||
<children>
|
||||
<TextField fx:id="searchKeyField" promptText="检索关键字"/>
|
||||
<Button fx:id="searchBtn" mnemonicParsing="false" text="检索"/>
|
||||
<Separator orientation="VERTICAL"/>
|
||||
<Button fx:id="updatePlanBtn" mnemonicParsing="false" text="更新"/>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="7.0" right="10.0" top="10.0"/>
|
||||
</padding>
|
||||
</HBox>
|
||||
<TableView fx:id="table" VBox.vgrow="ALWAYS" sortable="false">
|
||||
<columns>
|
||||
<TableColumn fx:id="idColumn" prefWidth="60.0" sortable="true" text="ID"/>
|
||||
<TableColumn fx:id="payDateColumn" prefWidth="120.0" sortable="true" text="付款日期"/>
|
||||
<TableColumn fx:id="payWayColumn" prefWidth="120.0" sortable="true" text="付款方式"/>
|
||||
<TableColumn fx:id="payCurrencyColumn" prefWidth="120.0" sortable="true" text="付款金额"/>
|
||||
|
||||
<TableColumn fx:id="payRatioColumn" prefWidth="100.0" sortable="true" text="付款比例"/>
|
||||
<TableColumn fx:id="payTermColumn" prefWidth="200.0" sortable="true" text="付款条件"/>
|
||||
<TableColumn fx:id="updateDateColumn" prefWidth="180.0" sortable="true" text="更新日期"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
|
||||
</padding>
|
||||
</AnchorPane>
|
||||
@@ -191,6 +191,8 @@
|
||||
</Tab>
|
||||
<Tab fx:id="contractTab" text="相关合同">
|
||||
</Tab>
|
||||
<Tab fx:id="fundPlanTab" text="资金计划">
|
||||
</Tab>
|
||||
<Tab fx:id="satisfactionTab" text="顾客满意度">
|
||||
</Tab>
|
||||
<Tab text="发货">
|
||||
|
||||
@@ -8,56 +8,83 @@
|
||||
<?import javafx.scene.control.ToolBar?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
|
||||
<TabPane minHeight="400.0" minWidth="500.0" tabMinWidth="70.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ecep.contract.manager.ui.task.TaskMonitorViewController">
|
||||
<tabs>
|
||||
<VBox minHeight="400.0" minWidth="500.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ecep.contract.manager.ui.task.TaskMonitorViewController">
|
||||
<ToolBar>
|
||||
<items>
|
||||
<Button fx:id="runTaskMonitorDemoBtn" text="运行演示任务" onAction="#onRunTaskMonitorDemo"/>
|
||||
</items>
|
||||
</ToolBar>
|
||||
<TabPane tabMinWidth="70.0" VBox.vgrow="ALWAYS">
|
||||
<tabs>
|
||||
<Tab closable="false" text="活动任务">
|
||||
<content>
|
||||
<VBox>
|
||||
<children>
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0">
|
||||
<items>
|
||||
<Button fx:id="cancelTaskButton" text="取消选中任务" />
|
||||
</items>
|
||||
</ToolBar>
|
||||
<TableView fx:id="activeTasksTable">
|
||||
<columns>
|
||||
<TableColumn fx:id="activeTaskIdColumn" prefWidth="150.0" text="任务ID" />
|
||||
<TableColumn fx:id="activeTaskTitleColumn" prefWidth="200.0" text="任务标题" />
|
||||
<TableColumn fx:id="activeTaskProgressColumn" prefWidth="150.0" text="进度" />
|
||||
<TableColumn fx:id="activeTaskStatusColumn" prefWidth="100.0" text="状态" />
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox>
|
||||
<children>
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0">
|
||||
<items>
|
||||
<Button fx:id="cancelTaskButton" text="取消选中任务"/>
|
||||
</items>
|
||||
</ToolBar>
|
||||
<TableView fx:id="activeTasksTable">
|
||||
<columns>
|
||||
<TableColumn fx:id="activeTaskIdColumn" prefWidth="150.0" text="任务ID"/>
|
||||
<TableColumn fx:id="activeTaskTitleColumn" prefWidth="200.0" text="任务标题"/>
|
||||
<TableColumn fx:id="activeTaskProgressColumn" prefWidth="150.0" text="进度"/>
|
||||
<TableColumn fx:id="activeTaskStatusColumn" prefWidth="100.0" text="状态"/>
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab closable="false" text="任务历史">
|
||||
<content>
|
||||
<content>
|
||||
<!-- 历史任务区域 -->
|
||||
<VBox spacing="5.0">
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0">
|
||||
<items>
|
||||
<Button fx:id="clearHistoryButton" alignment="CENTER_RIGHT" text="清空历史" />
|
||||
</items>
|
||||
</ToolBar>
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0">
|
||||
<items>
|
||||
<Button fx:id="clearHistoryButton" alignment="CENTER_RIGHT" text="清空历史"/>
|
||||
</items>
|
||||
</ToolBar>
|
||||
<TableView fx:id="historyTasksTable" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="historyTaskIdColumn" prefWidth="150.0" text="任务ID" />
|
||||
<TableColumn fx:id="historyTaskTitleColumn" prefWidth="200.0" text="任务标题" />
|
||||
<TableColumn fx:id="historyTaskStatusColumn" prefWidth="100.0" text="状态" />
|
||||
<TableColumn fx:id="historyTaskStartTimeColumn" prefWidth="150.0" text="开始时间" />
|
||||
<TableColumn fx:id="historyTaskExecutionTimeColumn" prefWidth="100.0" text="执行耗时" />
|
||||
<TableColumn fx:id="historyTaskIdColumn" prefWidth="150.0" text="任务ID"/>
|
||||
<TableColumn fx:id="historyTaskTitleColumn" prefWidth="200.0" text="任务标题"/>
|
||||
<TableColumn fx:id="historyTaskStatusColumn" prefWidth="100.0" text="状态"/>
|
||||
<TableColumn fx:id="historyTaskStartTimeColumn" prefWidth="150.0" text="开始时间"/>
|
||||
<TableColumn fx:id="historyTaskExecutionTimeColumn" prefWidth="100.0" text="执行耗时"/>
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</VBox>
|
||||
</content>
|
||||
</content>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
<Tab closable="false" text="Executor">
|
||||
<content>
|
||||
<VBox spacing="5.0">
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0">
|
||||
<items>
|
||||
<Button fx:id="refreshExecutorInfoButton" text="刷新"/>
|
||||
</items>
|
||||
</ToolBar>
|
||||
<TableView fx:id="executorInfoTable" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="executorFieldColumn" prefWidth="150.0" text="字段"/>
|
||||
<TableColumn fx:id="executorValueColumn" prefWidth="200.0" text="值"/>
|
||||
<TableColumn fx:id="executorDescriptionColumn" prefWidth="300.0" text="描述"/>
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
</VBox>
|
||||
</content>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
</VBox>
|
||||
|
||||
Reference in New Issue
Block a user