拆分模块
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package com.ecep.contract.cloud.rk;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.URI;
|
||||
|
||||
public class BlackListUpdateContext {
|
||||
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private ObjectMapper objectMapper;
|
||||
private Proxy.Type proxyType;
|
||||
@Getter
|
||||
private Proxy socksProxy;
|
||||
@Setter
|
||||
@Getter
|
||||
private String url;
|
||||
@Getter
|
||||
private long elapse = 1440;
|
||||
|
||||
|
||||
public void setProxy(String proxy) {
|
||||
if (proxy != null) {
|
||||
URI proxyUri = URI.create(proxy);
|
||||
proxyType = Proxy.Type.valueOf(proxyUri.getScheme().toUpperCase());
|
||||
socksProxy = new Proxy(
|
||||
proxyType,
|
||||
new InetSocketAddress(proxyUri.getHost(), proxyUri.getPort())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void setElapse(String value) {
|
||||
elapse = Long.parseLong(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.ecep.contract.cloud.rk;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.ecep.contract.ds.MyRepository;
|
||||
import com.ecep.contract.model.CloudRk;
|
||||
import com.ecep.contract.model.Company;
|
||||
|
||||
@Repository
|
||||
public interface CloudRkRepository extends MyRepository<CloudRk, Integer> {
|
||||
|
||||
Stream<CloudRk> findByCloudLatestAfter(Instant timestamp);
|
||||
|
||||
Stream<CloudRk> findByCloudEntUpdateAfter(Instant timestamp);
|
||||
|
||||
/**
|
||||
* 按公司查找 Cloud RK
|
||||
*
|
||||
* @param company 公司对象
|
||||
* @return Cloud RK
|
||||
*/
|
||||
Optional<CloudRk> findByCompany(Company company);
|
||||
|
||||
/**
|
||||
* 按公司查找 Cloud RK
|
||||
*
|
||||
* @param companyId 公司对象编号
|
||||
* @return Cloud RK
|
||||
*/
|
||||
Optional<CloudRk> findByCompanyId(int companyId);
|
||||
|
||||
List<CloudRk> findAllByCompanyId(int companyId);
|
||||
|
||||
long countByLatestUpdateBefore(Instant instant);
|
||||
|
||||
long countByAutoUpdateIsTrueAndLatestUpdateBefore(Instant instant);
|
||||
|
||||
List<CloudRk> findTop100ByLatestUpdateBeforeOrderByLatestUpdateDesc(Instant instant);
|
||||
|
||||
List<CloudRk> findTop100ByAutoUpdateIsTrueAndLatestUpdateBeforeOrderByLatestUpdateDesc(Instant instant);
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
int deleteAllByCompany(Company company);
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
package com.ecep.contract.cloud.rk;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.ecep.contract.util.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheConfig;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.BlackReasonType;
|
||||
import com.ecep.contract.IEntityService;
|
||||
import com.ecep.contract.cloud.CloudInfo;
|
||||
import com.ecep.contract.ds.company.repository.CompanyBlackReasonRepository;
|
||||
import com.ecep.contract.ds.company.repository.CompanyOldNameRepository;
|
||||
import com.ecep.contract.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.ds.other.service.SysConfService;
|
||||
import com.ecep.contract.model.CloudRk;
|
||||
import com.ecep.contract.model.Company;
|
||||
import com.ecep.contract.model.CompanyBlackReason;
|
||||
import com.ecep.contract.util.HttpJsonUtils;
|
||||
import com.ecep.contract.util.MyStringUtils;
|
||||
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import jakarta.persistence.criteria.Path;
|
||||
import lombok.Data;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "cloud-rk")
|
||||
public class CloudRkService implements IEntityService<CloudRk> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CloudRkService.class);
|
||||
|
||||
public final static String ENTERPRISE_CREDIT_REPORT = "企业征信报告";
|
||||
|
||||
public static final String KEY_PROXY = "cloud.rk.proxy";
|
||||
public static final String KEY_SYNC_ELAPSE = "cloud.rk.sync.elapse";
|
||||
public static final long DEFAULT_SYNC_ELAPSE = 36000L;
|
||||
public static final String KEY_VENDOR_REPORT_URL = "cloud.rk.vendor.report.url";
|
||||
public static final String KEY_CUSTOMER_REPORT_URL = "cloud.rk.customer.report.url";
|
||||
public static final String KEY_ENT_SCORE_URL = "cloud.rk.ent_score.url";
|
||||
public static final String KEY_ENT_REPORT_URL = "cloud.rk.ent_report.url";
|
||||
public static final String KEY_ENT_FUZZY_URL = "cloud.rk.ent_fuzzy.url";
|
||||
public static final String KEY_BLACK_LIST_URL = "cloud.rk.black_list.url";
|
||||
public static final String KEY_BLACK_LIST_ELAPSE = "cloud.rk.black_list.elapse";
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* 同步超时, 单位 毫秒
|
||||
*
|
||||
* @return 毫秒
|
||||
*/
|
||||
public long getSyncElapse() {
|
||||
String string = confService.getString(KEY_SYNC_ELAPSE);
|
||||
if (!StringUtils.hasText(string)) {
|
||||
return DEFAULT_SYNC_ELAPSE;
|
||||
}
|
||||
return MyStringUtils.toLong(string, DEFAULT_SYNC_ELAPSE);
|
||||
}
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public static class EntInfo {
|
||||
@JsonAlias("entid")
|
||||
private String id;
|
||||
@JsonAlias("entname")
|
||||
private String name;
|
||||
private boolean nowName;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private SysConfService confService;
|
||||
@Autowired
|
||||
private CloudRkRepository cloudRKRepository;
|
||||
@Lazy
|
||||
@Autowired
|
||||
private CompanyService companyService;
|
||||
@Autowired
|
||||
private CompanyOldNameRepository companyOldNameRepository;
|
||||
@Autowired
|
||||
private CompanyBlackReasonRepository companyBlackReasonRepository;
|
||||
|
||||
@Cacheable(key = "#p0")
|
||||
public CloudRk findById(Integer id) {
|
||||
return cloudRKRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
public Page<CloudRk> findAll(Specification<CloudRk> spec, Pageable pageable) {
|
||||
return cloudRKRepository.findAll(spec, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specification<CloudRk> getSpecification(String searchText) {
|
||||
if (!StringUtils.hasText(searchText)) {
|
||||
return null;
|
||||
}
|
||||
return (root, query, builder) -> {
|
||||
Path<Object> company = root.get("company");
|
||||
return builder.or(
|
||||
builder.like(company.get("name"), "%" + searchText + "%"),
|
||||
builder.like(company.get("shortName"), "%" + searchText + "%"),
|
||||
builder.like(root.get("cloudId"), "%" + searchText + "%"),
|
||||
builder.like(root.get("description"), "%" + searchText + "%"));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新黑名单列表
|
||||
*/
|
||||
public void updateBlackList(
|
||||
Company company, CloudRk cloudRk, BlackListUpdateContext context) throws IOException {
|
||||
List<String> companyNames = new ArrayList<>();
|
||||
companyNames.add(company.getName());
|
||||
// fixed 平台API使用企业名称,可能记录的是曾用名
|
||||
companyOldNameRepository.findAllByCompanyId(company.getId()).forEach(oldName -> {
|
||||
// 歧义的曾用名不采用
|
||||
if (oldName.getAmbiguity()) {
|
||||
return;
|
||||
}
|
||||
companyNames.add(oldName.getName());
|
||||
});
|
||||
|
||||
List<CompanyBlackReason> reasonList = new ArrayList<>();
|
||||
List<CompanyBlackReason> dbReasons = companyBlackReasonRepository.findAllByCompany(company);
|
||||
|
||||
companyNames.forEach(name -> {
|
||||
String url = context.getUrl() + URLEncoder.encode(name, StandardCharsets.UTF_8);
|
||||
try {
|
||||
HttpJsonUtils.get(url, json -> {
|
||||
if (!json.has("success") || !json.get("success").asBoolean()) {
|
||||
System.out.println("json = " + json.toPrettyString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (json.has("data")) {
|
||||
JsonNode data = json.get("data");
|
||||
try {
|
||||
if (data.has("blackReason")) {
|
||||
for (JsonNode reason : data.get("blackReason")) {
|
||||
toCompanyBlackReasonList(company, BlackReasonType.BLACK, reason, dbReasons,
|
||||
reasonList, context.getObjectMapper());
|
||||
}
|
||||
}
|
||||
if (data.has("greyReason")) {
|
||||
for (JsonNode reason : data.get("greyReason")) {
|
||||
toCompanyBlackReasonList(company, BlackReasonType.GRAY, reason, dbReasons,
|
||||
reasonList, context.getObjectMapper());
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.error("{} {},json = {}", company.getName(), ex.getMessage(), json, ex);
|
||||
throw new RuntimeException(json.toString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存JSON数据到公司目录
|
||||
String companyPath = company.getPath();
|
||||
if (StringUtils.hasText(companyPath)) {
|
||||
File dir = new File(companyPath);
|
||||
if (dir.exists()) {
|
||||
File file = new File(dir, FileUtils.FILE_BLACK_LIST_JSON);
|
||||
try {
|
||||
objectMapper.writeValue(file, json);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Unable Save BlackList to {}, company:{}", file, company.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, context.getObjectMapper(), context.getSocksProxy());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
if (!reasonList.isEmpty()) {
|
||||
companyBlackReasonRepository.saveAll(reasonList);
|
||||
}
|
||||
cloudRk.setCloudBlackListUpdated(Instant.now());
|
||||
}
|
||||
|
||||
private void toCompanyBlackReasonList(
|
||||
Company company, BlackReasonType type,
|
||||
JsonNode reason, List<CompanyBlackReason> dbReasons,
|
||||
List<CompanyBlackReason> reasonList, ObjectMapper objectMapper) throws JsonMappingException {
|
||||
ObjectNode object = (ObjectNode) reason;
|
||||
String key = "rk-" + object.remove("id").asText();
|
||||
CompanyBlackReason cbr = dbReasons.stream().filter(r -> r.getKey().equals(key)).findAny()
|
||||
.orElseGet(CompanyBlackReason::new);
|
||||
objectMapper.updateValue(cbr, reason);
|
||||
cbr.setCompany(company);
|
||||
cbr.setType(type);
|
||||
cbr.setKey(key);
|
||||
reasonList.add(cbr);
|
||||
}
|
||||
|
||||
public CompletableFuture<BlackListUpdateContext> createBlackListUpdateContext() {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
BlackListUpdateContext context = new BlackListUpdateContext();
|
||||
context.setObjectMapper(objectMapper);
|
||||
context.setProxy(confService.getString(KEY_PROXY));
|
||||
context.setUrl(confService.getString(KEY_BLACK_LIST_URL));
|
||||
// context.setElapse(confService.getLong(KEY_BLACK_LIST_ELAPSE));
|
||||
return context;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true
|
||||
*/
|
||||
public boolean checkBlackListUpdateElapse(
|
||||
Company company, CloudRk cloudRk, BlackListUpdateContext context) {
|
||||
Instant start = cloudRk.getCloudBlackListUpdated();
|
||||
if (start == null) {
|
||||
return true;
|
||||
}
|
||||
Instant elapse = start.plusSeconds(context.getElapse());
|
||||
return elapse.isBefore(Instant.now());
|
||||
}
|
||||
|
||||
public CloudRk getOrCreateCloudRk(CloudInfo info) {
|
||||
Optional<CloudRk> optional = cloudRKRepository.findById(info.getId());
|
||||
return optional.orElseGet(() -> getOrCreateCloudRk(info.getCompany()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回或者创建 Cloud RK
|
||||
*
|
||||
* @param company 公司对象
|
||||
* @return Cloud RK
|
||||
*/
|
||||
public CloudRk getOrCreateCloudRk(Company company) {
|
||||
Integer companyId = company.getId();
|
||||
List<CloudRk> list = cloudRKRepository.findAllByCompanyId(companyId);
|
||||
if (list.isEmpty()) {
|
||||
CloudRk rk = new CloudRk();
|
||||
rk.setCompany(company);
|
||||
rk.setCustomerGrade("");
|
||||
rk.setCustomerScore(-1);
|
||||
rk.setVendorGrade("");
|
||||
rk.setVendorScore(-1);
|
||||
rk.setRank("");
|
||||
return cloudRKRepository.save(rk);
|
||||
}
|
||||
if (list.size() == 1) {
|
||||
return list.getFirst();
|
||||
}
|
||||
|
||||
// 查询有 CloudId 的记录
|
||||
List<CloudRk> hasCouldIdList = list.stream().filter(v -> StringUtils.hasText(v.getCloudId()))
|
||||
.collect(Collectors.toList());
|
||||
// 没有匹配到一条时
|
||||
if (hasCouldIdList.isEmpty()) {
|
||||
// 保留第一条,其他删除
|
||||
CloudRk rk = list.removeFirst();
|
||||
cloudRKRepository.deleteAll(list);
|
||||
return rk;
|
||||
}
|
||||
|
||||
// 只有匹配到一条有 CloudId 的记录
|
||||
if (hasCouldIdList.size() == 1) {
|
||||
// 保留匹配的记录,其他删除
|
||||
CloudRk rk = hasCouldIdList.removeFirst();
|
||||
list.remove(rk);
|
||||
cloudRKRepository.deleteAll(list);
|
||||
return rk;
|
||||
}
|
||||
|
||||
// 查询有 CloudLatest 的记录
|
||||
List<CloudRk> hasLatestList = hasCouldIdList.stream().filter(v -> v.getCloudLatest() != null)
|
||||
.collect(Collectors.toList());
|
||||
// 没有匹配到一条时
|
||||
if (hasLatestList.isEmpty()) {
|
||||
// 保留第一条,其他删除
|
||||
CloudRk rk = hasCouldIdList.removeFirst();
|
||||
list.remove(rk);
|
||||
cloudRKRepository.deleteAll(list);
|
||||
return rk;
|
||||
}
|
||||
|
||||
// 只有匹配到一条有 CloudId 的记录
|
||||
if (hasLatestList.size() == 1) {
|
||||
// 保留匹配的记录,其他删除
|
||||
CloudRk rk = hasLatestList.removeFirst();
|
||||
list.remove(rk);
|
||||
cloudRKRepository.deleteAll(list);
|
||||
return rk;
|
||||
}
|
||||
|
||||
return hasLatestList.getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 Cloud Rk
|
||||
*
|
||||
* @param cloudRk Cloud Rk 对象
|
||||
* @return 更新的 Cloud Rk
|
||||
*/
|
||||
@CacheEvict(key = "#p0.id")
|
||||
public CloudRk save(CloudRk cloudRk) {
|
||||
return cloudRKRepository.save(cloudRk);
|
||||
}
|
||||
|
||||
@CacheEvict(key = "#p0.id")
|
||||
@Override
|
||||
public void delete(CloudRk entity) {
|
||||
cloudRKRepository.delete(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回 在 {@link #getSyncElapse()} 毫秒前,更新的
|
||||
*
|
||||
* @return 记录条数
|
||||
*/
|
||||
public long countNeedUpdate() {
|
||||
Instant now = Instant.now();
|
||||
long elapse = getSyncElapse();
|
||||
Instant instant = now.minusSeconds(elapse);
|
||||
return cloudRKRepository.countByAutoUpdateIsTrueAndLatestUpdateBefore(instant);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回距离上次更新超过 SysConfig:cloud.rk.black_list.elapse 秒的公司
|
||||
*/
|
||||
// @Transactional
|
||||
public List<CloudRk> findNeedUpdate() {
|
||||
Instant now = Instant.now();
|
||||
long elapse = getSyncElapse();
|
||||
Instant instant = now.minusSeconds(elapse);
|
||||
return cloudRKRepository.findTop100ByAutoUpdateIsTrueAndLatestUpdateBeforeOrderByLatestUpdateDesc(instant);
|
||||
}
|
||||
|
||||
@CacheEvict
|
||||
public void deleteByCompany(Company company) {
|
||||
int deleted = cloudRKRepository.deleteAllByCompany(company);
|
||||
if (deleted > 0) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Delete {} records by company:#{}", deleted, company.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 这个可以无法更新缓存
|
||||
@Caching(evict = {
|
||||
@CacheEvict(key = "#p0.id"),
|
||||
@CacheEvict(key = "#p1.id"),
|
||||
})
|
||||
public void resetTo(Company from, Company to) {
|
||||
List<CloudRk> list = cloudRKRepository.findAllByCompanyId(from.getId());
|
||||
for (CloudRk item : list) {
|
||||
item.setCompany(to);
|
||||
}
|
||||
cloudRKRepository.saveAll(list);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.ecep.contract.cloud.rk;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.cloud.rk.ctx.CloudRkCtx;
|
||||
import com.ecep.contract.constant.CloudServiceConstant;
|
||||
import com.ecep.contract.ds.contract.service.ContractService;
|
||||
import com.ecep.contract.model.CloudRk;
|
||||
import com.ecep.contract.model.Company;
|
||||
import com.ecep.contract.ui.Tasker;
|
||||
|
||||
/**
|
||||
* 集团相关方平台同步任务
|
||||
*/
|
||||
public class CloudRkSyncTask extends Tasker<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CloudRkSyncTask.class);
|
||||
|
||||
private ContractService contractService;
|
||||
|
||||
@Override
|
||||
protected Object execute(MessageHolder holder) throws Exception {
|
||||
updateTitle("集团相关方平台");
|
||||
|
||||
CloudRkCtx cloudRkCtx = null;
|
||||
CloudRkService service = null;
|
||||
try {
|
||||
cloudRkCtx = new CloudRkCtx();
|
||||
service = SpringApp.getBean(CloudRkService.class);
|
||||
cloudRkCtx.setCloudRkService(service);
|
||||
} catch (BeansException e) {
|
||||
holder.error("没有找到 " + CloudServiceConstant.RK_NAME + " 服务");
|
||||
return null;
|
||||
}
|
||||
|
||||
long total = service.countNeedUpdate();
|
||||
if (total == 0) {
|
||||
holder.info("没有需要更新");
|
||||
return null;
|
||||
}
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
holder.info("统计需要更新的 " + total + " 条");
|
||||
|
||||
try {
|
||||
// 每次获取100条记录
|
||||
while (!isCancelled()) {
|
||||
List<CloudRk> needUpdate = service.findNeedUpdate();
|
||||
if (needUpdate.isEmpty()) {
|
||||
holder.info("处理完成");
|
||||
break;
|
||||
}
|
||||
for (CloudRk cloudRk : needUpdate) {
|
||||
if (isCancelled()) {
|
||||
break;
|
||||
}
|
||||
MessageHolder subHolder = holder.sub(counter.get() + " / " + total + ">");
|
||||
// fixed lazy
|
||||
Company company = cloudRk.getCompany();
|
||||
if (company == null) {
|
||||
subHolder.error("数据不完整,没有关联公司");
|
||||
break;
|
||||
}
|
||||
if (!Hibernate.isInitialized(company)) {
|
||||
company = getCompanyService().findById(company.getId());
|
||||
cloudRk.setCompany(company);
|
||||
}
|
||||
if (cloudRk.isAutoUpdate()) {
|
||||
LocalDate date = LocalDate.now().minusYears(3);
|
||||
long count = getContractService().findAllByCompany(company).stream()
|
||||
.filter(c -> c.getSetupDate() != null)
|
||||
.filter(c -> c.getSetupDate().isAfter(date))
|
||||
.count();
|
||||
if (count == 0) {
|
||||
holder.info("公司:" + company.getName() + " 没有3年以上的合同, 取消自动更新");
|
||||
cloudRk.setAutoUpdate(false);
|
||||
}
|
||||
}
|
||||
try {
|
||||
cloudRk.setDescription("");
|
||||
if (cloudRkCtx.syncCompany(company, cloudRk, subHolder)) {
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
cloudRk.setLatestUpdate(Instant.now());
|
||||
service.save(cloudRk);
|
||||
}
|
||||
// updateProgress(counter.incrementAndGet(), total);
|
||||
}
|
||||
}
|
||||
|
||||
if (isCancelled()) {
|
||||
updateMessage("Cancelled");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("运行至 {}/{} 时,发生错误中断", counter.get(), total, e);
|
||||
}
|
||||
// updateProgress(1, 1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> delay(int second, Executor executor) {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
long until = System.currentTimeMillis() + second * 1000L;
|
||||
String title = "";
|
||||
AtomicReference<Runnable> reference = new AtomicReference<>();
|
||||
Runnable runnable = () -> {
|
||||
long let = until - System.currentTimeMillis();
|
||||
if (let < 0) {
|
||||
System.out.println("complete @" + Thread.currentThread().getName());
|
||||
future.complete(null);
|
||||
} else {
|
||||
// 再次调度
|
||||
executor.execute(reference.get());
|
||||
updateTitle(title + " 延时 " + ((int) let / 1000) + "秒");
|
||||
}
|
||||
};
|
||||
reference.set(runnable);
|
||||
// 第一次调度
|
||||
executor.execute(runnable);
|
||||
return future;
|
||||
}
|
||||
|
||||
ContractService getContractService() {
|
||||
if (contractService == null) {
|
||||
contractService = getBean(ContractService.class);
|
||||
}
|
||||
return contractService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
package com.ecep.contract.cloud.rk;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.ecep.contract.util.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.ds.company.repository.CompanyContactRepository;
|
||||
import com.ecep.contract.ds.company.service.CompanyOldNameService;
|
||||
import com.ecep.contract.model.CloudRk;
|
||||
import com.ecep.contract.model.Company;
|
||||
import com.ecep.contract.model.CompanyContact;
|
||||
import com.ecep.contract.model.CompanyOldName;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EntReportParser {
|
||||
private static final Logger logger = LoggerFactory.getLogger(EntReportParser.class);
|
||||
private ObjectMapper objectMapper;
|
||||
private Company company;
|
||||
private CloudRk cloudRk;
|
||||
private boolean modified = false;
|
||||
|
||||
|
||||
public void parse(JsonNode json) {
|
||||
if (!json.has("B1001")) {
|
||||
// 没有数据
|
||||
throw new RuntimeException("B1001 can't be null, json:" + json);
|
||||
}
|
||||
JsonNode b1001 = json.get("B1001");
|
||||
if (!b1001.has("count") || b1001.get("count").asInt() < 1 || !b1001.has("data")) {
|
||||
// 没有数据
|
||||
return;
|
||||
}
|
||||
JsonNode data = b1001.get("data");
|
||||
|
||||
updateCompanyProperty("entType", data.get("enttype"));
|
||||
updateCompanyProperty("entStatus", data.get("entstatus"));
|
||||
updateCompanyProperty("setupDate", data.get("esdate"));
|
||||
|
||||
updateCompanyUniscid(data);
|
||||
updateCompanyNameHistory(data);
|
||||
|
||||
updateCompanyProperty("regAddr", data.get("dom"));
|
||||
updateCompanyProperty("registeredCapital", data.get("regcap"));
|
||||
updateCompanyProperty("registeredCapitalCurrency", data.get("regcapcur"));
|
||||
updateCompanyProperty("legalRepresentative", data.get("frname"));
|
||||
updateCompanyProperty("district", data.get("regorgprovince"));
|
||||
updateCompanyProperty("telephone", data.get("tel"));
|
||||
updateCompanyProperty("address", data.get("oploc"));
|
||||
updateCompanyProperty("operationPeriodBegin", data.get("opfrom"));
|
||||
updateCompanyProperty("operationPeriodEnd", data.get("opto"), "-");
|
||||
updateCompanyProperty("industry", data.get("nicfulltitle"));
|
||||
|
||||
//
|
||||
updateCloudRkEntUpdateDate(data);
|
||||
|
||||
// 更新法人联系人
|
||||
updateLegalRepresentativeContact(data);
|
||||
|
||||
// 保存JSON数据到公司目录
|
||||
saveJsonToFile(json);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void updateLegalRepresentativeContact(JsonNode data) {
|
||||
String legalRepresentative = company.getLegalRepresentative();
|
||||
if (!StringUtils.hasText(legalRepresentative)) {
|
||||
return;
|
||||
}
|
||||
CompanyContact contact = null;
|
||||
boolean modified = false;
|
||||
CompanyContactRepository contactRepository = SpringApp.getBean(CompanyContactRepository.class);
|
||||
List<CompanyContact> contactList = contactRepository.findAllByCompanyAndName(company, legalRepresentative);
|
||||
if (contactList == null) {
|
||||
// db error
|
||||
return;
|
||||
}
|
||||
if (contactList.isEmpty()) {
|
||||
//没有,创建法人联系人
|
||||
contact = new CompanyContact();
|
||||
contact.setCompany(company);
|
||||
contact.setName(legalRepresentative);
|
||||
contact.setPosition("法定代表人");
|
||||
contact.setCreated(LocalDate.now());
|
||||
modified = true;
|
||||
} else {
|
||||
Optional<CompanyContact> any = contactList.stream().filter(c -> "法定代表人".equals(c.getPosition())).findAny();
|
||||
if (any.isEmpty()) {
|
||||
any = contactList.stream().findAny();
|
||||
}
|
||||
contact = any.get();
|
||||
// if (contact.getPostion() == null || !contact.setPostion().contains("法定代表人")) {
|
||||
// contact.setMemo("法定代表人");
|
||||
// modified = true;
|
||||
// }
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(contact.getEmail())) {
|
||||
String text = data.get("email").asText();
|
||||
contact.setEmail(text);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(contact.getAddress())) {
|
||||
String text = company.getAddress();
|
||||
contact.setAddress(text);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(contact.getPhone())) {
|
||||
String text = company.getTelephone();
|
||||
contact.setPhone(text);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(contact.getPosition())) {
|
||||
contact.setPosition("法定代表人");
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
contactRepository.save(contact);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateCompanyNameHistory(JsonNode data) {
|
||||
JsonNode node = data.get("nameHistory");
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
// 历史曾用名
|
||||
String nameHistory = node.asText();
|
||||
if (!StringUtils.hasText(nameHistory)) {
|
||||
return;
|
||||
}
|
||||
List<String> historyNames = new ArrayList<>();
|
||||
for (String str : nameHistory.split(",")) {
|
||||
String trimmed = str.trim();
|
||||
if (StringUtils.hasText(trimmed)) {
|
||||
historyNames.add(trimmed);
|
||||
}
|
||||
}
|
||||
CompanyOldNameService service = SpringApp.getBean(CompanyOldNameService.class);
|
||||
List<CompanyOldName> oldNames = service.findAllByCompany(company);
|
||||
for (CompanyOldName oldName : oldNames) {
|
||||
historyNames.remove(oldName.getName());
|
||||
}
|
||||
for (String historyName : historyNames) {
|
||||
CompanyOldName oldName = new CompanyOldName();
|
||||
oldName.setName(historyName);
|
||||
oldName.setCompanyId(company.getId());
|
||||
oldName.setMemo("从相关方平台导入");
|
||||
oldName.setAmbiguity(false);
|
||||
service.save(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCompanyUniscid(JsonNode data) {
|
||||
JsonNode node = data.get("uniscid");
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String uid = node.asText();
|
||||
if (StringUtils.hasText(uid)) {
|
||||
if (!uid.equals(company.getUniscid())) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("更新 {} 的 UNISCID {} -> {}", company.getName(), company.getUniscid(), uid);
|
||||
}
|
||||
company.setUniscid(uid);
|
||||
modified = true;
|
||||
}
|
||||
} else {
|
||||
//fixed 当平台返回的 社会统一信用代码为空时,如果原来已经有的,则不做更新
|
||||
if (StringUtils.hasText(company.getUniscid())) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("来自平台的 UNISCID 为空,但本地{}已经记录{},不做更改", company.getName(), company.getUniscid());
|
||||
}
|
||||
} else {
|
||||
company.setUniscid("");
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 平台的数据更新时间戳
|
||||
*/
|
||||
private void updateCloudRkEntUpdateDate(JsonNode data) {
|
||||
JsonNode node = data.get("updated");
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
LocalDateTime updated = objectMapper.convertValue(node, LocalDateTime.class);
|
||||
cloudRk.setCloudEntUpdate(updated.toInstant(ZoneOffset.ofHours(8)));
|
||||
}
|
||||
|
||||
private void updateCompanyProperty(String field, JsonNode node, String... excludeValues) {
|
||||
if (node == null || node.isNull()) {
|
||||
return;
|
||||
}
|
||||
String text = node.asText();
|
||||
for (String excludeValue : excludeValues) {
|
||||
if (Objects.equals(text, excludeValue)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
updateCompanyProperty(field, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新属性通用方法, 数据的类型转换由 objectMapper 提供
|
||||
*
|
||||
* @param field 类属性名称
|
||||
* @param node 数据来源 json node
|
||||
*/
|
||||
private void updateCompanyProperty(String field, JsonNode node) {
|
||||
if (node == null || node.isNull()) {
|
||||
return;
|
||||
}
|
||||
PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(Company.class, field);
|
||||
if (descriptor == null) {
|
||||
logger.error("Company 的字段 {} 不存在,请确认.", field);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Object oldValue = descriptor.getReadMethod().invoke(company);
|
||||
Object newValue = objectMapper.convertValue(node, descriptor.getReadMethod().getReturnType());
|
||||
if (!Objects.equals(oldValue, newValue)) {
|
||||
descriptor.getWriteMethod().invoke(company, newValue);
|
||||
modified = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void saveJsonToFile(JsonNode json) {
|
||||
String companyPath = company.getPath();
|
||||
if (StringUtils.hasText(companyPath)) {
|
||||
File dir = new File(companyPath);
|
||||
if (dir.exists()) {
|
||||
File file = new File(dir, FileUtils.FILE_B1001_JSON);
|
||||
try {
|
||||
objectMapper.writeValue(file, json);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Unable Save BlackList to {}, company:{}", file, company.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,830 @@
|
||||
package com.ecep.contract.cloud.rk.ctx;
|
||||
|
||||
import static com.ecep.contract.SpringApp.getBean;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketException;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import com.ecep.contract.util.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.ecep.contract.BlackReasonType;
|
||||
import com.ecep.contract.MessageHolder;
|
||||
import com.ecep.contract.SpringApp;
|
||||
import com.ecep.contract.cloud.AbstractCtx;
|
||||
import com.ecep.contract.cloud.rk.CloudRkService;
|
||||
import com.ecep.contract.ds.company.service.CompanyBlackReasonService;
|
||||
import com.ecep.contract.ds.company.service.CompanyContactService;
|
||||
import com.ecep.contract.ds.company.service.CompanyOldNameService;
|
||||
import com.ecep.contract.ds.company.service.CompanyService;
|
||||
import com.ecep.contract.model.CloudRk;
|
||||
import com.ecep.contract.model.Company;
|
||||
import com.ecep.contract.model.CompanyBlackReason;
|
||||
import com.ecep.contract.model.CompanyContact;
|
||||
import com.ecep.contract.model.CompanyOldName;
|
||||
import com.ecep.contract.util.HttpJsonUtils;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
public class CloudRkCtx extends AbstractCtx {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CloudRkCtx.class);
|
||||
@Setter
|
||||
private CloudRkService cloudRkService;
|
||||
@Setter
|
||||
private CompanyService companyService;
|
||||
@Setter
|
||||
private CompanyBlackReasonService companyBlackReasonService;
|
||||
@Setter
|
||||
private ObjectMapper objectMapper;
|
||||
private Proxy socksProxy;
|
||||
|
||||
public CloudRkService getCloudRkService() {
|
||||
if (cloudRkService == null) {
|
||||
cloudRkService = getBean(CloudRkService.class);
|
||||
}
|
||||
return cloudRkService;
|
||||
}
|
||||
|
||||
public CompanyService getCompanyService() {
|
||||
if (companyService == null) {
|
||||
companyService = getBean(CompanyService.class);
|
||||
}
|
||||
return companyService;
|
||||
}
|
||||
|
||||
CompanyBlackReasonService getCompanyBlackReasonService() {
|
||||
if (companyBlackReasonService == null) {
|
||||
companyBlackReasonService = getBean(CompanyBlackReasonService.class);
|
||||
}
|
||||
return companyBlackReasonService;
|
||||
}
|
||||
|
||||
ObjectMapper getObjectMapper() {
|
||||
if (objectMapper == null) {
|
||||
objectMapper = getBean(ObjectMapper.class);
|
||||
}
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
Proxy getSocksProxy() {
|
||||
if (socksProxy == null) {
|
||||
String proxy = getConfService().getString(CloudRkService.KEY_PROXY);
|
||||
URI proxyUri = URI.create(proxy);
|
||||
Proxy.Type proxyType = Proxy.Type.valueOf(proxyUri.getScheme().toUpperCase());
|
||||
socksProxy = new Proxy(
|
||||
proxyType,
|
||||
new InetSocketAddress(proxyUri.getHost(), proxyUri.getPort())
|
||||
);
|
||||
}
|
||||
return socksProxy;
|
||||
}
|
||||
|
||||
public void post(String url, Consumer<Map<String, Object>> data, Consumer<JsonNode> consumer) throws IOException {
|
||||
HttpJsonUtils.post(url, data, consumer, getObjectMapper(), getSocksProxy());
|
||||
}
|
||||
|
||||
|
||||
public boolean syncCompany(Company company, CloudRk cloudRk, MessageHolder holder) {
|
||||
if (!StringUtils.hasText(cloudRk.getCloudId())) {
|
||||
holder.warn("未定义平台编号, 尝试从平台上自动获取");
|
||||
// 当未定义平台编号时,尝试自动获取
|
||||
if (!queryCloudIdAndSelectOne(company, cloudRk, holder)) {
|
||||
// 自动获取到平台编号失败,立即返回
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(cloudRk.getCloudId()) || cloudRk.getCloudId().equals("-")) {
|
||||
// 平台编号为 空 或 - 时,跳过同步
|
||||
holder.debug("平台编号为 空 或 - 时,跳过同步");
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean updated = false;
|
||||
try {
|
||||
if (updateEnterpriseInfo(company, cloudRk, holder)) {
|
||||
company = getCompanyService().save(company);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updateBlackList(company, cloudRk, holder)) {
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updateEnterpriseCredit(company, cloudRk, holder)) {
|
||||
// cloudRk modified
|
||||
updated = true;
|
||||
}
|
||||
if (updateCustomerScore(company, cloudRk, holder)) {
|
||||
// cloudRk modified
|
||||
updated = true;
|
||||
}
|
||||
if (updateVendorScore(company, cloudRk, holder)) {
|
||||
// cloudRk modified
|
||||
updated = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 异常
|
||||
logger.error("使用评分接口更新企业资信评价等级时发生错误", e);
|
||||
cloudRk.setDescription("评分接口错误:" + e.getMessage());
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新黑名单列表
|
||||
*/
|
||||
public boolean updateBlackList(
|
||||
Company company, CloudRk cloudRk, MessageHolder holder
|
||||
) throws IOException {
|
||||
Instant start = cloudRk.getCloudBlackListUpdated();
|
||||
if (start != null) {
|
||||
long elapse = getConfService().getLong(CloudRkService.KEY_BLACK_LIST_ELAPSE);
|
||||
if (elapse > 0) {
|
||||
Instant next = start.plusSeconds(elapse);
|
||||
if (next.isAfter(Instant.now())) {
|
||||
holder.debug("更新时间未到, 上次更新时间 = " + start);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String api = getConfService().getString(CloudRkService.KEY_BLACK_LIST_URL);
|
||||
List<String> companyNames = getCompanyService().getAllNames(company);
|
||||
|
||||
|
||||
List<CompanyBlackReason> reasonList = new ArrayList<>();
|
||||
List<CompanyBlackReason> dbReasons = getCompanyBlackReasonService().findAllByCompany(company);
|
||||
for (String name : companyNames) {
|
||||
String url = api + URLEncoder.encode(name, StandardCharsets.UTF_8);
|
||||
try {
|
||||
HttpJsonUtils.get(url, json -> {
|
||||
applyBlackReason(json, company, cloudRk, reasonList, dbReasons, holder);
|
||||
saveJsonToFile(company, json, "black-" + name + ".json", holder);
|
||||
}, getObjectMapper(), getSocksProxy());
|
||||
} catch (IOException e) {
|
||||
catchException(e, holder);
|
||||
}
|
||||
}
|
||||
|
||||
if (reasonList.isEmpty()) {
|
||||
cloudRk.setCloudBlackListUpdated(Instant.now());
|
||||
return false;
|
||||
|
||||
}
|
||||
for (CompanyBlackReason companyBlackReason : reasonList) {
|
||||
getCompanyBlackReasonService().save(companyBlackReason);
|
||||
}
|
||||
cloudRk.setCloudBlackListUpdated(Instant.now());
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean applyBlackReason(
|
||||
JsonNode json, Company company, CloudRk cloudRk,
|
||||
List<CompanyBlackReason> reasonList, List<CompanyBlackReason> dbReasons,
|
||||
MessageHolder holder
|
||||
) {
|
||||
if (isUnSuccess(json, holder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!json.has("data")) {
|
||||
holder.error("数据异常,返回的json中没有 data 字段");
|
||||
return false;
|
||||
}
|
||||
JsonNode data = json.get("data");
|
||||
|
||||
if (data.has("blackReason")) {
|
||||
for (JsonNode reason : data.get("blackReason")) {
|
||||
try {
|
||||
toCompanyBlackReasonList(company, BlackReasonType.BLACK, reason, dbReasons, reasonList);
|
||||
} catch (JsonMappingException e) {
|
||||
holder.error("blackReason " + e.getMessage() + ", " + reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.has("greyReason")) {
|
||||
for (JsonNode reason : data.get("greyReason")) {
|
||||
try {
|
||||
toCompanyBlackReasonList(company, BlackReasonType.GRAY, reason, dbReasons, reasonList);
|
||||
} catch (JsonMappingException e) {
|
||||
holder.error("greyReason " + e.getMessage() + ", " + reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void toCompanyBlackReasonList(
|
||||
Company company, BlackReasonType type,
|
||||
JsonNode reason, List<CompanyBlackReason> dbReasons,
|
||||
List<CompanyBlackReason> reasonList
|
||||
) throws JsonMappingException {
|
||||
ObjectNode object = (ObjectNode) reason;
|
||||
String key = "rk-" + object.remove("id").asText();
|
||||
CompanyBlackReason cbr = dbReasons.stream().filter(r -> r.getKey().equals(key)).findAny().orElseGet(CompanyBlackReason::new);
|
||||
getObjectMapper().updateValue(cbr, reason);
|
||||
cbr.setCompany(company);
|
||||
cbr.setType(type);
|
||||
cbr.setKey(key);
|
||||
reasonList.add(cbr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新评分
|
||||
*/
|
||||
public boolean updateEnterpriseCredit(
|
||||
Company company, CloudRk cloudRk, MessageHolder holder
|
||||
) throws IOException {
|
||||
String api = getConfService().getString(CloudRkService.KEY_ENT_SCORE_URL);
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
try {
|
||||
post(api, data -> {
|
||||
data.put("entname", company.getName());
|
||||
// data.put("entid", cloudInfo.getCloudId());
|
||||
data.put("get", true);
|
||||
}, json -> {
|
||||
modified.set(applyEnterpriseCredit(json, cloudRk, holder));
|
||||
saveJsonToFile(company, json, "credit.json", holder);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
catchException(e, holder);
|
||||
}
|
||||
return modified.get();
|
||||
}
|
||||
|
||||
private boolean applyEnterpriseCredit(JsonNode json, CloudRk cloudRk, MessageHolder holder) {
|
||||
if (isUnSuccess(json, holder)) {
|
||||
return false;
|
||||
}
|
||||
if (isUnHasField(json, "data", holder)) {
|
||||
return false;
|
||||
}
|
||||
JsonNode data = json.get("data");
|
||||
boolean modified = false;
|
||||
String level = "";
|
||||
String description = "";
|
||||
if (data.isNull()) {
|
||||
level = "-";
|
||||
} else {
|
||||
level = data.get("level").asText();
|
||||
description = data.get("levelDescription").asText();
|
||||
}
|
||||
|
||||
if (updateText(cloudRk::getRank, cloudRk::setRank, level, holder, "企业资信评价等级")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(cloudRk::getRankDescription, cloudRk::setRankDescription, description, holder, "企业资信评价等级说明")) {
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
private boolean isUnHasField(JsonNode json, String field, MessageHolder holder) {
|
||||
if (!json.has("data")) {
|
||||
holder.error("数据异常,返回的json中没有 data 字段");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isUnSuccess(JsonNode json, MessageHolder holder) {
|
||||
if (isUnHasField(json, "success", holder)) {
|
||||
return true;
|
||||
}
|
||||
if (!json.get("success").asBoolean()) {
|
||||
holder.error("数据异常,返回 success = false, " + json);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户信用
|
||||
*/
|
||||
public boolean updateCustomerScore(
|
||||
Company company, CloudRk cloudRk, MessageHolder holder
|
||||
) throws IOException {
|
||||
String url = getConfService().getString(CloudRkService.KEY_CUSTOMER_REPORT_URL);
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
try {
|
||||
post(url, data -> {
|
||||
// data.put("entName", company.getName());
|
||||
data.put("entId", cloudRk.getCloudId());
|
||||
data.put("get", true);
|
||||
}, json -> {
|
||||
modified.set(applyCustomerScore(json, company, cloudRk, holder));
|
||||
saveJsonToFile(company, json, "customer-score.json", holder);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
catchException(e, holder);
|
||||
}
|
||||
return modified.get();
|
||||
}
|
||||
|
||||
private boolean applyCustomerScore(JsonNode json, Company company, CloudRk cloudRk, MessageHolder holder) {
|
||||
if (isUnSuccess(json, holder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean modified = false;
|
||||
String grade = "";
|
||||
int score = 0;
|
||||
String description = "";
|
||||
if (isUnHasField(json, "data", holder)) {
|
||||
grade = "-";
|
||||
score = -1;
|
||||
} else {
|
||||
JsonNode data = json.get("data");
|
||||
if (data.isNull()) {
|
||||
grade = "无";
|
||||
score = -1;
|
||||
} else {
|
||||
grade = data.get("grade").asText();
|
||||
score = data.get("totalScore").asInt();
|
||||
description = data.get("description").asText();
|
||||
}
|
||||
}
|
||||
|
||||
if (updateText(cloudRk::getCustomerGrade, cloudRk::setCustomerGrade, grade, holder, "客户信用评级")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateNumber(cloudRk::getCustomerScore, cloudRk::setCustomerScore, score, holder, "客户信用总分")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(cloudRk::getCustomerDescription, cloudRk::setCustomerDescription, description, holder, "客户信用评级说明")) {
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
public boolean updateVendorScore(
|
||||
Company company, CloudRk cloudRk, MessageHolder holder
|
||||
) throws IOException {
|
||||
String url = getConfService().getString(CloudRkService.KEY_VENDOR_REPORT_URL);
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
try {
|
||||
post(url, data -> {
|
||||
// data.put("entName", company.getName());
|
||||
data.put("entId", cloudRk.getCloudId());
|
||||
data.put("get", true);
|
||||
}, json -> {
|
||||
modified.set(applyVendorScore(json, cloudRk, holder));
|
||||
saveJsonToFile(company, json, "vendor-score.json", holder);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
catchException(e, holder);
|
||||
}
|
||||
return modified.get();
|
||||
}
|
||||
|
||||
private boolean applyVendorScore(JsonNode json, CloudRk cloudRk, MessageHolder holder) {
|
||||
if (isUnSuccess(json, holder)) {
|
||||
return false;
|
||||
}
|
||||
boolean modified = false;
|
||||
String grade = "";
|
||||
int score = 0;
|
||||
String description = "";
|
||||
if (isUnHasField(json, "data", holder)) {
|
||||
grade = "-";
|
||||
score = -1;
|
||||
} else {
|
||||
JsonNode data = json.get("data");
|
||||
if (data.isNull()) {
|
||||
grade = "无";
|
||||
score = -1;
|
||||
} else {
|
||||
grade = data.get("scoreLevel").asText();
|
||||
score = data.get("score").asInt();
|
||||
description = data.get("scoreDes").asText();
|
||||
}
|
||||
}
|
||||
|
||||
if (updateText(cloudRk::getVendorGrade, cloudRk::setVendorGrade, grade, holder, "供应商信用得分")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateNumber(cloudRk::getVendorScore, cloudRk::setVendorScore, score, holder, "供应商信用总分")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(cloudRk::getVendorDescription, cloudRk::setVendorDescription, description, holder, "供应商信用评级说明")) {
|
||||
modified = true;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动获取到平台编号
|
||||
*
|
||||
* @param company 公司对象
|
||||
* @param cloudRk Cloud Rk
|
||||
* @return true 更新了 cloudId,否则false
|
||||
*/
|
||||
private boolean queryCloudIdAndSelectOne(
|
||||
Company company, CloudRk cloudRk, MessageHolder holder
|
||||
) {
|
||||
try {
|
||||
List<CloudRkService.EntInfo> entInfos = queryEnterpriseWithFuzzy(company, cloudRk, holder);
|
||||
// 返回的查询结果为空时
|
||||
if (entInfos.isEmpty()) {
|
||||
// 设置为 -, 不在重复查找
|
||||
cloudRk.setCloudId("-");
|
||||
holder.warn("在平台中没有匹配到 " + company.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 在返回的结果中,找到与公司名字一致的一个
|
||||
Optional<CloudRkService.EntInfo> optional = entInfos.stream().filter(n -> n.getName().equals(company.getName())).findAny();
|
||||
if (optional.isPresent()) {
|
||||
cloudRk.setCloudId(optional.get().getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
holder.error("在平台中查询到多个匹配 (" + entInfos.stream().map(CloudRkService.EntInfo::getName).collect(Collectors.joining(", ")) + "),请手工同步选择匹配");
|
||||
return false;
|
||||
|
||||
} catch (Exception e) {
|
||||
// 异常
|
||||
holder.error("查询接口获取企业平台编号发生错误 = " + e.getMessage());
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("使用模糊查询接口获取 {} 企业平台编号发生错误", company.getName(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 使用模糊查询接口查询相关企业信息
|
||||
*/
|
||||
public List<CloudRkService.EntInfo> queryEnterpriseWithFuzzy(
|
||||
Company company, CloudRk cloudRk, MessageHolder holder
|
||||
) throws IOException {
|
||||
String url = getConfService().getString(CloudRkService.KEY_ENT_FUZZY_URL);
|
||||
List<CloudRkService.EntInfo> results = new ArrayList<>();
|
||||
ObjectMapper objectMapper = getObjectMapper();
|
||||
try {
|
||||
HttpJsonUtils.post(url, data -> {
|
||||
data.put("theKey", company.getName());
|
||||
data.put("get", true);
|
||||
}, json -> {
|
||||
applyEnterpriseQuery(json, company, cloudRk, results, holder);
|
||||
saveJsonToFile(company, json, "fuzzy.json", holder);
|
||||
}, objectMapper, getSocksProxy());
|
||||
} catch (IOException ex) {
|
||||
catchException(ex, holder);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private boolean applyEnterpriseQuery(JsonNode json, Company company, CloudRk cloudRk, List<CloudRkService.EntInfo> results, MessageHolder holder) {
|
||||
if (!json.has("data")) {
|
||||
// 没有数据
|
||||
holder.error("数据异常,返回的json中没有 data 字段");
|
||||
return false;
|
||||
}
|
||||
JsonNode dataNode = json.get("data");
|
||||
if (!dataNode.isArray()) {
|
||||
holder.error("数据异常,返回的json中 data 字段不是数组");
|
||||
return false;
|
||||
}
|
||||
ObjectMapper objectMapper = getObjectMapper();
|
||||
|
||||
for (JsonNode node : dataNode) {
|
||||
try {
|
||||
CloudRkService.EntInfo entInfo = new CloudRkService.EntInfo();
|
||||
objectMapper.updateValue(entInfo, node);
|
||||
if (node.has("isNowName")) {
|
||||
String s = node.get("isNowName").asText();
|
||||
entInfo.setNowName(s.equals("1") || s.equals("true"));
|
||||
}
|
||||
results.add(entInfo);
|
||||
} catch (Exception e) {
|
||||
holder.error("更新企业信息失败:" + e.getMessage() + ", json=" + node.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新企业工商注册信息
|
||||
*/
|
||||
public boolean updateEnterpriseInfo(
|
||||
Company company, CloudRk cloudRk, MessageHolder holder
|
||||
) throws IOException {
|
||||
String api = getConfService().getString(CloudRkService.KEY_ENT_REPORT_URL);
|
||||
Proxy socksProxy = getSocksProxy();
|
||||
holder.debug("更新企业工商注册信息: " + company.getName() + " @ " + api + ", proxy=" + socksProxy);
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
try {
|
||||
post(api, data -> {
|
||||
data.put("entName", company.getName());
|
||||
data.put("entid", cloudRk.getCloudId());
|
||||
data.put("get", true);
|
||||
data.put("method", "data");
|
||||
data.put("nodetype", "B1001");
|
||||
}, jsonNode -> {
|
||||
modified.set(applyEnterpriseInfo(jsonNode, company, cloudRk, holder));
|
||||
saveJsonToFile(company, jsonNode, FileUtils.FILE_B1001_JSON, holder);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
catchException(e, holder);
|
||||
}
|
||||
return modified.get();
|
||||
}
|
||||
|
||||
private void catchException(IOException e, MessageHolder holder) throws IOException {
|
||||
if (e instanceof SSLException) {
|
||||
holder.error("网络错误:" + e.getMessage());
|
||||
// 网络错误时,抛出异常,中断后续网络请求
|
||||
throw e;
|
||||
}
|
||||
if (e instanceof SocketException) {
|
||||
holder.error("网络错误:" + e.getMessage());
|
||||
// 网络错误时,抛出异常,中断后续网络请求
|
||||
throw e;
|
||||
}
|
||||
holder.error(e.getMessage());
|
||||
}
|
||||
|
||||
private boolean applyEnterpriseInfo(JsonNode json, Company company, CloudRk cloudRk, MessageHolder holder) {
|
||||
if (!json.has("B1001")) {
|
||||
holder.error("数据异常,返回的json中没有 B1001 字段");
|
||||
return false;
|
||||
}
|
||||
JsonNode b1001 = json.get("B1001");
|
||||
if (!b1001.has("count") || b1001.get("count").asInt() < 1 || !b1001.has("data")) {
|
||||
holder.error("数据异常,B1001 字段没有数据");
|
||||
return false;
|
||||
}
|
||||
boolean modified = false;
|
||||
JsonNode data = b1001.get("data");
|
||||
if (updateText(company::getEntType, company::setEntType, data, "enttype", holder, "企业类型")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getEntStatus, company::setEntStatus, data, "entstatus", holder, "企业状态")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateLocalDate(company::getSetupDate, company::setSetupDate, data, "esdate", holder, "成立日期")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getUniscid, company::setUniscid, data, "uniscid", holder, "企业状态")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getRegAddr, company::setRegAddr, data, "dom", holder, "注册地址")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getRegisteredCapital, company::setRegisteredCapital, data, "regcap", holder, "注册资金")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getRegisteredCapitalCurrency, company::setRegisteredCapitalCurrency, data, "regcapcur", holder, "资本金币种")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getLegalRepresentative, company::setLegalRepresentative, data, "frname", holder, "法人")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getDistrict, company::setDistrict, data, "regorgprovince", holder, "注册区域")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getTelephone, company::setTelephone, data, "tel", holder, "注册电话")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getAddress, company::setAddress, data, "oploc", holder, "通讯地址")) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateOperationPeriodBegin(company, data, holder)) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateOperationPeriodEnd(company, data, holder)) {
|
||||
modified = true;
|
||||
}
|
||||
if (updateText(company::getIndustry, company::setIndustry, data, "nicfulltitle", holder, "行业")) {
|
||||
modified = true;
|
||||
}
|
||||
|
||||
updateCompanyNameHistory(company, data, holder.sub("曾用名"));
|
||||
updateLegalRepresentativeContact(company, data, holder.sub("法人联系方式"));
|
||||
updateInstant(cloudRk::getCloudEntUpdate, cloudRk::setCloudEntUpdate, data, "updated", holder, "更新时间", false);
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新法人联系人联系方式
|
||||
*/
|
||||
private void updateLegalRepresentativeContact(Company company, JsonNode data, MessageHolder holder) {
|
||||
String legalRepresentative = company.getLegalRepresentative();
|
||||
if (!StringUtils.hasText(legalRepresentative)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CompanyContactService contactService = SpringApp.getBean(CompanyContactService.class);
|
||||
List<CompanyContact> contactList = contactService.findAllByCompanyAndName(company, legalRepresentative);
|
||||
if (contactList == null) {
|
||||
// db error
|
||||
return;
|
||||
}
|
||||
CompanyContact contact = null;
|
||||
boolean modified = false;
|
||||
if (contactList.isEmpty()) {
|
||||
//没有,创建法人联系人
|
||||
contact = new CompanyContact();
|
||||
contact.setCompany(company);
|
||||
contact.setName(legalRepresentative);
|
||||
contact.setPosition("法定代表人");
|
||||
contact.setCreated(LocalDate.now());
|
||||
modified = true;
|
||||
} else {
|
||||
// 先尝试查找法人
|
||||
Optional<CompanyContact> any = contactList.stream().filter(c -> "法定代表人".equals(c.getPosition())).findAny();
|
||||
// 如果没有找到,列表中第一个联系人
|
||||
if (any.isEmpty()) {
|
||||
any = contactList.stream().findFirst();
|
||||
}
|
||||
contact = any.get();
|
||||
if (updateText(contact::getPosition, contact::setPosition, "法定代表人", holder, "职位")) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(contact.getEmail())) {
|
||||
if (updateText(contact::getEmail, contact::setEmail, data, "email", holder, "邮箱")) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(contact.getAddress())) {
|
||||
if (updateText(contact::getAddress, contact::setAddress, data, "oploc", holder, "地址")) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(contact.getPhone())) {
|
||||
if (updateText(contact::getPhone, contact::setPhone, data, "tel", holder, "电话")) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
contactService.save(contact);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean updateOperationPeriodBegin(Company company, JsonNode data, MessageHolder holder) {
|
||||
return updateLocalDate(company::getOperationPeriodBegin, company::setOperationPeriodBegin, data, "opfrom", holder, "营业期限起始日期", true);
|
||||
}
|
||||
|
||||
private boolean updateOperationPeriodEnd(Company company, JsonNode data, MessageHolder holder) {
|
||||
JsonNode node = data.get("opto");
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
String text = node.asText();
|
||||
if (StringUtils.hasText(text)) {
|
||||
if (text.equals("-")) {
|
||||
return updateLocalDate(company::getOperationPeriodEnd, company::setOperationPeriodEnd, (LocalDate) null, holder, "营业期限截至日期", true);
|
||||
}
|
||||
return updateLocalDate(company::getOperationPeriodEnd, company::setOperationPeriodEnd, data, "opto", holder, "营业期限截至日期", true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void updateCompanyNameHistory(Company company, JsonNode data, MessageHolder holder) {
|
||||
JsonNode node = data.get("nameHistory");
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
// 历史曾用名
|
||||
String nameHistory = node.asText();
|
||||
if (!StringUtils.hasText(nameHistory)) {
|
||||
return;
|
||||
}
|
||||
List<String> historyNames = new ArrayList<>();
|
||||
for (String str : nameHistory.split(",")) {
|
||||
String trimmed = str.trim();
|
||||
if (StringUtils.hasText(trimmed)) {
|
||||
historyNames.add(trimmed);
|
||||
}
|
||||
}
|
||||
CompanyOldNameService service = SpringApp.getBean(CompanyOldNameService.class);
|
||||
List<CompanyOldName> oldNames = service.findAllByCompany(company);
|
||||
for (CompanyOldName oldName : oldNames) {
|
||||
// 已经存在的移除
|
||||
historyNames.remove(oldName.getName());
|
||||
}
|
||||
for (String historyName : historyNames) {
|
||||
CompanyOldName oldName = service.createNew(company, historyName, false);
|
||||
oldName.setMemo("从相关方平台导入");
|
||||
service.save(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateLocalDate(Supplier<LocalDate> getter, Consumer<LocalDate> setter, JsonNode data, String field, MessageHolder holder, String topic, boolean allowNull) {
|
||||
JsonNode node = data.get(field);
|
||||
if (node == null || node.isNull()) {
|
||||
return false;
|
||||
}
|
||||
LocalDate localDate = getObjectMapper().convertValue(node, LocalDate.class);
|
||||
if (localDate == null && !allowNull) {
|
||||
return false;
|
||||
}
|
||||
return updateLocalDate(getter, setter, localDate, holder, topic, allowNull);
|
||||
}
|
||||
|
||||
private boolean updateLocalDate(Supplier<LocalDate> getter, Consumer<LocalDate> setter, JsonNode data, String field, MessageHolder holder, String topic) {
|
||||
return updateLocalDate(getter, setter, data, field, holder, topic, false);
|
||||
}
|
||||
|
||||
private void updateInstant(Supplier<Instant> getter, Consumer<Instant> setter, JsonNode data, String field, MessageHolder holder, String topic, boolean allowNull) {
|
||||
JsonNode node = data.get("updated");
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
LocalDateTime updated = getObjectMapper().convertValue(node, LocalDateTime.class);
|
||||
if (updated == null) {
|
||||
if (!allowNull) {
|
||||
return;
|
||||
}
|
||||
updateInstant(getter, setter, null, holder, topic);
|
||||
return;
|
||||
}
|
||||
Instant instant = updated.toInstant(ZoneOffset.ofHours(8));
|
||||
updateInstant(getter, setter, instant, holder, topic);
|
||||
}
|
||||
|
||||
private boolean updateText(Supplier<String> getter, Consumer<String> setter, JsonNode data, String field, MessageHolder holder, String topic) {
|
||||
JsonNode node = data.get(field);
|
||||
if (node == null || node.isNull()) {
|
||||
return false;
|
||||
}
|
||||
String text = node.asText();
|
||||
if (!StringUtils.hasText(text)) {
|
||||
return false;
|
||||
}
|
||||
return updateText(getter, setter, text, holder, topic);
|
||||
}
|
||||
|
||||
private void saveJsonToFile(Company company, JsonNode json, String fileName, MessageHolder holder) {
|
||||
String companyPath = company.getPath();
|
||||
if (!StringUtils.hasText(companyPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
File dir = new File(companyPath);
|
||||
if (!dir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(dir, fileName);
|
||||
try {
|
||||
getObjectMapper().writeValue(file, json);
|
||||
holder.debug("保存文件 " + file.getName());
|
||||
} catch (IOException e) {
|
||||
holder.error("保存文件 " + file.getName() + " 发生错误:" + e.getMessage());
|
||||
logger.error("Save {}", file.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public CloudRk getOrCreateCloudRk(Company company) {
|
||||
return getCloudRkService().getOrCreateCloudRk(company);
|
||||
}
|
||||
|
||||
public CloudRk save(CloudRk cloudRk) {
|
||||
return getCloudRkService().save(cloudRk);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user