feat:钱包配置json解析

This commit is contained in:
dzc committed 2026-08-23 13:30:28 +08:00
1 parent 15743935ef
commit f917e231af
4 files changed
+123 -7

No files matched your search

@@ -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<MchManageEntity> {
* 功能范围
*/
@Schema(description = "功能范围")
@TableField(typeHandler = JacksonTypeHandler.class)
@TableField(typeHandler = MchManageJacksonTypeHandler.class)
private FunctionScope functionScope;
@@ -174,14 +174,14 @@ public class MchManageEntity extends Model<MchManageEntity> {
* 订餐详细配置
*/
@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<WalletAlias> walletAliasList;
/**
@@ -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 字段类型处理器。
*
* <p>MyBatis-Plus 自动结果映射会把字段反射信息传给 Jackson,但 XML 结果映射只会传递
* {@link List} 原始类型。这里为钱包别名列表补充固定元素类型,避免其在不同查询路径下被解析为 Map。</p>
*/
public class MchManageJacksonTypeHandler extends JacksonTypeHandler {
/**
* 钱包别名列表的完整泛型类型,用于兼容 XML 结果映射无法传递字段泛型的场景。
*/
private static final Type WALLET_ALIAS_LIST_TYPE = new TypeReference<List<MchManageEntity.WalletAlias>>() {
}.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;
}
}
@@ -3,6 +3,21 @@
<mapper namespace="com.bsd.pjcloud.wallet.mapper.MchManageMapper">
<!--
自定义 XML 查询不会复用 MchManageEntity 的 autoResultMap,三个 JSON 字段必须显式指定处理器。
其余同名字段继续由 MyBatis 驼峰规则自动映射到 MchManageVo(包括继承自实体的属性)。
-->
<resultMap id="mchManageVoMap" type="com.bsd.pjcloud.wallet.api.vo.MchManageVo" autoMapping="true">
<result column="function_scope" property="functionScope"
javaType="com.bsd.pjcloud.wallet.api.entity.mch.MchManageEntity$FunctionScope"
typeHandler="com.bsd.pjcloud.wallet.api.handler.MchManageJacksonTypeHandler"/>
<result column="table_reservation_conf" property="tableReservationConf"
javaType="com.bsd.pjcloud.wallet.api.entity.mch.MchManageEntity$TableReservationConf"
typeHandler="com.bsd.pjcloud.wallet.api.handler.MchManageJacksonTypeHandler"/>
<result column="wallet_alias_list" property="walletAliasList" javaType="java.util.List"
typeHandler="com.bsd.pjcloud.wallet.api.handler.MchManageJacksonTypeHandler"/>
</resultMap>
<sql id="selectA">
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 @@
</if>
</sql>
<select id="scopePageList" resultType="com.bsd.pjcloud.wallet.api.vo.MchManageVo">
<select id="scopePageList" resultMap="mchManageVoMap">
<include refid="selectA"/>
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
</select>
<select id="scopeList" resultType="com.bsd.pjcloud.wallet.api.vo.MchManageVo">
<select id="scopeList" resultMap="mchManageVoMap">
<include refid="selectA"/>
c.name as catgoryName
from mch_manage a
@@ -123,4 +140,4 @@
</where>
order by a.sort desc , a.dept_id desc , a.create_time desc
</select>
</mapper>
</mapper>
@@ -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());
}
}