Merge branch 'dev' into dev-bms-260826

# Conflicts:
#	mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/BmsServiceFeign.java
#	mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/facade/IReservationStockInOrderService.java
#	mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/mapper/ReservationStockInOrderMapper.java
#	mhd_oms/src/main/resources/mapper/reservationStockInOrder/ReservationStockInOrderMapper.xml
#	mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/po/MaterialInventoryPO.java
#	mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryDO.java
#	mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryDTO.java
#	mhd_wms/src/main/resources/mapper/materialInventory/MaterialInventoryMapper.xml
This commit is contained in:
王奎兴
2026-09-05 15:14:35 +08:00
211 changed files with 9989 additions and 706 deletions
@@ -16,7 +16,8 @@ public enum RoleEnum {
STORE_ADMIN("店铺管理员", "store_admin"),
OWNER_CARGO("货主", "ownerCargo"),
SUPPLIER("供应商", "supplier"),
CUSTOMER("客户", "customer");
CUSTOMER("客户", "customer"),
TENANT("租户", "tenant");
private String name;
private String code;
@@ -26,7 +26,7 @@ import java.io.InputStream;
import java.util.List;
import java.util.Map;
@FeignClient(value = "mhd-third-party-service",url = "http://127.0.0.1:8012", configuration = FeignAutoConfiguration.class)
@FeignClient(value = "mhd-third-party-service",url = "http://10.102.192.31:8012",configuration = FeignAutoConfiguration.class)
public interface ThirdPartyServiceFeign {
//查询当前组织所有三方接口信息
@@ -334,4 +334,12 @@ public interface ThirdPartyServiceFeign {
@PostMapping("/mdmMasterData/queryMerchant")
R<com.mhd.common.core.domain.thirdparty.MdmMerchantQueryResultDTO> queryMdmMerchant(
@RequestBody com.mhd.common.core.domain.thirdparty.MdmMerchantQueryDTO queryDTO);
/**
* 南岐GPS:根据车牌号查询车辆实时定位
* @param carPlate 车牌号
* @return AjaxResultdata 为车辆定位信息(code=200 成功)
*/
@GetMapping("/nanqiGps/queryByPlate")
AjaxResult nanqiQueryByPlate(@RequestParam("carPlate") String carPlate);
}
@@ -0,0 +1,112 @@
package com.mhd.common.core.jackson;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import java.io.IOException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 宽松日期反序列化:兼容 yyyy-MM-dd(纯日期)等常见格式。
*
* 背景:库存查询等接口日期只保留年月日后,前端可能把 "2026-07-06" 这类纯日期回传,
* 而实体/DTO 上 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 是严格格式,反序列化直接报
* InvalidFormatException。本反序列化器解析顺序:
* 1) 字段 @JsonFormat 指定的模式(严格全匹配,保持原行为);
* 2) 兜底常见格式:yyyy-MM-dd HH:mm:ss → yyyy-MM-dd HH:mm → yyyy-MM-dd
* 3) 纯数字按毫秒时间戳;
* 4) 交给 Jackson 默认解析(ISO-8601 等)。
* 仅放宽接受范围,不影响任何既有格式的解析结果;由各服务 DateCompatibilityConfig 显式注册生效。
*
* @author rcx
* @date 2026-09-05
*/
public class FlexibleDateDeserializer extends JsonDeserializer<Date> implements ContextualDeserializer {
/** 兜底格式按长度降序排列,避免长文本被短格式部分解析 */
private static final String[] FALLBACK_PATTERNS = {
"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd"
};
/** 字段 @JsonFormat 指定的模式,可为空 */
private final String pattern;
public FlexibleDateDeserializer() {
this(null);
}
public FlexibleDateDeserializer(String pattern) {
this.pattern = pattern;
}
@Override
public Date deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
String value = parser.getText();
if (value == null || value.trim().isEmpty()) {
return null;
}
value = value.trim();
// 纯数字按毫秒时间戳(10位秒级时间戳也兼容)
if (value.matches("\\d{10,}")) {
return new Date(Long.parseLong(value));
}
// 1) 字段 @JsonFormat 指定的模式优先
Date parsed = tryParse(value, pattern);
// 2) 兜底常见格式
if (parsed == null) {
for (String fallback : FALLBACK_PATTERNS) {
parsed = tryParse(value, fallback);
if (parsed != null) {
break;
}
}
}
// 3) 交给 Jackson 默认解析(ISO-8601 等)
if (parsed == null) {
try {
parsed = ctxt.parseDate(value);
} catch (IllegalArgumentException ignore) {
// 走不到默认解析时统一在下方抛出友好异常
}
}
if (parsed == null) {
throw ctxt.weirdStringException(value, Date.class,
"支持格式:yyyy-MM-dd HH:mm:ss / yyyy-MM-dd HH:mm / yyyy-MM-dd");
}
return parsed;
}
/**
* 严格全匹配解析:解析失败或文本未完整消费(如按 yyyy-MM-dd 解析 "2026-07-06 10:00:00"
* 都视为不匹配返回 null,交由下一个格式尝试
*/
private Date tryParse(String value, String pattern) {
if (pattern == null || pattern.isEmpty()) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
sdf.setLenient(false);
ParsePosition pos = new ParsePosition(0);
Date date = sdf.parse(value, pos);
return (date != null && pos.getIndex() == value.length()) ? date : null;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
if (property != null) {
JsonFormat jsonFormat = property.getAnnotation(JsonFormat.class);
if (jsonFormat != null && jsonFormat.pattern() != null && !jsonFormat.pattern().isEmpty()) {
return new FlexibleDateDeserializer(jsonFormat.pattern());
}
}
return this;
}
}