diff --git a/mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/domain/thirdparty/MdmMerchantQueryDTO.java b/mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/domain/thirdparty/MdmMerchantQueryDTO.java index 69ccb3cbd..8a597732c 100644 --- a/mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/domain/thirdparty/MdmMerchantQueryDTO.java +++ b/mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/domain/thirdparty/MdmMerchantQueryDTO.java @@ -27,4 +27,7 @@ public class MdmMerchantQueryDTO implements Serializable { @ApiModelProperty("一级组织ID,用于读取三方接口配置") private Long topOrganizationId; + + @ApiModelProperty("当前同步组织ID,用于 desc24 为空时判定南光组织体系") + private Long syncOrganizationId; } diff --git a/mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/domain/thirdparty/MdmMerchantSyncFilter.java b/mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/domain/thirdparty/MdmMerchantSyncFilter.java new file mode 100644 index 000000000..6b152d649 --- /dev/null +++ b/mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/domain/thirdparty/MdmMerchantSyncFilter.java @@ -0,0 +1,122 @@ +package com.mhd.common.core.domain.thirdparty; + +import com.mhd.common.core.utils.StringUtils; + +/** + * MDM 客商应用侧过滤(MDM 查询条件 DESC24 在对方接口侧未严格生效,需本地过滤) + */ +public final class MdmMerchantSyncFilter { + + private static final String MDM_FLAG_YES = "1"; + + /** 南光组织 ID,仅南光本组织(2827)同步时 desc24 为空写入该组织 */ + public static final Long NANGUANG_ORGANIZATION_ID = 2827L; + + private MdmMerchantSyncFilter() { + } + + public enum SkipReason { + EMPTY_CODE, + NOT_CUSTOMER, + INTERNAL_ORG, + ORG_MISMATCH, + DISABLED, + MISSING_NAME + } + + public static boolean belongsToOrg(String recordDesc24, String orgNcCode) { + return belongsToOrg(recordDesc24, orgNcCode, null, null); + } + + /** + * desc24 与 orgNcCode 一致则匹配;desc24 为空仅当同步组织为南光(2827)时匹配。 + */ + public static boolean belongsToOrg(String recordDesc24, String orgNcCode, + Long syncOrganizationId, Long topOrganizationId) { + if (StringUtils.isEmpty(orgNcCode)) { + return true; + } + String desc24 = trim(recordDesc24); + if (orgNcCode.equals(desc24)) { + return true; + } + if (StringUtils.isEmpty(desc24)) { + return isNanguangOrganization(syncOrganizationId); + } + return false; + } + + /** 是否南光本组织(不含下级组织) */ + public static boolean isNanguangOrganization(Long syncOrganizationId) { + return NANGUANG_ORGANIZATION_ID.equals(syncOrganizationId); + } + + public static boolean isEmptyDesc24(String recordDesc24) { + return StringUtils.isEmpty(trim(recordDesc24)); + } + + /** + * desc24 为空且由南光本组织(2827)发起同步时,写入南光组织;否则写入当前同步组织。 + */ + public static Long resolveSaveOrganizationId(MdmMerchantRecordDTO record, Long syncOrganizationId) { + if (record != null && isEmptyDesc24(record.getDesc24()) && isNanguangOrganization(syncOrganizationId)) { + return NANGUANG_ORGANIZATION_ID; + } + return syncOrganizationId; + } + + public static boolean isCustomer(MdmMerchantRecordDTO record) { + return record != null && MDM_FLAG_YES.equals(trim(record.getDesc3())); + } + + public static boolean isDisabled(MdmMerchantRecordDTO record) { + if (record == null || StringUtils.isEmpty(record.getDesc30())) { + return false; + } + String status = record.getDesc30().trim(); + return "否".equals(status) || "停用".equals(status) || "0".equals(status) || "3".equals(status); + } + + /** + * 判断是否应同步到委托方列表 + */ + public static boolean shouldSync(MdmMerchantRecordDTO record, String orgNcCode) { + return resolveSkipReason(record, orgNcCode, null, null) == null; + } + + public static boolean shouldSync(MdmMerchantRecordDTO record, String orgNcCode, + Long syncOrganizationId, Long topOrganizationId) { + return resolveSkipReason(record, orgNcCode, syncOrganizationId, topOrganizationId) == null; + } + + public static SkipReason resolveSkipReason(MdmMerchantRecordDTO record, String orgNcCode) { + return resolveSkipReason(record, orgNcCode, null, null); + } + + public static SkipReason resolveSkipReason(MdmMerchantRecordDTO record, String orgNcCode, + Long syncOrganizationId, Long topOrganizationId) { + if (record == null || StringUtils.isEmpty(record.getCode())) { + return SkipReason.EMPTY_CODE; + } + if (!isCustomer(record)) { + return SkipReason.NOT_CUSTOMER; + } + if (StringUtils.isNotEmpty(orgNcCode) && orgNcCode.equals(trim(record.getCode()))) { + return SkipReason.INTERNAL_ORG; + } + if (!belongsToOrg(record.getDesc24(), orgNcCode, syncOrganizationId, topOrganizationId)) { + return SkipReason.ORG_MISMATCH; + } + if (StringUtils.isEmpty(trim(record.getDesc1()))) { + return SkipReason.MISSING_NAME; + } + if (isDisabled(record)) { + return SkipReason.DISABLED; + } + return null; + } + + private static String trim(String value) { + return value == null ? "" : value.trim(); + } +} diff --git a/mhd-user-center/src/main/java/com/mhd/user/application/service/AsyncUserShipperMasterDataSyncService.java b/mhd-user-center/src/main/java/com/mhd/user/application/service/AsyncUserShipperMasterDataSyncService.java index cfb560391..64f370c75 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/application/service/AsyncUserShipperMasterDataSyncService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/application/service/AsyncUserShipperMasterDataSyncService.java @@ -1,5 +1,7 @@ package com.mhd.user.application.service; +import com.mhd.common.core.constant.SecurityConstants; +import com.mhd.common.core.context.SecurityContextHolder; import com.mhd.common.redis.service.RedisLock; import com.mhd.system.api.model.LoginUser; import lombok.extern.slf4j.Slf4j; @@ -23,12 +25,34 @@ public class AsyncUserShipperMasterDataSyncService { public void syncMasterDataAsync(LoginUser loginUser, String lockKey) { Long organizationId = loginUser.getUserPo().getOrganizationId(); try { + bindLoginUser(loginUser); userShipperMasterDataSyncService.executeSync(loginUser); } catch (Exception e) { log.error("异步同步主数据失败, organizationId={}", organizationId, e); userShipperMasterDataSyncService.markSyncFailed(organizationId, e.getMessage()); } finally { + SecurityContextHolder.remove(); redisLock.unlock(lockKey); } } + + /** + * 异步线程无 HTTP 请求上下文,需手动注入 LoginUser 供 addUser/authShipper 等使用。 + */ + private void bindLoginUser(LoginUser loginUser) { + SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser); + if (loginUser.getUserid() != null) { + SecurityContextHolder.setUserId(String.valueOf(loginUser.getUserid())); + } else if (loginUser.getUserPo() != null && loginUser.getUserPo().getUserId() != null) { + SecurityContextHolder.setUserId(String.valueOf(loginUser.getUserPo().getUserId())); + } + if (loginUser.getUsername() != null) { + SecurityContextHolder.setUserName(loginUser.getUsername()); + } else if (loginUser.getUserPo() != null) { + SecurityContextHolder.setUserName(loginUser.getUserPo().getUserAccount()); + } + if (loginUser.getToken() != null) { + SecurityContextHolder.setUserKey(loginUser.getToken()); + } + } } diff --git a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java index fcbdb5536..4c4d02309 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperApplicationService.java @@ -1341,14 +1341,17 @@ public class UserShipperApplicationService { } @Transactional(rollbackFor = Exception.class) - public void addEnterpriseShipperFromMasterData(MdmMerchantRecordDTO record, LoginUser loginUser) { + public void addEnterpriseShipperFromMasterData(MdmMerchantRecordDTO record, LoginUser loginUser, + Long targetOrganizationId, String targetOrganizationName, + Long targetTopOrganizationId) { validateMasterDataRecord(record); UserConfigSwitchPo configSwitch = commonApplicationService.getUserConfigSwitch(); if (ObjectUtil.isNull(configSwitch)) { throw new ServiceException("获取组织配置失败"); } - UserShipperDO userShipperDO = buildShipperDOFromMasterData(record, loginUser); + UserShipperDO userShipperDO = buildShipperDOFromMasterData(record, loginUser, + targetOrganizationId, targetOrganizationName, targetTopOrganizationId); userShipperDO.setDataSource(1); userShipperDO.setShipperType(2); userShipperDO.setBusinessType(1); @@ -1375,23 +1378,103 @@ public class UserShipperApplicationService { userShipperDO.setUpdateTime(DateUtil.date()); UserShipperEntity userShipperEntity = userShipperDomainService.saveUserShipperByUserId(userShipperDO); userShipperDO.setShipperId(userShipperEntity.getShipperId()); - authShipper(userShipperDO); + authEnterpriseShipperForMasterData(userShipperDO, loginUser); UserShipperEntity shipperEntity = userShipperDomainService.findShipperByUserId(user.getUserId()); - wlhyDomainService.addShipperUserInfo(shipperEntity); + syncWlhyShipperSafely(shipperEntity, record.getCode()); + } + + /** + * MDM 同步专用审核:只更新认证状态,不复制登录人全部角色、不开钱包、不发通知;网货由 syncWlhyShipperSafely 处理。 + */ + private void authEnterpriseShipperForMasterData(UserShipperDO userShipperDO, LoginUser loginUser) { + if (userShipperDO.getAuthType() == null || userShipperDO.getAuthType() != 2) { + throw new ServiceException("MDM同步仅支持企业委托方审核"); + } + if (userShipperDO.getShipperAuthStatus() != 3) { + throw new ServiceException("MDM同步审核状态错误"); + } + Long authUserId; + String authUserName; + if (ObjectUtil.isNotNull(userShipperDO.getAutomaticCheckUserInfo()) + && ObjectUtil.equal(userShipperDO.getAutomaticCheckUserInfo(), 1) + && loginUser.getOrganizationPo() != null + && loginUser.getOrganizationPo().getPrincipalId() != null) { + authUserId = loginUser.getOrganizationPo().getPrincipalId(); + authUserName = loginUser.getOrganizationPo().getPrincipalName(); + } else { + authUserId = loginUser.getUserPo().getUserId(); + authUserName = loginUser.getUserPo().getUserName(); + } + String remark = "MDM主数据自动审核"; + userShipperDO.setShipperFill(userShipperDO.getShipperAuthStatus()); + userShipperDO.setShipperFillAuthId(authUserId); + userShipperDO.setShipperFillAuthName(authUserName); + userShipperDO.setShipperFillTime(DateUtil.date()); + userShipperDO.setShipperFillRemark(remark); + userShipperDO.setShipperEnterpriseFill(userShipperDO.getShipperAuthStatus()); + userShipperDO.setShipperType(2); + userShipperDO.setShipperEnterpriselAuthId(authUserId); + userShipperDO.setShipperEnterpriselAuthName(authUserName); + userShipperDO.setShipperEnterpriseFillTime(DateUtil.date()); + userShipperDO.setShipperEnterpriseFillRemark(remark); + + UserDO userDO = new UserDO(); + userDO.setUserId(userShipperDO.getUserId()); + userDO.setUserAuthStatus(userShipperDO.getShipperAuthStatus()); + userDO.setUserAuthTime(userShipperDO.getShipperFillTime()); + userDO.setUserAuthByUsername(authUserName); + userApplicationService.updateUser(userDO); + + userShipperDO.setUpdateByName(loginUser.getUsername()); + userShipperDO.setUpdateBy(loginUser.getUserid()); + userShipperDO.setUpdateTime(new Date()); + userShipperDomainService.saveUserShipper(userShipperDO); } @Transactional(rollbackFor = Exception.class) - public void updateEnterpriseShipperFromMasterData(MdmMerchantRecordDTO record, UserShipperPo existing, LoginUser loginUser) { + public void updateEnterpriseShipperFromMasterData(MdmMerchantRecordDTO record, UserShipperPo existing, + LoginUser loginUser, Long targetOrganizationId, + String targetOrganizationName, Long targetTopOrganizationId) { validateMasterDataRecord(record); - UserShipperDO userShipperDO = buildShipperDOFromMasterData(record, loginUser); + UserShipperDO userShipperDO = buildShipperDOFromMasterData(record, loginUser, + targetOrganizationId, targetOrganizationName, targetTopOrganizationId); userShipperDO.setDataSource(1); userShipperDO.setShipperId(existing.getShipperId()); userShipperDO.setUserId(existing.getUserId()); - updateShipper(userShipperDO); + updateShipperFromMasterData(userShipperDO, record.getCode()); } - private UserShipperDO buildShipperDOFromMasterData(MdmMerchantRecordDTO record, LoginUser loginUser) { + /** + * MDM 同步:本地更新成功后同步网货,网货失败仅记日志,不阻断主数据同步。 + */ + private void updateShipperFromMasterData(UserShipperDO userShipperDO, String customerCode) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + throw new DigitalLogisticsException(UserError.TIMEOUT); + } + UserPo loginUserPo = loginUser.getUserPo(); + userShipperDO.setUpdateBy(loginUserPo.getUserId()); + userShipperDO.setUpdateByName(loginUserPo.getUserName()); + userShipperDO.setUpdateTime(new Date()); + updateUserInformation(userShipperDO); + userShipperDomainService.saveUserShipper(userShipperDO); + UserShipperEntity shipperEntity = userShipperDomainService.findShipperByUserId(userShipperDO.getUserId()); + syncWlhyShipperSafely(shipperEntity, customerCode); + } + + private void syncWlhyShipperSafely(UserShipperEntity shipperEntity, String customerCode) { + try { + wlhyDomainService.addShipperUserInfo(shipperEntity); + } catch (Exception e) { + log.warn("MDM同步委托方本地保存成功,同步网货失败(不影响主数据同步), CODE={}, userId={}, msg={}", + customerCode, shipperEntity.getUserId(), e.getMessage(), e); + } + } + + private UserShipperDO buildShipperDOFromMasterData(MdmMerchantRecordDTO record, LoginUser loginUser, + Long targetOrganizationId, String targetOrganizationName, + Long targetTopOrganizationId) { UserShipperDO userShipperDO = new UserShipperDO(); userShipperDO.setCustomerNcCode(record.getCode()); userShipperDO.setUserMemberCode(record.getCode()); @@ -1409,9 +1492,9 @@ public class UserShipperApplicationService { userShipperDO.setShipperCorpIdcardNumber(record.getDesc23()); userShipperDO.setRegisteredAddress(record.getDesc13()); userShipperDO.setRegisteredPhone(record.getDesc15()); - userShipperDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); - userShipperDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); - userShipperDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + userShipperDO.setOrganizationId(targetOrganizationId); + userShipperDO.setOrganizationName(targetOrganizationName); + userShipperDO.setTopOrganizationId(targetTopOrganizationId); return userShipperDO; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperMasterDataSyncService.java b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperMasterDataSyncService.java index 8b81a645a..b679eb16b 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperMasterDataSyncService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserShipperMasterDataSyncService.java @@ -6,6 +6,7 @@ import com.mhd.common.core.constant.Constants; import com.mhd.common.core.domain.thirdparty.MdmMerchantQueryDTO; import com.mhd.common.core.domain.thirdparty.MdmMerchantQueryResultDTO; import com.mhd.common.core.domain.thirdparty.MdmMerchantRecordDTO; +import com.mhd.common.core.domain.thirdparty.MdmMerchantSyncFilter; import com.mhd.common.core.exception.ServiceException; import com.mhd.common.core.feign.ThirdPartyServiceFeign; import com.mhd.common.core.utils.StringUtils; @@ -36,8 +37,6 @@ public class UserShipperMasterDataSyncService { /** MDM 单页条数,不宜过大以免 MDM/Feign 超时 */ private static final int PAGE_SIZE = 100; private static final long SYNC_LOCK_MINUTES = 30; - /** MDM desc3:是否客户 */ - private static final String MDM_FLAG_YES = "1"; @Resource private ThirdPartyServiceFeign thirdPartyServiceFeign; @@ -121,6 +120,7 @@ public class UserShipperMasterDataSyncService { private ShipperMasterDataSyncResultVo doSync(LoginUser loginUser) { Long organizationId = loginUser.getUserPo().getOrganizationId(); + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); String orgNcCode = resolveOrgNcCode(organizationId); if (StringUtils.isEmpty(orgNcCode)) { throw new ServiceException("当前组织未配置NC编码,请先在组织管理中维护"); @@ -130,43 +130,70 @@ public class UserShipperMasterDataSyncService { String lastModifyRecordTime = syncEntity == null ? null : syncEntity.getLastModifyRecordTime(); ShipperMasterDataSyncResultVo resultVo = new ShipperMasterDataSyncResultVo(); - log.info("开始同步MDM客商, organizationId={}, orgNcCode={}, lastModifyRecordTime={}", - organizationId, orgNcCode, lastModifyRecordTime); + log.info("开始同步MDM客商, organizationId={}, topOrganizationId={}, orgNcCode={}, lastModifyRecordTime={}", + organizationId, topOrganizationId, orgNcCode, lastModifyRecordTime); Map existingMap = userShipperApplicationService.loadMasterDataSyncShipperMap(organizationId); String maxModifyTime = lastModifyRecordTime; + int skipOrgMismatch = 0; + int skipNotCustomer = 0; + int skipInternalOrg = 0; + int skipDisabled = 0; + int skipOther = 0; int currentPage = 1; Integer totalPages = null; do { MdmMerchantQueryResultDTO pageData = queryMerchantPage(orgNcCode, lastModifyRecordTime, - loginUser.getUserPo().getTopOrganizationId(), currentPage); + topOrganizationId, organizationId, currentPage); if (pageData == null || pageData.getDataInfo() == null) { break; } for (MdmMerchantRecordDTO record : pageData.getDataInfo()) { - if (!shouldSyncRecord(record, orgNcCode)) { + MdmMerchantSyncFilter.SkipReason skipReason = MdmMerchantSyncFilter.resolveSkipReason( + record, orgNcCode, organizationId, topOrganizationId); + if (skipReason != null) { resultVo.setSkipCount(resultVo.getSkipCount() + 1); + switch (skipReason) { + case ORG_MISMATCH: + skipOrgMismatch++; + break; + case NOT_CUSTOMER: + skipNotCustomer++; + break; + case INTERNAL_ORG: + skipInternalOrg++; + break; + case DISABLED: + skipDisabled++; + break; + default: + skipOther++; + break; + } continue; } try { String ncCode = trimToEmpty(record.getCode()); String companyName = trimToEmpty(record.getDesc1()); - if (StringUtils.isEmpty(ncCode) || StringUtils.isEmpty(companyName)) { - resultVo.setSkipCount(resultVo.getSkipCount() + 1); - continue; - } String matchKey = UserShipperApplicationService.buildMasterDataMatchKey(ncCode, companyName); + Long targetOrganizationId = MdmMerchantSyncFilter.resolveSaveOrganizationId(record, organizationId); + MasterDataSaveTarget saveTarget = resolveSaveTarget( + targetOrganizationId, organizationId, topOrganizationId, loginUser); UserShipperPo existing = existingMap.get(matchKey); if (existing == null) { - userShipperApplicationService.addEnterpriseShipperFromMasterData(record, loginUser); + userShipperApplicationService.addEnterpriseShipperFromMasterData( + record, loginUser, saveTarget.getOrganizationId(), + saveTarget.getOrganizationName(), saveTarget.getTopOrganizationId()); resultVo.setAddCount(resultVo.getAddCount() + 1); UserShipperPo added = userShipperApplicationService.findByCustomerNcCodeAndCompanyName( - ncCode, companyName, organizationId); + ncCode, companyName, saveTarget.getOrganizationId()); if (added != null) { existingMap.put(matchKey, added); } } else { - userShipperApplicationService.updateEnterpriseShipperFromMasterData(record, existing, loginUser); + userShipperApplicationService.updateEnterpriseShipperFromMasterData( + record, existing, loginUser, saveTarget.getOrganizationId(), + saveTarget.getOrganizationName(), saveTarget.getTopOrganizationId()); resultVo.setUpdateCount(resultVo.getUpdateCount() + 1); } maxModifyTime = maxTime(maxModifyTime, record.getLastModifyRecordTime()); @@ -177,6 +204,11 @@ public class UserShipperMasterDataSyncService { log.error(msg, e); } } + log.info("MDM同步进度 page={}/{}, 本页{}条, 累计新增={}, 更新={}, 跳过={}, 失败={}", + currentPage, pageData.getTotalPages() != null ? pageData.getTotalPages() : "?", + pageData.getDataInfo().size(), + resultVo.getAddCount(), resultVo.getUpdateCount(), + resultVo.getSkipCount(), resultVo.getFailCount()); totalPages = pageData.getTotalPages(); if (totalPages == null || totalPages <= 0) { break; @@ -186,12 +218,14 @@ public class UserShipperMasterDataSyncService { Date now = new Date(); resultVo.setLastSyncTime(now); - saveSyncWatermark(organizationId, maxModifyTime, now, resultVo); + saveSyncWatermark(organizationId, orgNcCode, maxModifyTime, now, resultVo, + skipOrgMismatch, skipNotCustomer, skipInternalOrg, skipDisabled, skipOther); return resultVo; } private MdmMerchantQueryResultDTO queryMerchantPage(String orgNcCode, String lastModifyRecordTime, - Long topOrganizationId, int currentPage) { + Long topOrganizationId, Long syncOrganizationId, + int currentPage) { MdmMerchantQueryDTO queryDTO = new MdmMerchantQueryDTO(); queryDTO.setOrgNcCode(orgNcCode); if (StringUtils.isNotEmpty(lastModifyRecordTime)) { @@ -200,6 +234,7 @@ public class UserShipperMasterDataSyncService { queryDTO.setCurrentPage(currentPage); queryDTO.setCountPerPage(PAGE_SIZE); queryDTO.setTopOrganizationId(topOrganizationId); + queryDTO.setSyncOrganizationId(syncOrganizationId); R response = thirdPartyServiceFeign.queryMdmMerchant(queryDTO); if (response == null || response.getCode() != Constants.SUCCESS) { @@ -208,31 +243,10 @@ public class UserShipperMasterDataSyncService { return response.getData(); } - /** - * 同步过滤:MDM 查询侧 DESC24 无法精确过滤,必须在应用侧严格筛选。 - */ - private boolean shouldSyncRecord(MdmMerchantRecordDTO record, String orgNcCode) { - if (record == null || StringUtils.isEmpty(record.getCode())) { - return false; - } - // 仅同步客户(desc3=是否客户) - if (!MDM_FLAG_YES.equals(trimToEmpty(record.getDesc3()))) { - return false; - } - // 对应组织编码必须等于当前组织 NC,空值不同步 - String recordOrgNc = trimToEmpty(record.getDesc24()); - if (StringUtils.isEmpty(recordOrgNc) || !orgNcCode.equals(recordOrgNc)) { - return false; - } - // 跳过本组织主体(code 与组织 NC 相同,多为内部单位而非外部客商) - if (orgNcCode.equals(trimToEmpty(record.getCode()))) { - return false; - } - return !isDisabled(record); - } - - private void saveSyncWatermark(Long organizationId, String maxModifyTime, Date syncTime, - ShipperMasterDataSyncResultVo resultVo) { + private void saveSyncWatermark(Long organizationId, String orgNcCode, String maxModifyTime, Date syncTime, + ShipperMasterDataSyncResultVo resultVo, + int skipOrgMismatch, int skipNotCustomer, int skipInternalOrg, + int skipDisabled, int skipOther) { UserShipperMdmSyncEntity entity = userShipperMdmSyncMapper.selectByOrganizationId(organizationId); if (entity == null) { entity = new UserShipperMdmSyncEntity(); @@ -244,8 +258,14 @@ public class UserShipperMasterDataSyncService { } entity.setLastSyncTime(syncTime); entity.setSyncStatus(resultVo.getFailCount() > 0 ? 2 : 1); - entity.setSyncMessage(String.format("新增%d,更新%d,跳过%d,失败%d", - resultVo.getAddCount(), resultVo.getUpdateCount(), resultVo.getSkipCount(), resultVo.getFailCount())); + String syncMessage = String.format( + "新增%d,更新%d,跳过%d,失败%d;组织NC=%s;跳过明细[组织不匹配:%d,非客户:%d,内部单位:%d,停用:%d,其他:%d]", + resultVo.getAddCount(), resultVo.getUpdateCount(), resultVo.getSkipCount(), resultVo.getFailCount(), + orgNcCode, skipOrgMismatch, skipNotCustomer, skipInternalOrg, skipDisabled, skipOther); + if (resultVo.getFailCount() > 0 && !resultVo.getErrorMessages().isEmpty()) { + syncMessage += ";" + resultVo.getErrorMessages().get(0); + } + entity.setSyncMessage(syncMessage); entity.setUpdateTime(syncTime); if (entity.getId() == null) { userShipperMdmSyncMapper.insert(entity); @@ -269,13 +289,42 @@ public class UserShipperMasterDataSyncService { return orgJson.has("ncCode") ? orgJson.getString("ncCode") : null; } - private boolean isDisabled(MdmMerchantRecordDTO record) { - if (StringUtils.isEmpty(record.getDesc30())) { - return false; + private MasterDataSaveTarget resolveSaveTarget(Long targetOrganizationId, Long syncOrganizationId, + Long topOrganizationId, LoginUser loginUser) { + if (MdmMerchantSyncFilter.NANGUANG_ORGANIZATION_ID.equals(targetOrganizationId)) { + return new MasterDataSaveTarget( + MdmMerchantSyncFilter.NANGUANG_ORGANIZATION_ID, + loginUser.getUserPo().getOrganizationName(), + MdmMerchantSyncFilter.NANGUANG_ORGANIZATION_ID); + } + return new MasterDataSaveTarget( + syncOrganizationId, + loginUser.getUserPo().getOrganizationName(), + topOrganizationId); + } + + private static final class MasterDataSaveTarget { + private final Long organizationId; + private final String organizationName; + private final Long topOrganizationId; + + private MasterDataSaveTarget(Long organizationId, String organizationName, Long topOrganizationId) { + this.organizationId = organizationId; + this.organizationName = organizationName; + this.topOrganizationId = topOrganizationId; + } + + private Long getOrganizationId() { + return organizationId; + } + + private String getOrganizationName() { + return organizationName; + } + + private Long getTopOrganizationId() { + return topOrganizationId; } - String status = record.getDesc30().trim(); - // 2=启用;0/3/否/停用 视为停用(结合 MDM 样例数据) - return "否".equals(status) || "停用".equals(status) || "0".equals(status) || "3".equals(status); } private String trimToEmpty(String value) { diff --git a/mhd_thrid_party/src/main/java/com/linke/thirdParty/application/server/MdmMasterDataApplicationService.java b/mhd_thrid_party/src/main/java/com/linke/thirdParty/application/server/MdmMasterDataApplicationService.java index c36a9a003..fe8a28f10 100644 --- a/mhd_thrid_party/src/main/java/com/linke/thirdParty/application/server/MdmMasterDataApplicationService.java +++ b/mhd_thrid_party/src/main/java/com/linke/thirdParty/application/server/MdmMasterDataApplicationService.java @@ -8,6 +8,7 @@ import com.linke.thirdParty.domain.departInterfaceInfo.repository.mapper.SysDepa import com.mhd.common.core.domain.thirdparty.MdmMerchantQueryDTO; import com.mhd.common.core.domain.thirdparty.MdmMerchantQueryResultDTO; import com.mhd.common.core.domain.thirdparty.MdmMerchantRecordDTO; +import com.mhd.common.core.domain.thirdparty.MdmMerchantSyncFilter; import com.mhd.common.core.exception.ServiceException; import com.mhd.common.core.utils.StringUtils; import lombok.extern.slf4j.Slf4j; @@ -23,6 +24,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; /** * 北京三维天地 MDM 客商主数据查询 @@ -43,7 +45,35 @@ public class MdmMasterDataApplicationService { log.info("MDM客商查询请求 orgNcCode={}, page={}, lastTime={}", queryDTO.getOrgNcCode(), queryDTO.getCurrentPage(), queryDTO.getLastModifyRecordTime()); String responseBody = doPost(config.url, config.usercode, config.password, requestBody); - return parseResponse(responseBody); + MdmMerchantQueryResultDTO result = parseResponse(responseBody); + return applyOrgFilter(queryDTO, result); + } + + /** + * MDM 对 DESC24 条件未严格过滤,按 orgNcCode 在应用侧二次过滤并修正分页描述。 + */ + private MdmMerchantQueryResultDTO applyOrgFilter(MdmMerchantQueryDTO queryDTO, MdmMerchantQueryResultDTO result) { + if (result == null || StringUtils.isEmpty(queryDTO.getOrgNcCode()) + || result.getDataInfo() == null || result.getDataInfo().isEmpty()) { + return result; + } + String orgNcCode = queryDTO.getOrgNcCode().trim(); + int rawCount = result.getDataInfo().size(); + List filtered = result.getDataInfo().stream() + .filter(record -> MdmMerchantSyncFilter.belongsToOrg( + record.getDesc24(), orgNcCode, + queryDTO.getSyncOrganizationId(), queryDTO.getTopOrganizationId())) + .collect(Collectors.toList()); + result.setDataInfo(filtered); + if (rawCount != filtered.size()) { + String note = String.format( + "(MDM原始%d条,按DESC24=%s或南光本组织空DESC24过滤后%d条;MDM总条数totalNumber为未过滤全库统计)", + rawCount, orgNcCode, filtered.size()); + result.setDesc(StringUtils.isEmpty(result.getDesc()) ? note : result.getDesc() + note); + log.info("MDM客商查询应用侧过滤 orgNcCode={}, rawPageSize={}, filteredPageSize={}, mdmTotalNumber={}", + orgNcCode, rawCount, filtered.size(), result.getTotalNumber()); + } + return result; } private MdmConfig loadConfig() { diff --git a/mhd_wms/src/main/resources/mapper/deliveTask/DeliveTaskMapper.xml b/mhd_wms/src/main/resources/mapper/deliveTask/DeliveTaskMapper.xml index de30424e6..7d35518b4 100644 --- a/mhd_wms/src/main/resources/mapper/deliveTask/DeliveTaskMapper.xml +++ b/mhd_wms/src/main/resources/mapper/deliveTask/DeliveTaskMapper.xml @@ -69,49 +69,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and (operators_name IS NULL OR operators_name = '') - - - and NOT ( - (task_type = 1 AND EXISTS ( - SELECT 1 FROM stock_receipt_order biz - WHERE biz.receipt_order_number = delive_task.tracking_number AND biz.del_flag = 1 - AND (biz.status >= 2 OR (biz.operators_by IS NOT NULL AND biz.operators_by != 0)) - )) - OR (task_type = 2 AND EXISTS ( - SELECT 1 FROM stock_shelf_order biz - WHERE biz.shelf_order_number = delive_task.tracking_number AND biz.del_flag = 1 - AND (biz.status >= 2 OR (biz.operators_by IS NOT NULL AND biz.operators_by != 0)) - )) - OR (task_type = 3 AND EXISTS ( - SELECT 1 FROM stock_out_task_order biz - WHERE biz.task_number = delive_task.tracking_number AND biz.del_flag = 1 - AND (biz.status >= 2 OR (biz.operators_by IS NOT NULL AND biz.operators_by != 0)) - )) - OR (task_type = 4 AND ( - EXISTS ( - SELECT 1 FROM review_order biz - WHERE biz.review_order_number = delive_task.tracking_number AND biz.del_flag = 1 - AND biz.review_status >= 2 - ) - OR EXISTS ( - SELECT 1 FROM stock_out_order biz - WHERE biz.out_order_number = delive_task.tracking_number AND biz.del_flag = 1 - AND (biz.check_status >= 2 OR (biz.check_operators_by IS NOT NULL AND biz.check_operators_by != 0)) - ) - )) - OR (task_type = 5 AND EXISTS ( - SELECT 1 FROM shift_manage biz - WHERE biz.shift_number = delive_task.tracking_number AND biz.del_flag = 1 - AND (biz.shift_status >= 3 OR (biz.operators_by IS NOT NULL AND biz.operators_by != 0)) - )) - OR (task_type = 6 AND EXISTS ( - SELECT 1 FROM investigation_manage biz - WHERE biz.investigation_number = delive_task.tracking_number AND biz.del_flag = 1 - AND (biz.investigation_status >= 3 OR (biz.operators_by IS NOT NULL AND biz.operators_by != 0)) - )) - ) - - del_flag = 1 @@ -257,7 +214,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - @@ -443,7 +399,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" WHERE del_flag = 1 - ) taskSum