数据同步问题修改

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;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
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.po.SettlementCustomersPO;
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.interfaces.dto.settlementCustomers.SettlementCustomersDTO;
import com.mhd.common.core.domain.po.SysDictDataVo;
@@ -34,7 +34,9 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -56,7 +58,10 @@ public class SettlementCustomersApplicationService {
private UserServiceFeign userServiceFeign;
@Autowired
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() {
/*
查询当前租户下所有的托运人、承运人、货主
对比用户id及主体角色,过滤出未同步的结算对象数据,
新增结算对象,结算方式默认月结,结算方向根据角色区分,承运商是收款方,客户是付款方
首先采用同步请求方式,如果后续数据量过大,更换消息队列或者异步新增
*/
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
SettlementCustomersDO settlementCustomersDO = new SettlementCustomersDO();
settlementCustomersDO.setMainRole(2);
settlementCustomersDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
List<SettlementCustomersPO> settlementCustomersList = settlementCustomersDomainService.queryList(settlementCustomersDO);
//TODO 查询货主信息
// List<SettlementCustomersPO> saveSettingCustomersList = settlementCustomersList
long startMs = System.currentTimeMillis();
SyncDictCache dictCache = loadSyncDictCache();
Map<String, SettlementCustomers> existingMap = loadExistingSettlementCustomersMap(
loginUser.getUserPo().getTopOrganizationId());
List<SettlementCustomers> toInsert = new ArrayList<>();
List<SettlementCustomers> toUpdate = new ArrayList<>();
syncShipperSettlementCustomers(loginUser, existingMap, dictCache, toInsert, toUpdate);
syncDriverSettlementCustomers(loginUser, existingMap, dictCache, toInsert, toUpdate);
batchPersist(toInsert, toUpdate);
log.info("同步结算对象完成,新增{}条,更新{}条,耗时{}ms", toInsert.size(), toUpdate.size(), System.currentTimeMillis() - startMs);
}
//查询托运人信息,并过滤,同步
settlementCustomersDO.setMainRole(2);
List<SettlementCustomersPO> shipperList = settlementCustomersDomainService.queryList(settlementCustomersDO);
private void syncShipperSettlementCustomers(LoginUser loginUser,
Map<String, SettlementCustomers> existingMap,
SyncDictCache dictCache,
List<SettlementCustomers> toInsert,
List<SettlementCustomers> toUpdate) {
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);
List<UserShipperPo> userShipperPoList = parseFeignList(ajaxResult, UserShipperPo.class);
if (userShipperPoList.isEmpty()) {
return;
}
if(userShipperPoList != null && userShipperPoList.size()>0){
//使用stream流过滤出 userShipperPoList中有但是shipperList中没有的集合
List<UserShipperPo> shipperListNew = userShipperPoList.stream().filter(userShipperPo -> {
return shipperList.stream().noneMatch(shipper -> ObjectUtil.equal(shipper.getSettlementEntityId(),userShipperPo.getUserId()));
}).collect(Collectors.toList());
if(shipperListNew.size()>0){
shipperListNew.forEach(userShipperPo -> {
SettlementCustomersDO saveEntity = new SettlementCustomersDO();
saveEntity.setSettlementCustomersCode(OrderSequence.getOrderCode());
saveEntity.setSettlementEntityId(userShipperPo.getUserId());
saveEntity.setSettlementEntity(userShipperPo.getUserName());
saveEntity.setSettlementMethodCode("monthly_settle");
saveEntity.setMainRole(1);
saveEntity.setCustomerTypeCode("customer"); //从货主同步过来的 默认客户
saveEntity.setNcCode(userShipperPo.getCustomerNcCode());
saveEntity.setCreateTime(new Date()); // Set the create time to the current date and time
Long settlementEntityId = saveEntity.getSettlementEntityId();
List<SettlementCustomers> settlementCustomers = settlementCustomersMapper.selectList(new LambdaQueryWrapper<SettlementCustomers>().eq(SettlementCustomers::getSettlementEntityId, settlementEntityId));
if(settlementCustomers != null && settlementCustomers.size() > 0){
for (SettlementCustomers settlementCustomer : settlementCustomers) {
settlementCustomer.setSettlementEntity(userShipperPo.getUserName());
settlementCustomer.setSettlementMethodCode("monthly_settle");
settlementCustomer.setMainRole(1);
settlementCustomer.setNcCode(userShipperPo.getCustomerNcCode());
settlementCustomer.setSettlementEntity(userShipperPo.getUserName());
settlementCustomersMapper.updateById(settlementCustomer);
}
} else {
saveEntity(saveEntity);
}
});
}
}
//查询承运人信息,并过滤,同步
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();
saveEntity.setSettlementCustomersCode(OrderSequence.getOrderCode());
saveEntity.setSettlementEntityId(userDriverPo.getUserId());
saveEntity.setSettlementEntity(userDriverPo.getUserName());
saveEntity.setSettlementMethodCode("monthly_settle");
saveEntity.setMainRole(1);
saveEntity.setCustomerTypeCode("customer");
saveEntity.setCreateTime(new Date()); // Set the create time to the current date and time
Long settlementEntityId = saveEntity.getSettlementEntityId();
List<SettlementCustomers> settlementCustomers = settlementCustomersMapper.selectList(new LambdaQueryWrapper<SettlementCustomers>().eq(SettlementCustomers::getSettlementEntityId, settlementEntityId));
if(settlementCustomers != null && settlementCustomers.size() > 0){
for (SettlementCustomers settlementCustomer : settlementCustomers) {
settlementCustomer.setSettlementEntity(userDriverPo.getUserName());
settlementCustomer.setSettlementMethodCode("monthly_settle");
settlementCustomer.setMainRole(1);
settlementCustomersMapper.updateById(settlementCustomer);
}
} else {
saveEntity(saveEntity);
}
});
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.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.setSettlementEntity(userShipperPo.getUserName());
saveEntity.setSettlementMethodCode("monthly_settle");
saveEntity.setMainRole(1);
saveEntity.setCustomerTypeCode("customer");
saveEntity.setNcCode(userShipperPo.getCustomerNcCode());
saveEntity.setSettlementCurrency(userShipperPo.getSettlementCurrency());
saveEntity.setOrganizationId(organizationId);
saveEntity.setOrganizationName(StringUtils.isNotEmpty(userShipperPo.getOrganizationName())
? userShipperPo.getOrganizationName()
: loginUser.getUserPo().getOrganizationName());
saveEntity.setTopOrganizationId(userShipperPo.getTopOrganizationId() != null
? userShipperPo.getTopOrganizationId()
: loginUser.getUserPo().getTopOrganizationId());
saveEntity.setCreateTime(new Date());
return saveEntity;
}
private SettlementCustomersDO buildDriverSettlementCustomerDO(UserDriverPo userDriverPo, LoginUser loginUser, Long organizationId) {
SettlementCustomersDO saveEntity = new SettlementCustomersDO();
saveEntity.setSettlementEntityId(userDriverPo.getUserId());
saveEntity.setSettlementEntity(userDriverPo.getUserName());
saveEntity.setSettlementMethodCode("monthly_settle");
saveEntity.setMainRole(1);
saveEntity.setCustomerTypeCode("customer");
saveEntity.setOrganizationId(organizationId);
saveEntity.setOrganizationName(StringUtils.isNotEmpty(userDriverPo.getOrganizationName())
? userDriverPo.getOrganizationName()
: loginUser.getUserPo().getOrganizationName());
saveEntity.setTopOrganizationId(userDriverPo.getTopOrganizationId() != null
? userDriverPo.getTopOrganizationId()
: loginUser.getUserPo().getTopOrganizationId());
saveEntity.setCreateTime(new Date());
return saveEntity;
}
/**
* 保存结算客户信息
@@ -92,5 +92,8 @@ public class SettlementCustomers extends BaseVOEntity{
@ApiModelProperty(name = "nc编码")
private String ncCode;
@ApiModelProperty("默认结算币种")
private String settlementCurrency;
}
@@ -93,7 +93,7 @@ public class SettlementCustomersPO extends BaseVOEntity{
@ApiModelProperty(name = "nc编码")
private String ncCode;
@ApiModelProperty(name = "结算币种")
@ApiModelProperty("默认结算币种")
private String settlementCurrency;
@ApiModelProperty("业务单据id")
@@ -105,6 +105,9 @@ public class SettlementCustomersDO extends BaseVOEntity{
@ApiModelProperty(name = "nc编码")
private String ncCode;
@ApiModelProperty("默认结算币种")
private String settlementCurrency;
@ApiModelProperty("业务流水号")
private String businessFlow;
@@ -104,6 +104,9 @@ public class SettlementCustomersDTO extends BaseVOEntity{
@ApiModelProperty(name = "nc编码")
private String ncCode;
@ApiModelProperty("默认结算币种")
private String settlementCurrency;
@ApiModelProperty("业务流水号")
private String businessFlow;
@@ -23,6 +23,7 @@
<result property="customerTypeCode" column="customer_type_code" />
<result property="projectCode" column="project_code" />
<result property="projectName" column="project_name" />
<result property="ncCode" column="nc_code" />
<result property="settlementObject" column="settlement_object" />
<result property="createTime" column="create_time" />
<result property="createBy" column="create_by" />
@@ -71,11 +72,40 @@
</if>
</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"
resultMap="SettlementCustomersResult">
select
a.*,
b.SETTLEMENT_CURRENCY as settlement_currency,
<include refid="settlement_customers_columns"/>,
COALESCE(a.settlement_currency, b.SETTLEMENT_CURRENCY) as settlement_currency,
bd.business_document_id,
bd.business_flow,
bd.original_business_num,