mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	基于 Guava 实现 dict 字典数据的本地缓存
This commit is contained in:
		@@ -1,5 +1,8 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.api.dict;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.convert.dict.DictDataConvert;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
@@ -22,4 +25,16 @@ public class DictDataApiImpl implements DictDataApi {
 | 
			
		||||
        dictDataService.validDictDatas(dictType, values);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DictDataRespDTO getDictData(String dictType, String value) {
 | 
			
		||||
        DictDataDO dictData = dictDataService.getDictData(dictType, value);
 | 
			
		||||
        return DictDataConvert.INSTANCE.convert02(dictData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DictDataRespDTO parseDictData(String dictType, String label) {
 | 
			
		||||
        DictDataDO dictData = dictDataService.parseDictData(dictType, label);
 | 
			
		||||
        return DictDataConvert.INSTANCE.convert02(dictData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.convert.dict;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.*;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
 | 
			
		||||
import org.mapstruct.Mapper;
 | 
			
		||||
import org.mapstruct.factory.Mappers;
 | 
			
		||||
 | 
			
		||||
@@ -29,6 +29,4 @@ public interface DictDataConvert {
 | 
			
		||||
 | 
			
		||||
    DictDataRespDTO convert02(DictDataDO bean);
 | 
			
		||||
 | 
			
		||||
    List<DictDataRespDTO> convertList03(Collection<DictDataDO> list);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,9 @@ import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPage
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 | 
			
		||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
import org.apache.ibatis.annotations.Select;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@Mapper
 | 
			
		||||
@@ -23,6 +21,11 @@ public interface DictDataMapper extends BaseMapperX<DictDataDO> {
 | 
			
		||||
                .eq(DictDataDO::getValue, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default DictDataDO selectByDictTypeAndLabel(String dictType, String label) {
 | 
			
		||||
        return selectOne(new LambdaQueryWrapper<DictDataDO>().eq(DictDataDO::getDictType, dictType)
 | 
			
		||||
                .eq(DictDataDO::getLabel, label));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default List<DictDataDO> selectByDictTypeAndValues(String dictType, Collection<String> values) {
 | 
			
		||||
        return selectList(new LambdaQueryWrapper<DictDataDO>().eq(DictDataDO::getDictType, dictType)
 | 
			
		||||
                .in(DictDataDO::getValue, values));
 | 
			
		||||
@@ -46,7 +49,4 @@ public interface DictDataMapper extends BaseMapperX<DictDataDO> {
 | 
			
		||||
                .eqIfPresent(DictDataDO::getStatus, reqVO.getStatus()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Select("SELECT COUNT(*) FROM system_dict_data WHERE update_time > #{maxUpdateTime}")
 | 
			
		||||
    Long selectCountByUpdateTimeGt(Date maxUpdateTime);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.mq.consumer.dict;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
 | 
			
		||||
import cn.iocoder.yudao.module.system.mq.message.dict.DictDataRefreshMessage;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 针对 {@link DictDataRefreshMessage} 的消费者
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class DictDataRefreshConsumer extends AbstractChannelMessageListener<DictDataRefreshMessage> {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private DictDataService dictDataService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onMessage(DictDataRefreshMessage message) {
 | 
			
		||||
        log.info("[onMessage][收到 DictData 刷新消息]");
 | 
			
		||||
        dictDataService.initLocalCache();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.mq.message.dict;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 字典数据数据刷新 Message
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
public class DictDataRefreshMessage extends AbstractChannelMessage {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getChannel() {
 | 
			
		||||
        return "system.dict-data.refresh";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.mq.producer.dict;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.module.system.mq.message.dict.DictDataRefreshMessage;
 | 
			
		||||
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * DictData 字典数据相关消息的 Producer
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
public class DictDataProducer {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private RedisMQTemplate redisMQTemplate;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 发送 {@link DictDataRefreshMessage} 消息
 | 
			
		||||
     */
 | 
			
		||||
    public void sendDictDataRefreshMessage() {
 | 
			
		||||
        DictDataRefreshMessage message = new DictDataRefreshMessage();
 | 
			
		||||
        redisMQTemplate.send(message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +1,11 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.service.dict;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.dict.core.service.DictDataFrameworkService;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataCreateReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataExportReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPageReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataUpdateReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@@ -16,12 +15,7 @@ import java.util.List;
 | 
			
		||||
 *
 | 
			
		||||
 * @author ruoyi
 | 
			
		||||
 */
 | 
			
		||||
public interface DictDataService extends DictDataFrameworkService {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 初始化字典数据的本地缓存
 | 
			
		||||
     */
 | 
			
		||||
    void initLocalCache();
 | 
			
		||||
public interface DictDataService {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 创建字典数据
 | 
			
		||||
@@ -94,4 +88,21 @@ public interface DictDataService extends DictDataFrameworkService {
 | 
			
		||||
     */
 | 
			
		||||
    void validDictDatas(String dictType, Collection<String> values);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获得指定的字典数据
 | 
			
		||||
     *
 | 
			
		||||
     * @param dictType 字典类型
 | 
			
		||||
     * @param value 字典数据值
 | 
			
		||||
     * @return 字典数据
 | 
			
		||||
     */
 | 
			
		||||
    DictDataDO getDictData(String dictType, String value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 解析获得指定的字典数据,从缓存中
 | 
			
		||||
     *
 | 
			
		||||
     * @param dictType 字典类型
 | 
			
		||||
     * @param label 字典数据标签
 | 
			
		||||
     * @return 字典数据
 | 
			
		||||
     */
 | 
			
		||||
    DictDataDO parseDictData(String dictType, String label);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 | 
			
		||||
import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataCreateReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataExportReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPageReqVO;
 | 
			
		||||
@@ -13,20 +12,15 @@ import cn.iocoder.yudao.module.system.convert.dict.DictDataConvert;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
 | 
			
		||||
import cn.iocoder.yudao.module.system.mq.producer.dict.DictDataProducer;
 | 
			
		||||
import com.google.common.annotations.VisibleForTesting;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import com.google.common.collect.ImmutableTable;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.scheduling.annotation.Scheduled;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
			
		||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 | 
			
		||||
@@ -47,88 +41,12 @@ public class DictDataServiceImpl implements DictDataService {
 | 
			
		||||
            .comparing(DictDataDO::getDictType)
 | 
			
		||||
            .thenComparingInt(DictDataDO::getSort);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
 | 
			
		||||
     * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
 | 
			
		||||
     */
 | 
			
		||||
    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private DictTypeService dictTypeService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private DictDataMapper dictDataMapper;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private DictDataProducer dictDataProducer;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 字典数据缓存,第二个 key 使用 label
 | 
			
		||||
     *
 | 
			
		||||
     * key1:字典类型 dictType
 | 
			
		||||
     * key2:字典标签 label
 | 
			
		||||
     */
 | 
			
		||||
    private ImmutableTable<String, String, DictDataDO> labelDictDataCache;
 | 
			
		||||
    /**
 | 
			
		||||
     * 字典数据缓存,第二个 key 使用 value
 | 
			
		||||
     *
 | 
			
		||||
     * key1:字典类型 dictType
 | 
			
		||||
     * key2:字典值 value
 | 
			
		||||
     */
 | 
			
		||||
    private ImmutableTable<String, String, DictDataDO> valueDictDataCache;
 | 
			
		||||
    /**
 | 
			
		||||
     * 缓存字典数据的最大更新时间,用于后续的增量轮询,判断是否有更新
 | 
			
		||||
     */
 | 
			
		||||
    private volatile Date maxUpdateTime;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @PostConstruct
 | 
			
		||||
    public synchronized void initLocalCache() {
 | 
			
		||||
        // 获取字典数据列表,如果有更新
 | 
			
		||||
        List<DictDataDO> dataList = loadDictDataIfUpdate(maxUpdateTime);
 | 
			
		||||
        if (CollUtil.isEmpty(dataList)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 构建缓存
 | 
			
		||||
        ImmutableTable.Builder<String, String, DictDataDO> labelDictDataBuilder = ImmutableTable.builder();
 | 
			
		||||
        ImmutableTable.Builder<String, String, DictDataDO> valueDictDataBuilder = ImmutableTable.builder();
 | 
			
		||||
        dataList.forEach(dictData -> {
 | 
			
		||||
            labelDictDataBuilder.put(dictData.getDictType(), dictData.getLabel(), dictData);
 | 
			
		||||
            valueDictDataBuilder.put(dictData.getDictType(), dictData.getValue(), dictData);
 | 
			
		||||
        });
 | 
			
		||||
        labelDictDataCache = labelDictDataBuilder.build();
 | 
			
		||||
        valueDictDataCache = valueDictDataBuilder.build();
 | 
			
		||||
        maxUpdateTime = CollectionUtils.getMaxValue(dataList, DictDataDO::getUpdateTime);
 | 
			
		||||
        log.info("[initLocalCache][缓存字典数据,数量为:{}]", dataList.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 如果字典数据发生变化,从数据库中获取最新的全量字典数据。
 | 
			
		||||
     * 如果未发生变化,则返回空
 | 
			
		||||
     *
 | 
			
		||||
     * @param maxUpdateTime 当前字典数据的最大更新时间
 | 
			
		||||
     * @return 字典数据列表
 | 
			
		||||
     */
 | 
			
		||||
    private List<DictDataDO> loadDictDataIfUpdate(Date maxUpdateTime) {
 | 
			
		||||
        // 第一步,判断是否要更新。
 | 
			
		||||
        if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
 | 
			
		||||
            log.info("[loadDictDataIfUpdate][首次加载全量字典数据]");
 | 
			
		||||
        } else { // 判断数据库中是否有更新的字典数据
 | 
			
		||||
            if (dictDataMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            log.info("[loadDictDataIfUpdate][增量加载全量字典数据]");
 | 
			
		||||
        }
 | 
			
		||||
        // 第二步,如果有更新,则从数据库加载所有字典数据
 | 
			
		||||
        return dictDataMapper.selectList();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
 | 
			
		||||
    public void schedulePeriodicRefresh() {
 | 
			
		||||
        initLocalCache();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<DictDataDO> getDictDatas() {
 | 
			
		||||
        List<DictDataDO> list = dictDataMapper.selectList();
 | 
			
		||||
@@ -153,16 +71,6 @@ public class DictDataServiceImpl implements DictDataService {
 | 
			
		||||
        return dictDataMapper.selectById(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DictDataRespDTO getDictDataFromCache(String type, String value) {
 | 
			
		||||
        return DictDataConvert.INSTANCE.convert02(valueDictDataCache.get(type, value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DictDataRespDTO parseDictDataFromCache(String type, String label) {
 | 
			
		||||
        return DictDataConvert.INSTANCE.convert02(labelDictDataCache.get(type, label));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Long createDictData(DictDataCreateReqVO reqVO) {
 | 
			
		||||
        // 校验正确性
 | 
			
		||||
@@ -171,9 +79,6 @@ public class DictDataServiceImpl implements DictDataService {
 | 
			
		||||
        // 插入字典类型
 | 
			
		||||
        DictDataDO dictData = DictDataConvert.INSTANCE.convert(reqVO);
 | 
			
		||||
        dictDataMapper.insert(dictData);
 | 
			
		||||
 | 
			
		||||
        // 发送刷新消息
 | 
			
		||||
        dictDataProducer.sendDictDataRefreshMessage();
 | 
			
		||||
        return dictData.getId();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -185,9 +90,6 @@ public class DictDataServiceImpl implements DictDataService {
 | 
			
		||||
        // 更新字典类型
 | 
			
		||||
        DictDataDO updateObj = DictDataConvert.INSTANCE.convert(reqVO);
 | 
			
		||||
        dictDataMapper.updateById(updateObj);
 | 
			
		||||
 | 
			
		||||
        // 发送刷新消息
 | 
			
		||||
        dictDataProducer.sendDictDataRefreshMessage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -197,9 +99,6 @@ public class DictDataServiceImpl implements DictDataService {
 | 
			
		||||
 | 
			
		||||
        // 删除字典数据
 | 
			
		||||
        dictDataMapper.deleteById(id);
 | 
			
		||||
 | 
			
		||||
        // 发送刷新消息
 | 
			
		||||
        dictDataProducer.sendDictDataRefreshMessage();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -259,7 +158,8 @@ public class DictDataServiceImpl implements DictDataService {
 | 
			
		||||
        if (CollUtil.isEmpty(values)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        ImmutableMap<String, DictDataDO> dictDataMap = valueDictDataCache.row(dictType);
 | 
			
		||||
        Map<String, DictDataDO> dictDataMap = CollectionUtils.convertMap(
 | 
			
		||||
                dictDataMapper.selectByDictTypeAndValues(dictType, values), DictDataDO::getValue);
 | 
			
		||||
        // 校验
 | 
			
		||||
        values.forEach(value -> {
 | 
			
		||||
            DictDataDO dictData = dictDataMap.get(value);
 | 
			
		||||
@@ -272,4 +172,14 @@ public class DictDataServiceImpl implements DictDataService {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DictDataDO getDictData(String dictType, String value) {
 | 
			
		||||
        return dictDataMapper.selectByDictTypeAndValue(dictType, value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DictDataDO parseDictData(String dictType, String label) {
 | 
			
		||||
        return dictDataMapper.selectByDictTypeAndLabel(dictType, label);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user