You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by zh...@apache.org on 2022/06/05 12:05:40 UTC

[incubator-shenyu] branch master updated: [ISSUE #3221]record log in dict (#3488)

This is an automated email from the ASF dual-hosted git repository.

zhangzicheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 55037b8e9 [ISSUE #3221]record log in dict (#3488)
55037b8e9 is described below

commit 55037b8e93bd0e308b372f071624f5c9f5c33c73
Author: likeguo <33...@users.noreply.github.com>
AuthorDate: Sun Jun 5 20:05:34 2022 +0800

    [ISSUE #3221]record log in dict (#3488)
    
    * fixbug/pg script error
    
    * feature/record log in dict
---
 .../shenyu/admin/mapper/ShenyuDictMapper.java      |  8 ++
 .../shenyu/admin/model/enums/EventTypeEnum.java    | 17 ++++-
 .../model/event/dict/BatchDictChangedEvent.java    | 58 ++++++++++++++
 .../model/event/dict/BatchDictDeletedEvent.java    | 67 ++++++++++++++++
 .../admin/model/event/dict/DictChangedEvent.java   | 88 ++++++++++++++++++++++
 .../admin/model/event/dict/DictCreatedEvent.java   | 48 ++++++++++++
 .../admin/model/event/dict/DictUpdatedEvent.java   | 49 ++++++++++++
 .../admin/service/impl/ShenyuDictServiceImpl.java  | 67 +++++++++++-----
 .../admin/service/publish/DictEventPublisher.java  | 85 +++++++++++++++++++++
 .../main/resources/mappers/shenyu-dict-sqlmap.xml  | 10 +++
 .../admin/service/ShenyuDictServiceTest.java       |  8 +-
 11 files changed, 483 insertions(+), 22 deletions(-)

diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ShenyuDictMapper.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ShenyuDictMapper.java
index ee69a6fb0..3e7e24b80 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ShenyuDictMapper.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ShenyuDictMapper.java
@@ -146,4 +146,12 @@ public interface ShenyuDictMapper extends ExistProvider {
      * @return affected rows
      */
     Integer enabled(@Param("ids") List<String> ids, @Param("enabled") Boolean enabled);
+    
+    /**
+     * select by ids.
+     *
+     * @param ids ids
+     * @return list
+     */
+    List<ShenyuDictDO> selectByIds(@Param("ids") List<String> ids);
 }
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java
index 9a8938b6b..ce756ecad 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/enums/EventTypeEnum.java
@@ -65,6 +65,11 @@ public enum EventTypeEnum {
      */
     RESOURCE_CREATE("CREATE:RESOURCE", DataEventTypeEnum.CREATE, Color.CREATE_COLOR),
     
+    /**
+     * dict created event.
+     */
+    DICT_CREATE("CREATE:DICT", DataEventTypeEnum.CREATE, Color.CREATE_COLOR),
+    
     // ============== delete ===================
     /**
      * deleted event.
@@ -107,6 +112,11 @@ public enum EventTypeEnum {
      */
     RESOURCE_DELETE("DELETE:RESOURCE", DataEventTypeEnum.DELETE, Color.DELETE_COLOR),
     
+    /**
+     * dict deleted event.
+     */
+    DICT_DELETE("DELETE:DICT", DataEventTypeEnum.DELETE, Color.DELETE_COLOR),
+    
     // ============== update ===================
     
     /**
@@ -142,7 +152,12 @@ public enum EventTypeEnum {
     /**
      * resource update.
      */
-    RESOURCE_UPDATE("UPDATE:RESOURCE", DataEventTypeEnum.UPDATE, Color.UPDATE_COLOR);
+    RESOURCE_UPDATE("UPDATE:RESOURCE", DataEventTypeEnum.UPDATE, Color.UPDATE_COLOR),
+    
+    /**
+     * dict update.
+     */
+    DICT_UPDATE("UPDATE:DICT", DataEventTypeEnum.UPDATE, Color.UPDATE_COLOR);
     
     /**
      * type name.
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/BatchDictChangedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/BatchDictChangedEvent.java
new file mode 100644
index 000000000..84f45de7b
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/BatchDictChangedEvent.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.model.event.dict;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.entity.ShenyuDictDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+import org.apache.shenyu.admin.model.event.BatchChangedEvent;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * BatchDictChangedEvent.
+ */
+public class BatchDictChangedEvent extends BatchChangedEvent {
+    
+    
+    /**
+     * Create a new {@code BatchDictChangedEvent}.operator is unknown.
+     *
+     * @param source Current dict state
+     * @param before Before the change dict state
+     * @param type   event type
+     */
+    public BatchDictChangedEvent(final Collection<ShenyuDictDO> source, final Collection<ShenyuDictDO> before, final EventTypeEnum type, final String operator) {
+        super(source, before, type, operator);
+    }
+    
+    @Override
+    public String buildContext() {
+        final String plugins = ((Collection<?>) getSource())
+                .stream()
+                .map(s -> ((ShenyuDictDO) s).getDictName())
+                .collect(Collectors.joining(","));
+        return String.format("the shenyu dict[%s] is %s", plugins, StringUtils.lowerCase(getType().getType().toString()));
+    }
+    
+    @Override
+    public String eventName() {
+        return "dict";
+    }
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/BatchDictDeletedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/BatchDictDeletedEvent.java
new file mode 100644
index 000000000..51546db9e
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/BatchDictDeletedEvent.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.model.event.dict;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.entity.BaseDO;
+import org.apache.shenyu.admin.model.entity.ShenyuDictDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+import org.apache.shenyu.admin.utils.ListUtil;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * BatchPluginDeletedEvent.
+ */
+public class BatchDictDeletedEvent extends BatchDictChangedEvent {
+    
+    private final List<String> deletedIds;
+    
+    /**
+     * Create a new {@code PluginChangedEvent}.operator is unknown.
+     *
+     * @param source   Current plugin state
+     * @param operator operator
+     */
+    public BatchDictDeletedEvent(final Collection<ShenyuDictDO> source, final String operator) {
+        super(source, null, EventTypeEnum.DICT_DELETE, operator);
+        this.deletedIds = ListUtil.map(source, BaseDO::getId);
+    }
+    
+    @Override
+    public String buildContext() {
+        final String data = ((Collection<?>) getSource())
+                .stream()
+                .map(s -> ((ShenyuDictDO) s).getDictName())
+                .collect(Collectors.joining(","));
+        return String.format("the dict[%s] is %s", data, StringUtils.lowerCase(getType().getType().toString()));
+    }
+    
+
+    
+    /**
+     * get deleted iss.
+     *
+     * @return list
+     */
+    public List<String> getDeletedIds() {
+        return deletedIds;
+    }
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictChangedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictChangedEvent.java
new file mode 100644
index 000000000..164d789d8
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictChangedEvent.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.model.event.dict;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.entity.ShenyuDictDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+import org.apache.shenyu.admin.model.event.AdminDataModelChangedEvent;
+
+import java.util.Objects;
+
+/**
+ * DictChangedEvent.
+ */
+public class DictChangedEvent extends AdminDataModelChangedEvent {
+    
+    
+    /**
+     * Create a new {@code DictChangedEvent}.operator is unknown.
+     *
+     * @param source Current dict state
+     * @param before Before the change dict state
+     * @param type   event type
+     */
+    public DictChangedEvent(final ShenyuDictDO source, final ShenyuDictDO before, final EventTypeEnum type, final String operator) {
+        super(source, before, type, operator);
+    }
+    
+    @Override
+    public String buildContext() {
+        final ShenyuDictDO after = (ShenyuDictDO) getAfter();
+        if (Objects.isNull(getBefore())) {
+            return String.format("the dict [%s] is %s", after.getDictName(), StringUtils.lowerCase(getType().getType().toString()));
+        }
+        return String.format("the dict [%s] is %s : %s", after.getDictName(), StringUtils.lowerCase(getType().getType().toString()), contrast());
+        
+    }
+    
+    private String contrast() {
+        final ShenyuDictDO before = (ShenyuDictDO) getBefore();
+        Objects.requireNonNull(before);
+        final ShenyuDictDO after = (ShenyuDictDO) getAfter();
+        Objects.requireNonNull(after);
+        if (Objects.equals(before, after)) {
+            return "it no change";
+        }
+        final StringBuilder builder = new StringBuilder();
+        if (!Objects.equals(before.getDictName(), after.getDictName())) {
+            builder.append(String.format("name[%s => %s] ", before.getDictName(), after.getDictName()));
+        }
+        if (!Objects.equals(before.getDictValue(), after.getDictValue())) {
+            builder.append(String.format("value[%s => %s] ", before.getDictValue(), after.getDictValue()));
+        }
+        if (!Objects.equals(before.getDesc(), after.getDesc())) {
+            builder.append(String.format("desc[%s => %s] ", before.getDesc(), after.getDesc()));
+        }
+        if (!Objects.equals(before.getType(), after.getType())) {
+            builder.append(String.format("type[%s => %s] ", before.getType(), after.getType()));
+        }
+        if (!Objects.equals(before.getEnabled(), after.getEnabled())) {
+            builder.append(String.format("enable[%s => %s] ", before.getEnabled(), after.getEnabled()));
+        }
+        if (!Objects.equals(before.getSort(), after.getSort())) {
+            builder.append(String.format("sort[%s => %s] ", before.getSort(), after.getSort()));
+        }
+        return builder.toString();
+    }
+    
+    @Override
+    public String eventName() {
+        return "dict";
+    }
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictCreatedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictCreatedEvent.java
new file mode 100644
index 000000000..42efbaf0b
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictCreatedEvent.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.model.event.dict;
+
+import org.apache.shenyu.admin.model.entity.ShenyuDictDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+
+/**
+ * DictCreatedEvent.
+ */
+public class DictCreatedEvent extends DictChangedEvent {
+    
+    
+    /**
+     * Create a new {@code DictCreatedEvent}.operator is unknown.
+     *
+     * @param source   Current dict state
+     * @param operator operator
+     */
+    public DictCreatedEvent(final ShenyuDictDO source, final String operator) {
+        super(source, null, EventTypeEnum.DICT_CREATE, operator);
+    }
+    
+    /**
+     * the created dict.
+     *
+     * @return dict
+     */
+    public ShenyuDictDO getDict() {
+        return (ShenyuDictDO) getSource();
+    }
+    
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictUpdatedEvent.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictUpdatedEvent.java
new file mode 100644
index 000000000..0b1cd2de6
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/event/dict/DictUpdatedEvent.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.model.event.dict;
+
+import org.apache.shenyu.admin.model.entity.ShenyuDictDO;
+import org.apache.shenyu.admin.model.enums.EventTypeEnum;
+
+/**
+ * DictUpdatedEvent.
+ */
+public class DictUpdatedEvent extends DictChangedEvent {
+    
+    
+    /**
+     * Create a new {@code DictUpdatedEvent}.operator is unknown.
+     *
+     * @param source   Current dict state
+     * @param before   before dict state
+     * @param operator operator
+     */
+    public DictUpdatedEvent(final ShenyuDictDO source, final ShenyuDictDO before, final String operator) {
+        super(source, before, EventTypeEnum.DICT_UPDATE, operator);
+    }
+    
+    /**
+     * the update dict.
+     *
+     * @return dict
+     */
+    public ShenyuDictDO getDict() {
+        return (ShenyuDictDO) getSource();
+    }
+    
+}
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ShenyuDictServiceImpl.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ShenyuDictServiceImpl.java
index 624add4de..66ddd7c06 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ShenyuDictServiceImpl.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ShenyuDictServiceImpl.java
@@ -27,6 +27,8 @@ import org.apache.shenyu.admin.model.page.PageResultUtils;
 import org.apache.shenyu.admin.model.query.ShenyuDictQuery;
 import org.apache.shenyu.admin.model.vo.ShenyuDictVO;
 import org.apache.shenyu.admin.service.ShenyuDictService;
+import org.apache.shenyu.admin.service.publish.DictEventPublisher;
+import org.apache.shenyu.admin.utils.Assert;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -38,52 +40,77 @@ import java.util.stream.Collectors;
  */
 @Service
 public class ShenyuDictServiceImpl implements ShenyuDictService {
-
+    
     private final ShenyuDictMapper shenyuDictMapper;
-
-    public ShenyuDictServiceImpl(final ShenyuDictMapper shenyuDictMapper) {
+    
+    private final DictEventPublisher publisher;
+    
+    public ShenyuDictServiceImpl(final ShenyuDictMapper shenyuDictMapper, final DictEventPublisher publisher) {
         this.shenyuDictMapper = shenyuDictMapper;
+        this.publisher = publisher;
     }
-
+    
     @Override
     @Pageable
     public CommonPager<ShenyuDictVO> listByPage(final ShenyuDictQuery shenyuDictQuery) {
-        return PageResultUtils.result(shenyuDictQuery.getPageParameter(),
-            () -> shenyuDictMapper.selectByQuery(shenyuDictQuery)
-                        .stream()
-                        .map(ShenyuDictVO::buildShenyuDictVO)
-                        .collect(Collectors.toList()));
+        return PageResultUtils.result(shenyuDictQuery.getPageParameter(), () -> shenyuDictMapper.selectByQuery(shenyuDictQuery)
+                .stream()
+                .map(ShenyuDictVO::buildShenyuDictVO)
+                .collect(Collectors.toList()));
     }
-
+    
     @Override
     public Integer createOrUpdate(final ShenyuDictDTO shenyuDictDTO) {
-        return StringUtils.isBlank(shenyuDictDTO.getId())
-                ? shenyuDictMapper.insertSelective(ShenyuDictDO.buildShenyuDictDO(shenyuDictDTO))
-                : shenyuDictMapper.updateByPrimaryKeySelective(ShenyuDictDO.buildShenyuDictDO(shenyuDictDTO));
+        return StringUtils.isBlank(shenyuDictDTO.getId()) ? create(shenyuDictDTO) : update(shenyuDictDTO);
     }
-
+    
+    private int update(final ShenyuDictDTO shenyuDictDTO) {
+        final ShenyuDictDO before = shenyuDictMapper.selectById(shenyuDictDTO.getId());
+        Assert.notNull(before, "the dict is not existed");
+        final ShenyuDictDO dict = ShenyuDictDO.buildShenyuDictDO(shenyuDictDTO);
+        final int changeCount = shenyuDictMapper.updateByPrimaryKeySelective(dict);
+        if (changeCount > 0) {
+            publisher.onUpdated(dict, before);
+        }
+        return changeCount;
+    }
+    
+    private int create(final ShenyuDictDTO shenyuDictDTO) {
+        final ShenyuDictDO dict = ShenyuDictDO.buildShenyuDictDO(shenyuDictDTO);
+        final int insertCount = shenyuDictMapper.insertSelective(dict);
+        if (insertCount > 0) {
+            publisher.onCreated(dict);
+        }
+        return insertCount;
+    }
+    
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Integer deleteShenyuDicts(final List<String> ids) {
-        return shenyuDictMapper.deleteByIdList(ids);
+        final List<ShenyuDictDO> dictList = shenyuDictMapper.selectByIds(ids);
+        final int deleteCount = shenyuDictMapper.deleteByIdList(ids);
+        if (deleteCount > 0) {
+            publisher.onDeleted(dictList);
+        }
+        return deleteCount;
     }
-
+    
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Integer enabled(final List<String> ids, final Boolean enabled) {
         return shenyuDictMapper.enabled(ids, enabled);
     }
-
+    
     @Override
     public ShenyuDictVO findById(final String id) {
         return ShenyuDictVO.buildShenyuDictVO(shenyuDictMapper.selectById(id));
     }
-
+    
     @Override
     public ShenyuDictVO findByDictCodeName(final String dictCode, final String dictName) {
         return ShenyuDictVO.buildShenyuDictVO(shenyuDictMapper.selectByDictCodeAndDictName(dictCode, dictName));
     }
-
+    
     @Override
     public List<ShenyuDictVO> list(final String type) {
         ShenyuDictQuery shenyuDictQuery = new ShenyuDictQuery();
@@ -92,5 +119,5 @@ public class ShenyuDictServiceImpl implements ShenyuDictService {
                 .map(ShenyuDictVO::buildShenyuDictVO)
                 .collect(Collectors.toList());
     }
-
+    
 }
diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/publish/DictEventPublisher.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/publish/DictEventPublisher.java
new file mode 100644
index 000000000..f994f65c1
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/publish/DictEventPublisher.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.service.publish;
+
+import org.apache.shenyu.admin.model.entity.ShenyuDictDO;
+import org.apache.shenyu.admin.model.event.AdminDataModelChangedEvent;
+import org.apache.shenyu.admin.model.event.dict.BatchDictDeletedEvent;
+import org.apache.shenyu.admin.model.event.dict.DictCreatedEvent;
+import org.apache.shenyu.admin.model.event.dict.DictUpdatedEvent;
+import org.apache.shenyu.admin.utils.SessionUtil;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+
+/**
+ * DictEventPublisher.
+ */
+@Component
+public class DictEventPublisher implements AdminDataModelChangedEventPublisher<ShenyuDictDO> {
+    
+    private final ApplicationEventPublisher publisher;
+    
+    public DictEventPublisher(final ApplicationEventPublisher publisher) {
+        this.publisher = publisher;
+    }
+    
+    /**
+     * on selector created.
+     *
+     * @param data dict
+     */
+    @Override
+    public void onCreated(final ShenyuDictDO data) {
+        publish(new DictCreatedEvent(data, SessionUtil.visitorName()));
+    }
+    
+    /**
+     * on selector updated.
+     *
+     * @param selector selector
+     * @param before   before selector
+     */
+    @Override
+    public void onUpdated(final ShenyuDictDO selector, final ShenyuDictDO before) {
+        publish(new DictUpdatedEvent(selector, before, SessionUtil.visitorName()));
+    }
+    
+    
+    /**
+     * on dict deleted.
+     *
+     * @param dict dict
+     */
+    @Override
+    public void onDeleted(final Collection<ShenyuDictDO> dict) {
+        publish(new BatchDictDeletedEvent(dict, SessionUtil.visitorName()));
+        
+    }
+    
+    /**
+     * event.
+     *
+     * @param event event.
+     */
+    @Override
+    public void publish(final AdminDataModelChangedEvent event) {
+        publisher.publishEvent(event);
+    }
+}
diff --git a/shenyu-admin/src/main/resources/mappers/shenyu-dict-sqlmap.xml b/shenyu-admin/src/main/resources/mappers/shenyu-dict-sqlmap.xml
index 7fa7f0438..24fc29cc5 100644
--- a/shenyu-admin/src/main/resources/mappers/shenyu-dict-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/shenyu-dict-sqlmap.xml
@@ -273,6 +273,16 @@
          LIMIT 1
     </select>
 
+    <select id="selectByIds" resultType="org.apache.shenyu.admin.model.entity.ShenyuDictDO">
+        SELECT
+        <include refid="Base_Column_List"/>
+        FROM shenyu_dict
+        WHERE id IN
+        <foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
+
     <update id="enabled">
         UPDATE shenyu_dict
            SET enabled = #{enabled, jdbcType=TINYINT}
diff --git a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ShenyuDictServiceTest.java b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ShenyuDictServiceTest.java
index a1037c26b..786805df3 100644
--- a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ShenyuDictServiceTest.java
+++ b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ShenyuDictServiceTest.java
@@ -27,6 +27,7 @@ import org.apache.shenyu.admin.model.page.PageParameter;
 import org.apache.shenyu.admin.model.query.ShenyuDictQuery;
 import org.apache.shenyu.admin.model.vo.ShenyuDictVO;
 import org.apache.shenyu.admin.service.impl.ShenyuDictServiceImpl;
+import org.apache.shenyu.admin.service.publish.DictEventPublisher;
 import org.apache.shenyu.common.utils.UUIDUtils;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -61,6 +62,9 @@ public final class ShenyuDictServiceTest {
 
     @Mock
     private ShenyuDictMapper shenyuDictMapper;
+    
+    @Mock
+    private DictEventPublisher publisher;
 
     @Test
     public void testFindByType() {
@@ -85,8 +89,10 @@ public final class ShenyuDictServiceTest {
         ShenyuDictDTO insertShenyuDictDTO = buildShenyuDictDTO();
         given(this.shenyuDictMapper.insertSelective(any())).willReturn(1);
         assertThat(this.shenyuDictService.createOrUpdate(insertShenyuDictDTO), greaterThan(0));
-        ShenyuDictDTO updateShenyuDictDTO = buildShenyuDictDTO(UUIDUtils.getInstance().generateShortUuid());
+        final String id = UUIDUtils.getInstance().generateShortUuid();
+        ShenyuDictDTO updateShenyuDictDTO = buildShenyuDictDTO(id);
         given(this.shenyuDictMapper.updateByPrimaryKeySelective(any())).willReturn(1);
+        given(this.shenyuDictMapper.selectById(id)).willReturn(new ShenyuDictDO());
         assertThat(this.shenyuDictService.createOrUpdate(updateShenyuDictDTO), greaterThan(0));
     }