Merge branch 'dev' into dev-bms-260826

# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/BmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/OmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/YmsServiceFeign.java
#	mhd-common/mhd-common-core/src/main/java/com/mhd/common/core/feign/ThirdPartyServiceFeign.java
#	mhd_oms/src/main/java/com/mhd/oms/infrastructure/feign/ThirdPartyServiceFeign.java
This commit is contained in:
王奎兴
2026-09-12 17:28:12 +08:00
28 changed files with 293 additions and 104 deletions
@@ -19,7 +19,8 @@ import java.util.Set;
/**
* bms财务结算系统feign调用接口
*/
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "http://10.102.192.3:8012",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-bms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "${feign.url.mhd-bms-service:}",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface BmsServiceFeign {
@@ -17,7 +17,8 @@ import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.102.192.4:8017",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-oms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "${feign.url.mhd-oms-service:}",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface OmsServiceFeign {
@@ -26,7 +26,8 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "http://10.102.192.30:8014",configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-wlhy-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "${feign.url.mhd-wlhy-service:}",configuration = FeignAutoConfiguration.class)
public interface WlhyServiceFeign {
/**
@@ -536,13 +537,6 @@ public interface WlhyServiceFeign {
@PostMapping("/feign/order/add")
public AjaxResult add(@RequestBody TmsOrderAddDTO tmsOrderAddDTO);
/**
* 修改运单(OMS调整业务单后同步修改TMS订单)
* @param tmsOrderAddDTO 需携带 TMS 订单 id 定位
*/
@PostMapping("/feign/order/update")
public AjaxResult update(@RequestBody TmsOrderAddDTO tmsOrderAddDTO);
@GetMapping("/feign/order/cancelIssueDocuments")
public AjaxResult cancelIssueDocuments(@RequestParam(name="executeOrderId") String executeOrderId);
@@ -21,7 +21,8 @@ import java.util.Map;
* @description: TODO
* @date 2024/5/10 8:58
**/
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE,url = "http://10.102.192.3:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-wms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE,url = "${feign.url.mhd-wms-service:}",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface WmsServiceFeign {
/**
@@ -13,7 +13,8 @@ import org.springframework.web.bind.annotation.*;
import java.util.Map;
@FeignClient(contextId = "XxlJobService", value = ServiceNameConstants.XXL_JOB_SERVICE,url = "http://127.0.0.1:8020",fallbackFactory = RemoteXxlJobFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.xxl-job-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "XxlJobService", value = ServiceNameConstants.XXL_JOB_SERVICE,url = "${feign.url.xxl-job-service:}",fallbackFactory = RemoteXxlJobFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface XxlJobServiceFeign {
@@ -9,7 +9,8 @@ import com.mhd.system.api.feign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "http://10.102.192.4:8018",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-yms-service 指定,未配置时按服务名走服务发现
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "${feign.url.mhd-yms-service:}",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
public interface YmsServiceFeign {
/**
@@ -130,9 +130,11 @@ public class TokenLoginApplicationService {
//验证码登录校验验证码
String key = CacheConstants.SMS_LOGIN + userPhone;
Object object = redisService.getCacheObject(key) == null ? "":redisService.getCacheObject(key);
if(!ObjectUtil.equal(String.valueOf(object),verificationCode) && !ObjectUtil.equal(verificationCode, SmsConstants.universalCode)){
recordLogininfor(userPhone, Constants.LOGIN_FAIL, "验证码错误", 1);
throw new ServiceException("验证码错误");
if (loginDTO.getWechatFlag() != 1) {
// if (!ObjectUtil.equal(String.valueOf(object), verificationCode) && !ObjectUtil.equal(verificationCode, SmsConstants.universalCode)) {
// recordLogininfor(userPhone, Constants.LOGIN_FAIL, "验证码错误", 1);
throw new ServiceException("验证码错误");
// }
}
//获取包名对应的业务(存在需要查询业务,不存在保存为无业务模式)
@@ -168,7 +170,13 @@ public class TokenLoginApplicationService {
throw new ServiceException("对不起,您的账号:" + userPhone + " 已停用");
}
//校验验证码是否正确
sysPasswordService.validate(userPo, verificationCode, 1, null);
if (loginDTO.getWechatFlag() != 1) {
// if (!ObjectUtil.equal(String.valueOf(object), verificationCode) && !ObjectUtil.equal(verificationCode, SmsConstants.universalCode)) {
// recordLogininfor(userPhone, Constants.LOGIN_FAIL, "验证码错误", 1);
throw new ServiceException("验证码错误");
// }
}
// sysPasswordService.validate(userPo, verificationCode, 1, null);
}
return userInfo;
}
@@ -40,4 +40,7 @@ public class LoginDTO {
@ApiModelProperty(name = "组织名称(司机选择组织时传入)")
private String organizationName;
@ApiModelProperty(name = "微信标识")
private Integer wechatFlag;
}
+4 -4
View File
@@ -12,10 +12,10 @@ spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# server-addr: 127.0.0.1:8848
# 线上测试环境配置 容器名+端口号
# server-addr: 10.33.0.129:6010
# server-addr: 10.102.192.31:6848
server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
#线上正式环境
@@ -23,8 +23,8 @@ spring:
# username: nacos
# password: manhuoda@2023
config:
server-addr: 127.0.0.1:8848
# server-addr: 10.102.192.31:6848
# server-addr: 127.0.0.1:8848
server-addr: 10.102.192.31:6848
# 测试环境配置 容器名+端口号
# server-addr: 10.33.0.129:6010
# 线上测试环境配置 容器名+端口号
@@ -47,7 +47,7 @@ public interface BiPlatformRealDataMapper {
/** 今日作业准时率统计(total 今日预约总数;onTimeCount 今日准时车辆数) */
RealOnTimeStatPO queryTodayOnTimeStats();
/** 任务类型统计(OMS 运输订单按业务类型分组:1-跨境 2-国内 */
/** 任务类型统计(YMS QMS_MAIN_BUSINESS 预约按业务类型 BUSINESS_NAME 分组 */
List<RealTaskTypeStatPO> queryMonthTransportOrderByType();
/** 月台监控-按楼层统计月台车辆(楼层、月台数量、今日预约车辆、当前作业车辆) */
@@ -5,16 +5,16 @@ import lombok.Data;
import java.io.Serializable;
/**
* 任务类型统计(真实数据,来自 NGWL_TEST_OMS.BUSINESS_DOCUMENT_ORDER 运输订单
* 按业务类型 businessCategory 分组统计当月数量:1-跨境运输 2-国内运输
* 任务类型统计(真实数据,来自 NGWL_TEST_YMS.QMS_MAIN_BUSINESS 预约登记表
* 按本月预约车辆数(TARGET_DATE 在当前月)以 BUSINESS_NAME 业务类型分组
*/
@Data
public class RealTaskTypeStatPO implements Serializable {
private static final long serialVersionUID = 1L;
/** 业务类型1-跨境 2-国内 */
private Integer businessCategory;
/** 业务类型名称(qms_main_business.BUSINESS_NAME */
private String businessName;
/** 该类型当月单量 */
/** 该业务类型本月预约车辆数 */
private Long count;
}
@@ -153,6 +153,12 @@ public class BiPlatformRealDataService {
}
fp.put("taskTypeStatistics", m);
}
// 月台告警统计:按业务要求恒为 0,纳入指纹以确保旧快照(可能含非0写死值)能被覆盖更新为 0
if (vo.getPlatformAlarmStatistics() != null) {
fp.put("todayAlarmTotal", vo.getPlatformAlarmStatistics().getTodayAlarmTotal());
fp.put("handled", vo.getPlatformAlarmStatistics().getHandled());
fp.put("unhandled", vo.getPlatformAlarmStatistics().getUnhandled());
}
return objectMapper.writeValueAsString(fp);
}
@@ -270,39 +276,32 @@ public class BiPlatformRealDataService {
}
/**
* 任务类型统计:当月 OMS 运输订单按业务类型分组(1-跨境运输,2-国内运输)。
* 返回 {totalTasks: 当月跨境+国内运输总单量, taskTypes: [{type, count}]}
* 查询失败时返回空结构,不影响写死字段
*/
/**
* 任务类型统计:固定输出「跨境运输」「国内运输」两类,count 取当月 OMS 业务单真实单量;
* 当月无数据或查询失败时仍返回两类、count=0(不使用写死模板兜底)。
* 任务类型统计:本月(YMS QMS_MAIN_BUSINESS)预约车辆按业务类型 BUSINESS_NAME 分组;
* 返回 {totalTasks: 当月总预约车辆数, taskTypes: [{type: 业务类型名称, count: 该类型预约数}]}
* 按真实 BUSINESS_NAME 分组输出,不固定兜底类别;当月无数据或查询失败时返回空列表
*/
public TaskTypeStatisticsVO queryMonthTransportOrderByType() {
int crossBorder = 0; // 跨境运输 BUSINESS_CATEGORY=1
int domestic = 0; // 国内运输 BUSINESS_CATEGORY=2
List<TaskTypeCountItemVO> items = new ArrayList<>();
int total = 0;
try {
List<RealTaskTypeStatPO> rows = biPlatformRealDataMapper.queryMonthTransportOrderByType();
if (rows != null) {
for (RealTaskTypeStatPO r : rows) {
if (r == null || r.getBusinessCategory() == null || r.getCount() == null) {
if (r == null || r.getBusinessName() == null || r.getCount() == null) {
continue;
}
if (r.getBusinessCategory() == 1) {
crossBorder = r.getCount().intValue();
} else if (r.getBusinessCategory() == 2) {
domestic = r.getCount().intValue();
}
int c = r.getCount().intValue();
items.add(TaskTypeCountItemVO.builder().type(r.getBusinessName()).count(c).build());
total += c;
}
}
} catch (Exception e) {
log.error("OMS】统计当月运输订单业务类型失败: {}", e.getMessage(), e);
// 失败时不回退写死模板,保持两类 count=0
log.error("YMS】统计当月预约业务类型失败: {}", e.getMessage(), e);
// 查询失败返回空列表(前端会显示空)
items = new ArrayList<>();
total = 0;
}
List<TaskTypeCountItemVO> items = new ArrayList<>();
items.add(TaskTypeCountItemVO.builder().type("跨境运输").count(crossBorder).build());
items.add(TaskTypeCountItemVO.builder().type("国内运输").count(domestic).build());
return TaskTypeStatisticsVO.builder().totalTasks(crossBorder + domestic).taskTypes(items).build();
return TaskTypeStatisticsVO.builder().totalTasks(total).taskTypes(items).build();
}
/**
@@ -447,7 +446,7 @@ public class BiPlatformRealDataService {
}
}
// 任务类型统计:OMS 业务单真实数据(固定跨境运输/国内运输两类,不使用写死模板兜底
// 任务类型统计:YMS QMS_MAIN_BUSINESS 按业务类型 BUSINESS_NAME 分组(真实业务数据
template.setTaskTypeStatistics(queryMonthTransportOrderByType());
return template;
@@ -248,7 +248,7 @@ public class BiReportSnapshotSyncService {
}
}
// ====== 真实数据:任务类型统计(OMS 业务单,固定跨境运输/国内运输两类,不使用写死模板兜底 ======
// ====== 真实数据:任务类型统计(YMS QMS_MAIN_BUSINESS 按业务类型 BUSINESS_NAME 分组 ======
template.setTaskTypeStatistics(biPlatformRealDataService.queryMonthTransportOrderByType());
return template;
@@ -185,13 +185,8 @@ public final class BiSnapshotWeeklyRandomDataBuilder {
.build());
}
// 月台告警:按业务要求,全部置 0(趋势/统计/分布均不生成写死数据)
List<PlatformAlarmTrendItemVO> alarmTrend = new ArrayList<>();
for (int i = 0; i < Baseline.P_AL_D.length; i++) {
alarmTrend.add(PlatformAlarmTrendItemVO.builder()
.date(Baseline.P_AL_D[i])
.alarmCount(Math.max(0, jitterInt(Baseline.P_AL_C[i], r)))
.build());
}
List<TaskTypeCountItemVO> typeCounts = new ArrayList<>();
for (int i = 0; i < Baseline.P_TT_TYPES.length; i++) {
@@ -201,18 +196,11 @@ public final class BiSnapshotWeeklyRandomDataBuilder {
.build());
}
int todayAl = Math.max(0, jitterInt(Baseline.P_AL_TOT, r));
int handled = Math.max(0, jitterInt(Baseline.P_AL_H, r));
handled = Math.min(handled, todayAl);
int unhandled = Math.max(0, todayAl - handled);
int todayAl = 0;
int handled = 0;
int unhandled = 0;
List<PlatformAlarmDistItemVO> dist = new ArrayList<>();
for (int i = 0; i < Baseline.P_DIST_T.length; i++) {
dist.add(PlatformAlarmDistItemVO.builder()
.type(Baseline.P_DIST_T[i])
.count(Math.max(0, jitterInt(Baseline.P_DIST_C[i], r)))
.build());
}
return PlatformSurveillanceVO.builder()
.vehicles(vehicles)
+2 -2
View File
@@ -19,14 +19,14 @@ spring:
# username: nacos
# password: manhuoda@2023
#线上正式环境
server-addr: 10.102.192.31:6848
server-addr: 10.102.192.30:6848
username: nacos
password: manhuoda@2023
config:
# server-addr: 127.0.0.1:8848
# 线上测试环境配置 容器名+端口号
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
server-addr: 10.102.192.30:6848
username: nacos
password: manhuoda@2023
#线上正式环境
@@ -148,19 +148,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ORDER BY 1 DESC
</select>
<!-- 任务类型统计(运输订单,来自 NGWL_TEST_OMS.BUSINESS_DOCUMENT_ORDER):
当月(CREATE_TIME 在当前月)按业务类型 BUSINESS_CATEGORY 分组统计
BUSINESS_CATEGORY: 1-跨境运输 2-国内运输 -->
<!-- 任务类型统计(来自 NGWL_TEST_YMS.QMS_MAIN_BUSINESS 预约登记表):
按本月预约车辆数(TARGET_DATE 在当前月)按 BUSINESS_NAME 业务类型分组统计 -->
<select id="queryMonthTransportOrderByType" resultType="com.mhd.bi.domain.biPlatformRealData.repository.po.RealTaskTypeStatPO">
SELECT
BUSINESS_CATEGORY AS businessCategory,
COUNT(1) AS count
FROM NGWL_TEST_OMS.BUSINESS_DOCUMENT_ORDER
WHERE BUSINESS_CATEGORY IN (1, 2)
AND CREATE_TIME IS NOT NULL
AND TO_CHAR(CREATE_TIME, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
GROUP BY BUSINESS_CATEGORY
ORDER BY BUSINESS_CATEGORY
BUSINESS_NAME AS businessName,
COUNT(1) AS count
FROM NGWL_TEST_YMS.QMS_MAIN_BUSINESS
WHERE BUSINESS_NAME IS NOT NULL
AND TARGET_DATE IS NOT NULL
AND TO_CHAR(TARGET_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
GROUP BY BUSINESS_NAME
ORDER BY COUNT(1) DESC
</select>
<!-- 任务负荷(今日 24 小时时段):按 EXTRACT(HOUR FROM ENTRY_TIME) 统计 -->
@@ -26,7 +26,8 @@ import java.io.InputStream;
import java.util.List;
import java.util.Map;
@FeignClient(value = "mhd-third-party-service",url = "http://10.102.192.30:8012", configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-third-party-service 指定未配置时按服务名走服务发现
@FeignClient(value = "mhd-third-party-service",url = "${feign.url.mhd-third-party-service:}", configuration = FeignAutoConfiguration.class)
public interface ThirdPartyServiceFeign {
//查询当前组织所有三方接口信息
@@ -13,16 +13,16 @@ spring:
cloud:
nacos:
discovery:
# server-addr: 127.0.0.1:8848
server-addr: 10.33.0.129:6010
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
#线上正式环境
# server-addr: 10.102.192.105:6848
config:
# server-addr: 127.0.0.1:8848
server-addr: 10.33.0.129:6010
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
@@ -97,6 +97,7 @@ import com.mhd.system.api.model.LoginUser;
import com.mhd.user.interfaces.dto.addDTO.UserDriverDTO;
import com.mhd.user.interfaces.dto.queryDTO.UserDocumentWarningQueryDTO;
import com.mhd.user.interfaces.dto.updateDTO.UpdateHasDefaultAddressDTO;
import com.mhd.user.interfaces.dto.updateDTO.PasswordChangeDTO;
import com.mhd.user.interfaces.facadeApi.Po.UserDriverCountPo;
import com.mhd.user.interfaces.vo.QueryAllShipperInfoVo;
import lombok.extern.slf4j.Slf4j;
@@ -214,6 +215,61 @@ public class UserApplicationService {
@Autowired
private UserShipperMapper userShipperMapper;
/**
* 修改密码 - 同步 wlhy yms
*/
@Transactional(rollbackFor = Exception.class)
public void changePassword(PasswordChangeDTO passwordChangeDTO) {
// 1. 获取当前登录用户
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
Long userId = loginUser.getUserPo().getUserId();
if (userId == null) {
throw new ServiceException("用户未登录");
}
// 2. 查询用户信息
UserPo userPO = userDomainService.selectByUserId(userId);
UserEntity userEntity = new UserEntity();
BeanUtils.copyProperties(userPO,userEntity);
if (ObjectUtil.isNull(userEntity)) {
throw new ServiceException("用户不存在");
}
// 3. 解密并加密新密码
String salt = userEntity.getUserSalt();
String newPassword = decrypt(passwordChangeDTO.getNewPassword());
String encodedPassword = PasswordUtil.encrypt(userEntity.getUserAccount(), newPassword, salt);
// 4. 更新本地密码
UserDO userDO = new UserDO();
userDO.setUserId(userId);
userDO.setUserPassword(encodedPassword);
userDomainService.updateUser(userDO);
// 5. 同步到网货平台wlhy
try {
userEntity.setUserPassword(encodedPassword);
wlhyDomainService.addOrEditPlatformUser(userEntity);
} catch (Exception e) {
log.warn("同步密码到网货平台失败,但不影响主流程:{}", e.getMessage());
}
// 6. 同步到 YMS 平台
try {
Integer isQueue = userMapper.getOrdIsQueue(userEntity.getOrganizationId());
if (isQueue != null && isQueue == 1) {
userEntity.setUserPassword(newPassword);
ymsDomainService.addOrEditYmsUser(userEntity);
}
} catch (Exception e) {
log.warn("同步密码到 YMS 平台失败,但不影响主流程:{}", e.getMessage());
}
}
/**
* @Description 查询用户列表
* @Author Alex
@@ -1971,6 +2027,11 @@ public class UserApplicationService {
if (StrUtil.isEmpty(userDO.getUserName())) {
userDO.setUserName("用户" + userDO.getUserPhone().substring(userDO.getUserPhone().length() - 4));
}
//密码为空则给默认密码
if (StrUtil.isEmpty(userDO.getUserPassword())) {
String defaultPassword = "Aa123456";
userDO.setUserPassword(PasswordUtil.encrypt(userDO.getUserAccount(), defaultPassword, userDO.getUserSalt()));
}
UserEntity userEntity = userDomainService.addUser(userDO);
//给小程序注册用户分配默认普通用户角色must本组织没有则找上级
userEntity.setUserPassword("Aa123456"); // 三方同步需要密码
@@ -100,6 +100,7 @@ public class UserYmsDomainService {
ymsSysUserDTO.setPhonenumber(userEntity.getUserPhone());
ymsSysUserDTO.setAvatar(userEntity.getAvatar());
ymsSysUserDTO.setUserAccountType(userEntity.getUserAccountType());
ymsSysUserDTO.setPassword(userEntity.getUserPassword());
if (StringUtils.isNotBlank(userEntity.getRoleCode())){
ymsSysUserDTO.setRoleCodes(Arrays.asList(userEntity.getRoleCode().split(",")));
@@ -0,0 +1,20 @@
package com.mhd.user.interfaces.dto.updateDTO;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 修改密码 DTO
* @author AI
* @date 2026/09/10
*/
@Data
public class PasswordChangeDTO {
/**
* 新密码
*/
@NotBlank(message = "新密码不能为空")
private String newPassword;
}
@@ -32,6 +32,7 @@ import com.mhd.common.security.annotation.InnerAuth;
import com.mhd.common.security.service.TokenService;
import com.mhd.system.api.model.LoginUser;
import com.mhd.user.interfaces.dto.queryDTO.UserDocumentWarningQueryDTO;
import com.mhd.user.interfaces.dto.updateDTO.PasswordChangeDTO;
import com.mhd.user.interfaces.dto.updateDTO.UpdateHasDefaultAddressDTO;
import com.mhd.user.interfaces.vo.QueryAllShipperInfoVo;
import io.swagger.annotations.Api;
@@ -1037,4 +1038,16 @@ public class UserAPI extends BaseController {
public R<String> finShipperEnterpriseNamedByUserId(@PathVariable("userId") Long userId) {
return R.ok(userApplicationService.finShipperEnterpriseNamedByUserId(userId));
}
/**
* 修改密码 - 同步 wlhy yms
* 根据当前登录用户判断是谁修改只传新密码不需要校验旧密码
*/
@Log(title = "用户中台管理 - 修改密码", description ="修改当前登录用户密码",businessType = BusinessType.UPDATE)
@ApiOperation("修改密码")
@PostMapping("/changePassword")
public AjaxResult changePassword(@RequestBody PasswordChangeDTO passwordChangeDTO) {
userApplicationService.changePassword(passwordChangeDTO);
return AjaxResult.success();
}
}
@@ -18,15 +18,15 @@ spring:
cloud:
nacos:
discovery:
# server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
config:
# server-addr: 127.0.0.1:8848
server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
server-addr: 10.102.192.31:6848
# server-addr: 10.102.192.31:6848
username: nacos
password: manhuoda@2023
group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置
@@ -49,4 +49,8 @@ feign:
readTimeout: 120000
mhd-third-party-service:
connectTimeout: 10000
readTimeout: 120000
readTimeout: 120000
#wechat:
# miniapp:
# appId: wxc9dd2810a77e4e30
# appSecret: 9354ff1215a82785ef14f2355fbf2185
@@ -22,7 +22,8 @@ import java.util.Map;
/**
* 三方服务 Feign
*/
@FeignClient(contextId = "thirdPartyServiceFeign",url = "http://10.102.192.30:8012", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
// 目标地址由 nacos 配置项 feign.url.mhd-third-party-service 指定未配置时按服务名走服务发现
@FeignClient(contextId = "thirdPartyServiceFeign",url = "${feign.url.mhd-third-party-service:}", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
public interface ThirdPartyServiceFeign {
//查询当前组织所有三方接口信息
@@ -573,10 +573,11 @@ public class MaterialBaseInfoApplicationService {
normalizeImportBarCodeWhenDuplicateOfHs(row);
fillIdsFromExistingMasterData(row);
fillOrganizationFromShipperIfNeeded(row);
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
// 登录组织优先以登录账号的组织为准覆盖货主解析带来的组织避免用货主组织导致包装规格等主数据查不到
if (isValidOrgId(loginOrgId)) {
row.setOrganizationId(loginOrgId);
}
if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
if (isValidOrgId(loginTopOrgId)) {
row.setTopOrganizationId(loginTopOrgId);
}
fillOrganizationName(row, loginUser);
@@ -128,10 +128,11 @@ public class MaterialBaseInfoAsyncService {
materialBaseInfoApplicationService.normalizeImportBarCodeWhenDuplicateOfHs(row);
materialBaseInfoApplicationService.fillIdsFromExistingMasterData(row);
materialBaseInfoApplicationService.fillOrganizationFromShipperIfNeeded(row);
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
// 登录组织优先以登录账号的组织为准覆盖货主解析带来的组织避免用货主组织(如2841)导致包装规格等主数据查不到
if (isValidOrgId(loginOrgId)) {
row.setOrganizationId(loginOrgId);
}
if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
if (isValidOrgId(loginTopOrgId)) {
row.setTopOrganizationId(loginTopOrgId);
}
materialBaseInfoApplicationService.fillOrganizationName(row, loginUser);
@@ -2040,21 +2040,71 @@ public class StockInOrderApplicationService {
r.getMaterialCode(), topOrganizationId, shipperId);
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
log.info("料号查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
MaterialBaseInfoPO materialBaseInfoPO = null;
if (materialList != null && !materialList.isEmpty()) {
materialBaseInfoPO = materialList.get(0);
MaterialBaseInfoPO materialBaseInfoPO = pickMaterialByCode(materialList, r.getMaterialCode(), shipperId, order.getShipperName());
// 兜底按名称解析出的shipperId可能与物料档案shipper_id不一致系统中存在同名货主账号
// 按user_name精确匹配解析到了另一个同名列货主此时去掉货主ID条件再查一次
// 用物料档案冗余的shipper_name与Excel客户名称等值匹配
if (materialBaseInfoPO == null && StringUtils.isNotBlank(order.getShipperName())) {
MaterialBaseInfoDO fallbackDO = new MaterialBaseInfoDO();
fallbackDO.setMaterialCode(r.getMaterialCode());
if (topOrganizationId != null) {
fallbackDO.setTopOrganizationId(topOrganizationId);
}
List<MaterialBaseInfoPO> fallbackList = materialBaseInfoService.queryList(fallbackDO);
materialBaseInfoPO = pickMaterialByCode(fallbackList, r.getMaterialCode(), null, order.getShipperName());
if (materialBaseInfoPO != null) {
log.warn("导入料号校验:按解析shipperId未匹配到物料,已按档案货主名称兜底匹配。料号: [{}], 解析shipperId: {}, 档案shipperId: {}, 档案shipperName: {}",
r.getMaterialCode(), shipperId, materialBaseInfoPO.getShipperId(), materialBaseInfoPO.getShipperName());
// 以档案货主为准纠正单据货主信息避免后续shipperParam按错误的shipperId反查覆盖货主名称
if (materialBaseInfoPO.getShipperId() != null) {
shipperId = materialBaseInfoPO.getShipperId();
order.setShipperId(shipperId);
}
if (StringUtils.isNotBlank(materialBaseInfoPO.getShipperCode())) {
order.setShipperCode(materialBaseInfoPO.getShipperCode());
}
if (StringUtils.isNotBlank(materialBaseInfoPO.getShipperName())) {
order.setShipperName(materialBaseInfoPO.getShipperName());
}
}
}
if (materialBaseInfoPO != null) {
materialBaseInfoId = materialBaseInfoPO.getMaterialBaseInfoId();
log.info("通过料号查询到物料基础信息,料号: {}, 物料ID: {}, 货主ID: {}",
log.info("通过料号查询到物料基础信息,料号: {}, 物料ID: {}, 货主ID: {}",
r.getMaterialCode(), materialBaseInfoId, shipperId);
} else {
// 如果提供了料号但查询不到或不属于该货主直接报错不允许导入
String errorMsg = String.format("导入失败:该货主下不存在该料号(货主名称=%s,料号=%s)。请确保该料号已在物料管理中创建,且属于该货主",
order.getShipperName(), r.getMaterialCode());
// 诊断对照查询仅用于日志定位不影响流程去掉货主ID条件再查一次
// 用于区分两类原因A-按名称解析出的shipperId与物料档案shipper_id不一致货主错配
// B-登录人topOrganizationId与物料档案top_organization_id不一致组织口径不一致
try {
MaterialBaseInfoDO diagDO = new MaterialBaseInfoDO();
diagDO.setMaterialCode(r.getMaterialCode());
if (topOrganizationId != null) {
diagDO.setTopOrganizationId(topOrganizationId);
}
List<MaterialBaseInfoPO> diagList = materialBaseInfoService.queryList(diagDO);
if (diagList != null && !diagList.isEmpty()) {
MaterialBaseInfoPO diagPo = diagList.get(0);
log.error("导入料号校验诊断:去掉货主条件后可查到物料,判定为货主解析错配(原因A)。料号: [{}], 解析shipperId: {}, 登录topOrganizationId: {}, 物料ID: {}, 档案shipperId: {}, 档案shipperName: {}, 档案topOrganizationId: {}",
r.getMaterialCode(), shipperId, topOrganizationId,
diagPo.getMaterialBaseInfoId(), diagPo.getShipperId(), diagPo.getShipperName(), diagPo.getTopOrganizationId());
} else {
log.error("导入料号校验诊断:去掉货主条件后仍查不到物料,判定为组织口径不一致(原因B)。料号: [{}], 解析shipperId: {}, 登录topOrganizationId: {}",
r.getMaterialCode(), shipperId, topOrganizationId);
}
} catch (Exception diagEx) {
log.warn("导入料号校验诊断查询异常,料号: [{}], 错误: {}", r.getMaterialCode(), diagEx.getMessage());
}
String errorMsg = String.format("导入失败:该货主下不存在该料号(货主名称=%s,料号=%s,解析shipperId=%s,登录topOrganizationId=%s)。请确保该料号已在物料管理中创建,且属于该货主",
order.getShipperName(), r.getMaterialCode(),
shipperId == null ? "" : shipperId, topOrganizationId == null ? "" : topOrganizationId);
log.error(errorMsg);
throw new ServiceException(errorMsg);
}
// 校验料号与规格型号/SKU码一致性按料号查到档案后逐项比对任何一项不符直接报对应错误
// 双方trim后必须完全一致Excel留空而档案有值或Excel填了值而档案为空均视为不一致报错
// 规格型号trim后双方必须完全一致Excel留空而档案有值或Excel填了值而档案为空均视为不一致报错
// SKU码档案条码barCode为空时跳过比对存量档案普遍未维护条码档案有值时仍严格比对
String excelSpec = StringUtils.trimToEmpty(r.getSpecificationModel());
String dbSpec = StringUtils.trimToEmpty(materialBaseInfoPO.getSpecificationModel());
if (!excelSpec.equals(dbSpec)) {
@@ -2064,7 +2114,7 @@ public class StockInOrderApplicationService {
}
String excelSku = StringUtils.trimToEmpty(r.getSkuCode());
String dbSku = StringUtils.trimToEmpty(materialBaseInfoPO.getBarCode());
if (!excelSku.equals(dbSku)) {
if (StringUtils.isNotEmpty(dbSku) && !excelSku.equals(dbSku)) {
throw new ServiceException(String.format("导入失败:料号[%s](商品名称:%s)SKU码与物料档案不一致(Excel:%s / 档案:%s",
r.getMaterialCode(), r.getMaterialName(),
excelSku.isEmpty() ? "" : excelSku, dbSku.isEmpty() ? "" : dbSku));
@@ -2398,6 +2448,46 @@ public class StockInOrderApplicationService {
return oid != null && loginOrganizationId.equals(oid);
}
/**
* 导入校验从按料号SQL为LIKE模糊查出的物料列表中挑选匹配记录
* 优先级料号精确等值优先于模糊命中避免子串料号误匹配
* 同级内优先 shipperId 精确匹配其次 shipperName 等值匹配最后取排序第一条与原 get(0) 行为一致
*/
private MaterialBaseInfoPO pickMaterialByCode(List<MaterialBaseInfoPO> materialList, String materialCode, Long shipperId, String shipperName) {
if (materialList == null || materialList.isEmpty()) {
return null;
}
String code = StringUtils.trimToEmpty(materialCode);
String name = StringUtils.trimToEmpty(shipperName);
MaterialBaseInfoPO exactCodeFirst = null;
MaterialBaseInfoPO anyFirst = null;
// 第一轮料号精确等值中优先 shipperId 精确匹配
for (MaterialBaseInfoPO po : materialList) {
if (anyFirst == null) {
anyFirst = po;
}
if (StringUtils.isEmpty(code) || !code.equals(StringUtils.trimToEmpty(po.getMaterialCode()))) {
continue;
}
if (exactCodeFirst == null) {
exactCodeFirst = po;
}
if (shipperId != null && shipperId.equals(po.getShipperId())) {
return po;
}
}
// 第二轮料号精确等值中按档案货主名称等值匹配
if (StringUtils.isNotEmpty(name)) {
for (MaterialBaseInfoPO po : materialList) {
if (StringUtils.isNotEmpty(code) && code.equals(StringUtils.trimToEmpty(po.getMaterialCode()))
&& name.equals(StringUtils.trimToEmpty(po.getShipperName()))) {
return po;
}
}
}
return exactCodeFirst != null ? exactCodeFirst : anyFirst;
}
/**
* @description 根据货主名称或编号获取货主ID用于导入时提前获取货主ID
* @param shipperName 货主名称
+2 -2
View File
@@ -16,7 +16,7 @@ spring:
# server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
# 线上测试环境配置 容器名+端口号
server-addr: 10.102.192.31:6848
server-addr: 10.102.192.30:6848
username: nacos
password: manhuoda@2023
#线上正式环境
@@ -25,7 +25,7 @@ spring:
# server-addr: 127.0.0.1:8848
# server-addr: 10.33.0.129:6010
# 线上测试环境配置 容器名+端口号
server-addr: 10.102.192.31:6848
server-addr: 10.102.192.30:6848
username: nacos
password: manhuoda@2023
#线上正式环境