拆分模块

This commit is contained in:
2025-09-03 20:56:44 +08:00
parent 08cc2c29a5
commit a2f5e4864b
939 changed files with 14227 additions and 9607 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}
/**
* 返回距离上次更新超过 SysConfigcloud.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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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);
}
}