diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/mch/MchManageEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/mch/MchManageEntity.java index 89450c983..1b6736d44 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/mch/MchManageEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/mch/MchManageEntity.java @@ -2,8 +2,8 @@ package com.bsd.pjcloud.wallet.api.entity.mch; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.bsd.pjcloud.wallet.api.constant.mch.WalletMchTableReservationMode; +import com.bsd.pjcloud.wallet.api.handler.MchManageJacksonTypeHandler; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -166,7 +166,7 @@ public class MchManageEntity extends Model { * 功能范围 */ @Schema(description = "功能范围") - @TableField(typeHandler = JacksonTypeHandler.class) + @TableField(typeHandler = MchManageJacksonTypeHandler.class) private FunctionScope functionScope; @@ -174,14 +174,14 @@ public class MchManageEntity extends Model { * 订餐详细配置 */ @Schema(description = "订餐详细配置") - @TableField(typeHandler = JacksonTypeHandler.class) + @TableField(typeHandler = MchManageJacksonTypeHandler.class) private TableReservationConf tableReservationConf; /** * 钱包别名 */ @Schema(description = "钱包别名") - @TableField(typeHandler = JacksonTypeHandler.class) + @TableField(typeHandler = MchManageJacksonTypeHandler.class) private List walletAliasList; /** diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/handler/MchManageJacksonTypeHandler.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/handler/MchManageJacksonTypeHandler.java new file mode 100644 index 000000000..df40dc4a2 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/handler/MchManageJacksonTypeHandler.java @@ -0,0 +1,54 @@ +package com.bsd.pjcloud.wallet.api.handler; + +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.bsd.pjcloud.wallet.api.entity.mch.MchManageEntity; +import com.fasterxml.jackson.core.type.TypeReference; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.List; + +/** + * 商户 JSON 字段类型处理器。 + * + *

MyBatis-Plus 自动结果映射会把字段反射信息传给 Jackson,但 XML 结果映射只会传递 + * {@link List} 原始类型。这里为钱包别名列表补充固定元素类型,避免其在不同查询路径下被解析为 Map。

+ */ +public class MchManageJacksonTypeHandler extends JacksonTypeHandler { + + /** + * 钱包别名列表的完整泛型类型,用于兼容 XML 结果映射无法传递字段泛型的场景。 + */ + private static final Type WALLET_ALIAS_LIST_TYPE = new TypeReference>() { + }.getType(); + + /** + * 创建仅持有属性原始类型的处理器,主要供 MyBatis XML 结果映射使用。 + * + * @param type 目标属性原始类型;列表类型会固定解析为钱包别名列表 + */ + public MchManageJacksonTypeHandler(Class type) { + super(type); + } + + /** + * 创建持有实体字段信息的处理器,供 MyBatis-Plus 和 MPJ 自动结果映射使用。 + * + * @param type 目标属性原始类型 + * @param field 实体字段,包含列表元素的泛型信息 + */ + public MchManageJacksonTypeHandler(Class type, Field field) { + super(type, field); + } + + /** + * 获取 Jackson 反序列化目标类型;字段泛型缺失时为钱包别名列表补充元素类型。 + * + * @return 当前商户 JSON 字段的完整目标类型 + */ + @Override + public Type getFieldType() { + Type fieldType = super.getFieldType(); + return List.class.equals(fieldType) ? WALLET_ALIAS_LIST_TYPE : fieldType; + } +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/MchManageMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/MchManageMapper.xml index d3835ef2c..3fcbcbfd0 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/MchManageMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/MchManageMapper.xml @@ -3,6 +3,21 @@ + + + + + + + select a.id, a.parent_id, @@ -27,6 +42,8 @@ a.cooperation_status, a.mch_count, a.function_scope, + a.table_reservation_conf, + a.wallet_alias_list, a.create_by, a.create_time, a.update_by, @@ -102,7 +119,7 @@ - c.name as catgoryName from mch_manage a @@ -113,7 +130,7 @@ order by a.sort desc , a.dept_id desc , a.create_time desc - c.name as catgoryName from mch_manage a @@ -123,4 +140,4 @@ order by a.sort desc , a.dept_id desc , a.create_time desc - \ No newline at end of file + diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/api/handler/MchManageJacksonTypeHandlerTest.java b/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/api/handler/MchManageJacksonTypeHandlerTest.java new file mode 100644 index 000000000..881c46187 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/test/java/com/bsd/pjcloud/wallet/api/handler/MchManageJacksonTypeHandlerTest.java @@ -0,0 +1,45 @@ +package com.bsd.pjcloud.wallet.api.handler; + +import com.bsd.pjcloud.wallet.api.entity.mch.MchManageEntity; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +/** + * 商户 JSON 字段在自动映射和 XML 映射下的目标类型测试。 + */ +class MchManageJacksonTypeHandlerTest { + + /** + * XML 映射只传入 List 原始类型时,元素仍应反序列化为钱包别名对象而不是 Map。 + */ + @Test + void rawListTypeShouldDeserializeWalletAliasElements() { + MchManageJacksonTypeHandler handler = new MchManageJacksonTypeHandler(List.class); + + Object value = handler.parse("[{\"walletTypeId\":10,\"walletUniqueCode\":\"EAT\",\"visible\":true,\"aliasName\":\"餐补\"}]"); + + List aliases = assertInstanceOf(List.class, value); + MchManageEntity.WalletAlias alias = assertInstanceOf(MchManageEntity.WalletAlias.class, aliases.get(0)); + assertEquals(10L, alias.getWalletTypeId()); + assertEquals("EAT", alias.getWalletUniqueCode()); + assertEquals("餐补", alias.getAliasName()); + } + + /** + * 普通对象字段应继续按 XML 显式传入的目标 Class 反序列化。 + */ + @Test + void concreteTypeShouldDeserializeConfiguredClass() { + MchManageJacksonTypeHandler handler = new MchManageJacksonTypeHandler(MchManageEntity.FunctionScope.class); + + Object value = handler.parse("{\"mallEnable\":true,\"tableReservation\":false}"); + + MchManageEntity.FunctionScope functionScope = assertInstanceOf(MchManageEntity.FunctionScope.class, value); + assertEquals(Boolean.TRUE, functionScope.getMallEnable()); + assertEquals(Boolean.FALSE, functionScope.getTableReservation()); + } +}