数据同步问题修改

This commit is contained in:
秦鸿展
2026-06-11 16:25:27 +08:00
parent 2912d10bbe
commit 801bfdff5f
6 changed files with 237 additions and 92 deletions
@@ -1,7 +1,6 @@
package com.mhd.bms.application.server.settlementCustomers; package com.mhd.bms.application.server.settlementCustomers;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -9,6 +8,7 @@ import com.mhd.bms.domain.settlementCustomers.entity.SettlementCustomers;
import com.mhd.bms.domain.settlementCustomers.repository.mapper.SettlementCustomersMapper; import com.mhd.bms.domain.settlementCustomers.repository.mapper.SettlementCustomersMapper;
import com.mhd.bms.domain.settlementCustomers.repository.po.SettlementCustomersPO; import com.mhd.bms.domain.settlementCustomers.repository.po.SettlementCustomersPO;
import com.mhd.bms.domain.settlementCustomers.repository.todo.SettlementCustomersDO; import com.mhd.bms.domain.settlementCustomers.repository.todo.SettlementCustomersDO;
import com.mhd.bms.domain.settlementCustomers.repository.persistence.SettlementCustomersImpl;
import com.mhd.bms.domain.settlementCustomers.service.SettlementCustomersDomainService; import com.mhd.bms.domain.settlementCustomers.service.SettlementCustomersDomainService;
import com.mhd.bms.interfaces.dto.settlementCustomers.SettlementCustomersDTO; import com.mhd.bms.interfaces.dto.settlementCustomers.SettlementCustomersDTO;
import com.mhd.common.core.domain.po.SysDictDataVo; import com.mhd.common.core.domain.po.SysDictDataVo;
@@ -34,7 +34,9 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -56,7 +58,10 @@ public class SettlementCustomersApplicationService {
private UserServiceFeign userServiceFeign; private UserServiceFeign userServiceFeign;
@Autowired @Autowired
private SettlementCustomersMapper settlementCustomersMapper; private SettlementCustomersMapper settlementCustomersMapper;
@Autowired
private SettlementCustomersImpl settlementCustomersImpl;
private static final int SYNC_BATCH_SIZE = 500;
/** /**
* 分页查询结算对象列表 * 分页查询结算对象列表
@@ -248,105 +253,206 @@ public class SettlementCustomersApplicationService {
* 同步结算对象 * 同步结算对象
*/ */
public void syncSettlementCustomers() { public void syncSettlementCustomers() {
/*
查询当前租户下所有的托运人、承运人、货主
对比用户id及主体角色,过滤出未同步的结算对象数据,
新增结算对象,结算方式默认月结,结算方向根据角色区分,承运商是收款方,客户是付款方
首先采用同步请求方式,如果后续数据量过大,更换消息队列或者异步新增
*/
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) { if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT); throw new DigitalLogisticsException(UserError.TIMEOUT);
} }
SettlementCustomersDO settlementCustomersDO = new SettlementCustomersDO(); long startMs = System.currentTimeMillis();
settlementCustomersDO.setMainRole(2); SyncDictCache dictCache = loadSyncDictCache();
settlementCustomersDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); Map<String, SettlementCustomers> existingMap = loadExistingSettlementCustomersMap(
List<SettlementCustomersPO> settlementCustomersList = settlementCustomersDomainService.queryList(settlementCustomersDO); loginUser.getUserPo().getTopOrganizationId());
//TODO 查询货主信息 List<SettlementCustomers> toInsert = new ArrayList<>();
// List<SettlementCustomersPO> saveSettingCustomersList = settlementCustomersList List<SettlementCustomers> toUpdate = new ArrayList<>();
syncShipperSettlementCustomers(loginUser, existingMap, dictCache, toInsert, toUpdate);
//查询托运人信息,并过滤,同步 syncDriverSettlementCustomers(loginUser, existingMap, dictCache, toInsert, toUpdate);
settlementCustomersDO.setMainRole(2); batchPersist(toInsert, toUpdate);
List<SettlementCustomersPO> shipperList = settlementCustomersDomainService.queryList(settlementCustomersDO); log.info("同步结算对象完成,新增{}条,更新{}条,耗时{}ms", toInsert.size(), toUpdate.size(), System.currentTimeMillis() - startMs);
AjaxResult ajaxResult = userServiceFeign.userShipperListAll();
List<UserShipperPo> userShipperPoList = new ArrayList<>();
if ("200".equals(String.valueOf(ajaxResult.get("code"))) && ObjectUtil.isNotNull(ajaxResult.get("data"))) {
userShipperPoList = JSONUtil.toList(JSONObject.toJSONString(ajaxResult.get("data")), UserShipperPo.class);
} }
if(userShipperPoList != null && userShipperPoList.size()>0){
//使用stream流过滤出 userShipperPoList中有但是shipperList中没有的集合 private void syncShipperSettlementCustomers(LoginUser loginUser,
List<UserShipperPo> shipperListNew = userShipperPoList.stream().filter(userShipperPo -> { Map<String, SettlementCustomers> existingMap,
return shipperList.stream().noneMatch(shipper -> ObjectUtil.equal(shipper.getSettlementEntityId(),userShipperPo.getUserId())); SyncDictCache dictCache,
}).collect(Collectors.toList()); List<SettlementCustomers> toInsert,
if(shipperListNew.size()>0){ List<SettlementCustomers> toUpdate) {
shipperListNew.forEach(userShipperPo -> { AjaxResult ajaxResult = userServiceFeign.userShipperListAll();
SettlementCustomersDO saveEntity = new SettlementCustomersDO(); List<UserShipperPo> userShipperPoList = parseFeignList(ajaxResult, UserShipperPo.class);
if (userShipperPoList.isEmpty()) {
return;
}
for (UserShipperPo userShipperPo : userShipperPoList) {
if (StringUtils.isEmpty(userShipperPo.getUserName())) {
continue;
}
Long organizationId = userShipperPo.getOrganizationId() != null
? userShipperPo.getOrganizationId()
: loginUser.getUserPo().getOrganizationId();
SettlementCustomersDO saveEntity = buildShipperSettlementCustomerDO(userShipperPo, loginUser, organizationId);
collectSyncEntity(existingMap, dictCache, organizationId, userShipperPo.getUserName(), saveEntity, toInsert, toUpdate);
}
}
private void syncDriverSettlementCustomers(LoginUser loginUser,
Map<String, SettlementCustomers> existingMap,
SyncDictCache dictCache,
List<SettlementCustomers> toInsert,
List<SettlementCustomers> toUpdate) {
AjaxResult ajaxResultDriver = userServiceFeign.userDriverListAll();
List<UserDriverPo> userDriverPoList = parseFeignList(ajaxResultDriver, UserDriverPo.class);
if (userDriverPoList.isEmpty()) {
return;
}
for (UserDriverPo userDriverPo : userDriverPoList) {
if (StringUtils.isEmpty(userDriverPo.getUserName())) {
continue;
}
Long organizationId = userDriverPo.getOrganizationId() != null
? userDriverPo.getOrganizationId()
: loginUser.getUserPo().getOrganizationId();
SettlementCustomersDO saveEntity = buildDriverSettlementCustomerDO(userDriverPo, loginUser, organizationId);
collectSyncEntity(existingMap, dictCache, organizationId, userDriverPo.getUserName(), saveEntity, toInsert, toUpdate);
}
}
private void collectSyncEntity(Map<String, SettlementCustomers> existingMap,
SyncDictCache dictCache,
Long organizationId,
String settlementEntity,
SettlementCustomersDO saveEntity,
List<SettlementCustomers> toInsert,
List<SettlementCustomers> toUpdate) {
String key = buildOrgEntityKey(organizationId, settlementEntity);
SettlementCustomers existing = existingMap.get(key);
applySyncDictLabels(saveEntity, dictCache);
if (existing != null) {
saveEntity.setSettlementCustomersId(existing.getSettlementCustomersId());
saveEntity.setSettlementCustomersCode(existing.getSettlementCustomersCode());
toUpdate.add(toEntity(saveEntity));
} else {
saveEntity.setSettlementCustomersCode(OrderSequence.getOrderCode()); saveEntity.setSettlementCustomersCode(OrderSequence.getOrderCode());
saveEntity.setDelFlag(1);
SettlementCustomers entity = toEntity(saveEntity);
toInsert.add(entity);
existingMap.put(key, entity);
}
}
private void batchPersist(List<SettlementCustomers> toInsert, List<SettlementCustomers> toUpdate) {
if (!toInsert.isEmpty()) {
settlementCustomersImpl.saveBatch(toInsert, SYNC_BATCH_SIZE);
}
if (!toUpdate.isEmpty()) {
settlementCustomersImpl.updateBatchById(toUpdate, SYNC_BATCH_SIZE);
}
}
private Map<String, SettlementCustomers> loadExistingSettlementCustomersMap(Long topOrganizationId) {
LambdaQueryWrapper<SettlementCustomers> wrapper = new LambdaQueryWrapper<SettlementCustomers>()
.eq(SettlementCustomers::getDelFlag, 1);
if (topOrganizationId != null) {
wrapper.eq(SettlementCustomers::getTopOrganizationId, topOrganizationId);
}
List<SettlementCustomers> existingList = settlementCustomersMapper.selectList(wrapper);
Map<String, SettlementCustomers> existingMap = new HashMap<>(existingList.size() * 2);
for (SettlementCustomers existing : existingList) {
if (existing.getOrganizationId() != null && StringUtils.isNotEmpty(existing.getSettlementEntity())) {
existingMap.put(buildOrgEntityKey(existing.getOrganizationId(), existing.getSettlementEntity()), existing);
}
}
return existingMap;
}
private SyncDictCache loadSyncDictCache() {
SyncDictCache cache = new SyncDictCache();
cache.settlementMethodLabel = resolveDictLabel(DictCode.SETTLEWAY.getCode(), "monthly_settle");
cache.customerTypeLabel = resolveDictLabel(DictCode.CUSTOMER_TYPE.getCode(), "customer");
return cache;
}
private String resolveDictLabel(String dictType, String dictValue) {
AjaxResult ajaxResult = systemServiceFeign.selectListByDictType(dictType);
if (!"200".equals(String.valueOf(ajaxResult.get("code"))) || ajaxResult.get("data") == null) {
return null;
}
List<SysDictDataVo> dictList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), SysDictDataVo.class);
if (dictList == null || dictList.isEmpty()) {
return null;
}
return dictList.stream()
.filter(info -> ObjectUtil.equal(info.getDictValue(), dictValue))
.map(SysDictDataVo::getDictLabel)
.findAny()
.orElse(null);
}
private void applySyncDictLabels(SettlementCustomersDO settlementCustomersDO, SyncDictCache dictCache) {
if (StringUtils.isNotEmpty(settlementCustomersDO.getSettlementMethodCode()) && dictCache.settlementMethodLabel != null) {
settlementCustomersDO.setSettlementMethod(dictCache.settlementMethodLabel);
}
if (StringUtils.isNotEmpty(settlementCustomersDO.getCustomerTypeCode()) && dictCache.customerTypeLabel != null) {
settlementCustomersDO.setCustomerType(dictCache.customerTypeLabel);
}
}
private <T> List<T> parseFeignList(AjaxResult ajaxResult, Class<T> clazz) {
if (!"200".equals(String.valueOf(ajaxResult.get("code"))) || ObjectUtil.isNull(ajaxResult.get("data"))) {
return new ArrayList<>();
}
List<T> list = JSON.parseArray(JSON.toJSONString(ajaxResult.get("data")), clazz);
return list != null ? list : new ArrayList<>();
}
private SettlementCustomers toEntity(SettlementCustomersDO settlementCustomersDO) {
SettlementCustomers settlementCustomers = new SettlementCustomers();
BeanUtils.copyProperties(settlementCustomersDO, settlementCustomers);
return settlementCustomers;
}
private String buildOrgEntityKey(Long organizationId, String settlementEntity) {
return organizationId + "|" + settlementEntity;
}
private static class SyncDictCache {
private String settlementMethodLabel;
private String customerTypeLabel;
}
private SettlementCustomersDO buildShipperSettlementCustomerDO(UserShipperPo userShipperPo, LoginUser loginUser, Long organizationId) {
SettlementCustomersDO saveEntity = new SettlementCustomersDO();
saveEntity.setSettlementEntityId(userShipperPo.getUserId()); saveEntity.setSettlementEntityId(userShipperPo.getUserId());
saveEntity.setSettlementEntity(userShipperPo.getUserName()); saveEntity.setSettlementEntity(userShipperPo.getUserName());
saveEntity.setSettlementMethodCode("monthly_settle"); saveEntity.setSettlementMethodCode("monthly_settle");
saveEntity.setMainRole(1); saveEntity.setMainRole(1);
saveEntity.setCustomerTypeCode("customer"); //从货主同步过来的 默认客户 saveEntity.setCustomerTypeCode("customer");
saveEntity.setNcCode(userShipperPo.getCustomerNcCode()); saveEntity.setNcCode(userShipperPo.getCustomerNcCode());
saveEntity.setCreateTime(new Date()); // Set the create time to the current date and time saveEntity.setSettlementCurrency(userShipperPo.getSettlementCurrency());
Long settlementEntityId = saveEntity.getSettlementEntityId(); saveEntity.setOrganizationId(organizationId);
List<SettlementCustomers> settlementCustomers = settlementCustomersMapper.selectList(new LambdaQueryWrapper<SettlementCustomers>().eq(SettlementCustomers::getSettlementEntityId, settlementEntityId)); saveEntity.setOrganizationName(StringUtils.isNotEmpty(userShipperPo.getOrganizationName())
if(settlementCustomers != null && settlementCustomers.size() > 0){ ? userShipperPo.getOrganizationName()
for (SettlementCustomers settlementCustomer : settlementCustomers) { : loginUser.getUserPo().getOrganizationName());
settlementCustomer.setSettlementEntity(userShipperPo.getUserName()); saveEntity.setTopOrganizationId(userShipperPo.getTopOrganizationId() != null
settlementCustomer.setSettlementMethodCode("monthly_settle"); ? userShipperPo.getTopOrganizationId()
settlementCustomer.setMainRole(1); : loginUser.getUserPo().getTopOrganizationId());
settlementCustomer.setNcCode(userShipperPo.getCustomerNcCode()); saveEntity.setCreateTime(new Date());
settlementCustomer.setSettlementEntity(userShipperPo.getUserName()); return saveEntity;
settlementCustomersMapper.updateById(settlementCustomer);
} }
} else {
saveEntity(saveEntity); private SettlementCustomersDO buildDriverSettlementCustomerDO(UserDriverPo userDriverPo, LoginUser loginUser, Long organizationId) {
}
});
}
}
//查询承运人信息,并过滤,同步
settlementCustomersDO.setMainRole(1);
List<SettlementCustomersPO> driverList = settlementCustomersDomainService.queryList(settlementCustomersDO);
AjaxResult ajaxResultDriver = userServiceFeign.userDriverListAll();
List<UserDriverPo> userDriverPoList = new ArrayList<>();
if ("200".equals(String.valueOf(ajaxResultDriver.get("code"))) && ObjectUtil.isNotNull(ajaxResultDriver.get("data"))) {
userDriverPoList = JSONUtil.toList(JSONObject.toJSONString(ajaxResultDriver.get("data")), UserDriverPo.class);
}
if(userDriverPoList != null && userDriverPoList.size()>0){
//使用stream流过滤出 userDriverPoList中有但是driverList中没有的集合
List<UserDriverPo> driverListNew = userDriverPoList.stream().filter(item -> {
return driverList.stream().noneMatch(driver -> ObjectUtil.equal(driver.getSettlementEntityId(),item.getUserId()));
}).collect(Collectors.toList());
if(driverListNew.size()>0){
driverListNew.forEach(userDriverPo -> {
SettlementCustomersDO saveEntity = new SettlementCustomersDO(); SettlementCustomersDO saveEntity = new SettlementCustomersDO();
saveEntity.setSettlementCustomersCode(OrderSequence.getOrderCode());
saveEntity.setSettlementEntityId(userDriverPo.getUserId()); saveEntity.setSettlementEntityId(userDriverPo.getUserId());
saveEntity.setSettlementEntity(userDriverPo.getUserName()); saveEntity.setSettlementEntity(userDriverPo.getUserName());
saveEntity.setSettlementMethodCode("monthly_settle"); saveEntity.setSettlementMethodCode("monthly_settle");
saveEntity.setMainRole(1); saveEntity.setMainRole(1);
saveEntity.setCustomerTypeCode("customer"); saveEntity.setCustomerTypeCode("customer");
saveEntity.setCreateTime(new Date()); // Set the create time to the current date and time saveEntity.setOrganizationId(organizationId);
Long settlementEntityId = saveEntity.getSettlementEntityId(); saveEntity.setOrganizationName(StringUtils.isNotEmpty(userDriverPo.getOrganizationName())
List<SettlementCustomers> settlementCustomers = settlementCustomersMapper.selectList(new LambdaQueryWrapper<SettlementCustomers>().eq(SettlementCustomers::getSettlementEntityId, settlementEntityId)); ? userDriverPo.getOrganizationName()
if(settlementCustomers != null && settlementCustomers.size() > 0){ : loginUser.getUserPo().getOrganizationName());
for (SettlementCustomers settlementCustomer : settlementCustomers) { saveEntity.setTopOrganizationId(userDriverPo.getTopOrganizationId() != null
settlementCustomer.setSettlementEntity(userDriverPo.getUserName()); ? userDriverPo.getTopOrganizationId()
settlementCustomer.setSettlementMethodCode("monthly_settle"); : loginUser.getUserPo().getTopOrganizationId());
settlementCustomer.setMainRole(1); saveEntity.setCreateTime(new Date());
settlementCustomersMapper.updateById(settlementCustomer); return saveEntity;
} }
} else {
saveEntity(saveEntity);
}
});
}
}
}
/** /**
* 保存结算客户信息 * 保存结算客户信息
@@ -92,5 +92,8 @@ public class SettlementCustomers extends BaseVOEntity{
@ApiModelProperty(name = "nc编码") @ApiModelProperty(name = "nc编码")
private String ncCode; private String ncCode;
@ApiModelProperty("默认结算币种")
private String settlementCurrency;
} }
@@ -93,7 +93,7 @@ public class SettlementCustomersPO extends BaseVOEntity{
@ApiModelProperty(name = "nc编码") @ApiModelProperty(name = "nc编码")
private String ncCode; private String ncCode;
@ApiModelProperty(name = "结算币种") @ApiModelProperty("默认结算币种")
private String settlementCurrency; private String settlementCurrency;
@ApiModelProperty("业务单据id") @ApiModelProperty("业务单据id")
@@ -105,6 +105,9 @@ public class SettlementCustomersDO extends BaseVOEntity{
@ApiModelProperty(name = "nc编码") @ApiModelProperty(name = "nc编码")
private String ncCode; private String ncCode;
@ApiModelProperty("默认结算币种")
private String settlementCurrency;
@ApiModelProperty("业务流水号") @ApiModelProperty("业务流水号")
private String businessFlow; private String businessFlow;
@@ -104,6 +104,9 @@ public class SettlementCustomersDTO extends BaseVOEntity{
@ApiModelProperty(name = "nc编码") @ApiModelProperty(name = "nc编码")
private String ncCode; private String ncCode;
@ApiModelProperty("默认结算币种")
private String settlementCurrency;
@ApiModelProperty("业务流水号") @ApiModelProperty("业务流水号")
private String businessFlow; private String businessFlow;
@@ -23,6 +23,7 @@
<result property="customerTypeCode" column="customer_type_code" /> <result property="customerTypeCode" column="customer_type_code" />
<result property="projectCode" column="project_code" /> <result property="projectCode" column="project_code" />
<result property="projectName" column="project_name" /> <result property="projectName" column="project_name" />
<result property="ncCode" column="nc_code" />
<result property="settlementObject" column="settlement_object" /> <result property="settlementObject" column="settlement_object" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
@@ -71,11 +72,40 @@
</if> </if>
</sql> </sql>
<sql id="settlement_customers_columns">
a.settlement_customers_id,
a.top_organization_id,
a.organization_id,
a.organization_name,
a.settlement_customers_code,
a.settlement_entity_id,
a.settlement_entity,
a.settlement_method,
a.settlement_method_code,
a.bank_name,
a.bank_card_number,
a.bank_binding_name,
a.remark,
a.main_role,
a.customer_type,
a.customer_type_code,
a.project_code,
a.project_name,
a.nc_code,
a.create_time,
a.create_by,
a.create_by_name,
a.update_time,
a.update_by,
a.update_by_name,
a.del_flag
</sql>
<select id="queryList" parameterType="com.mhd.bms.domain.settlementCustomers.repository.todo.SettlementCustomersDO" <select id="queryList" parameterType="com.mhd.bms.domain.settlementCustomers.repository.todo.SettlementCustomersDO"
resultMap="SettlementCustomersResult"> resultMap="SettlementCustomersResult">
select select
a.*, <include refid="settlement_customers_columns"/>,
b.SETTLEMENT_CURRENCY as settlement_currency, COALESCE(a.settlement_currency, b.SETTLEMENT_CURRENCY) as settlement_currency,
bd.business_document_id, bd.business_document_id,
bd.business_flow, bd.business_flow,
bd.original_business_num, bd.original_business_num,