@@ -185,6 +191,10 @@
                 
                 SEC080aac67ff78e79fdaba132aa51e3fb3f6060dec99492feaac82cabf9f8b6a19
                  
+
+                
+                192.168.1.130:9876;192.168.1.132:9876 
+                epmet_message 
             
         
         
@@ -237,6 +247,9 @@
                 
                 SEC080aac67ff78e79fdaba132aa51e3fb3f6060dec99492feaac82cabf9f8b6a19
                  
+                
+                192.168.1.130:9876;192.168.1.132:9876 
+                epmet_message 
             
          
         
@@ -288,6 +301,10 @@
                 
                 SEC080aac67ff78e79fdaba132aa51e3fb3f6060dec99492feaac82cabf9f8b6a19
                  
+
+                
+                192.168.10.161:9876 
+                epmet_message 
             
          
         
@@ -336,6 +353,10 @@
                 
                 SEC95f4f40b533ad379ea6a6d1af6dd37029383cfe1b7cd96dfac2678be2c1c3ed1
                  
+
+                
+                192.168.11.187:9876;192.168.11.184:9876 
+                epmet_message 
             
          
     
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementConfigDao.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementConfigDao.java
index 24d35a5edd..b53a2cf69c 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementConfigDao.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementConfigDao.java
@@ -1,4 +1,4 @@
-/**
+package com.epmet.modules.group.dao; /**
  * Copyright 2018 人人开源 https://www.renren.io
  * 
  * This program is free software: you can redistribute it and/or modify
@@ -15,11 +15,14 @@
  * along with this program.  If not, see  .
  */
 
-package com.epmet.modules.group.dao;
+
 
 import com.epmet.commons.mybatis.dao.BaseDao;
 import com.epmet.modules.group.entity.ResiGroupAchievementConfigEntity;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 小组成就配置表
@@ -29,5 +32,26 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface ResiGroupAchievementConfigDao extends BaseDao {
-	
-}
\ No newline at end of file
+
+    /**
+     * desc: 获取成就配置 比targetValue
+     *
+     * @param achievementType
+     * @param offset
+     * @param pageSize
+     * @return java.util.List
+     * @author LiuJanJun
+     * @date 2021/4/21 10:04 下午
+     */
+    List selectMoreThanOneByValue(@Param("achievementType") String achievementType, @Param("offset") int offset, @Param("pageSize") int pageSize);
+
+    /**
+     * desc: 获取最后一条配置
+     *
+     * @param achievementType
+     * @return com.epmet.modules.group.entity.ResiGroupAchievementConfigEntity
+     * @author LiuJanJun
+     * @date 2021/4/22 1:58 下午
+     */
+    ResiGroupAchievementConfigEntity getLastOne(@Param("achievementType") String achievementType);
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementStatsDao.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementStatsDao.java
index 0de55fe72e..247c371ed6 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementStatsDao.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/dao/ResiGroupAchievementStatsDao.java
@@ -35,10 +35,34 @@ import java.util.List;
 public interface ResiGroupAchievementStatsDao extends BaseDao {
 	/**
 	 * 获取未完成的成就
-	 * @author zhaoqifeng
-	 * @date 2021/4/19 15:52
+	 *
 	 * @param groupId
 	 * @return java.util.List
+	 * @author zhaoqifeng
+	 * @date 2021/4/19 15:52
 	 */
 	List selectUnAchieved(@Param("groupId") String groupId);
-}
\ No newline at end of file
+
+	/**
+	 * desc: 获取最后一个为实现的成就
+	 *
+	 * @param customerId
+	 * @param groupId
+	 * @param achievementType
+	 * @return com.epmet.modules.group.entity.ResiGroupAchievementStatsEntity
+	 * @author LiuJanJun
+	 * @date 2021/4/21 8:34 下午
+	 */
+	ResiGroupAchievementStatsEntity selectLastUnAchieved(@Param("customerId") String customerId, @Param("groupId") String groupId, @Param("achievementType") String achievementType);
+
+	/**
+	 * desc: 插入或更新成就
+	 *
+	 * @param haveArrive
+	 * @param updateAll
+	 * @return int
+	 * @author LiuJanJun
+	 * @date 2021/4/22 3:03 下午
+	 */
+	int saveOrUpdate(@Param("list") List list, @Param("updateAll") boolean updateAll);
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/entity/ResiGroupAchievementStatsEntity.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/entity/ResiGroupAchievementStatsEntity.java
index 8710dc43d9..3559786095 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/entity/ResiGroupAchievementStatsEntity.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/entity/ResiGroupAchievementStatsEntity.java
@@ -49,15 +49,20 @@ public class ResiGroupAchievementStatsEntity extends BaseEpmetEntity {
 	private String groupId;
 
     /**
-     * 里程ID
+     * 成就ID
      */
 	private String achievementId;
 
     /**
-     * 里程名称
+     * 成就名称
      */
 	private String achievementName;
 
+	/**
+	 * 成就类型
+	 */
+	private String achievementType;
+
     /**
      * 实现时间
      */
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/AbstractStatsAchievementService.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/AbstractStatsAchievementService.java
new file mode 100644
index 0000000000..818937dcf6
--- /dev/null
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/AbstractStatsAchievementService.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright 2018 人人开源 https://www.renren.io
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see  .
+ */
+
+package com.epmet.modules.group.service;
+
+import com.epmet.commons.tools.constant.NumConstant;
+import com.epmet.commons.tools.constant.StrConstant;
+import com.epmet.commons.tools.exception.EpmetErrorCode;
+import com.epmet.commons.tools.exception.RenException;
+import com.epmet.modules.enums.AchievementTypeEnum;
+import com.epmet.modules.group.entity.ResiGroupAchievementConfigEntity;
+import com.epmet.modules.support.GroupAchievementUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * desc:实时计算小组成就完成情况
+ *
+ * @author generator generator@elink-cn.com
+ * @since v1.0.0 2021-04-19
+ */
+public abstract class AbstractStatsAchievementService {
+
+    @Autowired
+    public ResiGroupAchievementConfigService achievementConfigService;
+    @Autowired
+    public ResiGroupAchievementStatsService achievementStatsService;
+
+
+    /**
+     * desc: 根据成绩类型 分页获取成就配置 按targetValue 升序
+     *
+     * @param offset
+     * @param pageSize
+     * @return java.util.List
+     * @author LiuJanJun
+     * @date 2021/4/22 1:36 下午
+     */
+    /**
+     * desc: 根据成绩类型 分页获取成就配置 按targetValue 升序
+     *
+     * @param pageNum
+     * @param pageSize
+     * @return java.util.List
+     * @author LiuJanJun
+     * @date 2021/4/22 1:36 下午
+     */
+    protected List getAchievemnetConfigPage(int pageNum, int pageSize, String achievementType) {
+        return achievementConfigService.selectMoreThanOneByValue(achievementType, (pageNum - NumConstant.ONE) * pageSize, pageSize);
+    }
+
+    /**
+     * desc:初始化配置5条
+     *
+     * @param achievementType
+     * @return
+     */
+    protected List initAchievementConfig(String achievementType) {
+        AchievementTypeEnum anEnum = AchievementTypeEnum.getEnum(achievementType);
+        if (anEnum == null) {
+            throw new RenException(EpmetErrorCode.INTERNAL_VALIDATE_ERROR.getCode());
+        }
+        if (AchievementTypeEnum.MEMBER.getCode().equals(anEnum.getCode())) {
+            throw new RenException("小组人数都到10000啦?");
+        }
+        ResiGroupAchievementConfigEntity lastOne = achievementConfigService.getLastOne(achievementType);
+        List newConfigList = new ArrayList<>();
+        Integer nextTargetValue = null;
+        int preValue = lastOne.getTargetValue();
+        String oldName = lastOne.getAchievementName().replace(String.valueOf(lastOne.getTargetValue()), StrConstant.UNDER_LINE);
+        for (int i = 0; i < 5; i++) {
+            nextTargetValue = GroupAchievementUtils.getNextTargetValue(achievementType, preValue);
+            ResiGroupAchievementConfigEntity next = new ResiGroupAchievementConfigEntity();
+            next.setCustomerId(lastOne.getCustomerId());
+            next.setAchievementName(oldName.replace(StrConstant.UNDER_LINE, String.valueOf(nextTargetValue)));
+            //todo 把这个字段去掉
+            next.setPreValue(preValue);
+            preValue = nextTargetValue;
+            next.setTargetValue(nextTargetValue);
+            next.setAchievementType(lastOne.getAchievementType());
+            newConfigList.add(next);
+        }
+        achievementConfigService.insertBatch(newConfigList);
+        return newConfigList;
+    }
+
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementConfigService.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementConfigService.java
index cb45a821ef..d7de022e82 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementConfigService.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementConfigService.java
@@ -18,12 +18,9 @@
 package com.epmet.modules.group.service;
 
 import com.epmet.commons.mybatis.service.BaseService;
-import com.epmet.commons.tools.page.PageData;
 import com.epmet.modules.group.entity.ResiGroupAchievementConfigEntity;
-import com.epmet.resi.group.dto.group.ResiGroupAchievementConfigDTO;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * 小组成就配置表
@@ -33,63 +30,7 @@ import java.util.Map;
  */
 public interface ResiGroupAchievementConfigService extends BaseService {
 
-    /**
-     * 默认分页
-     *
-     * @param params
-     * @return PageData
-     * @author generator
-     * @date 2021-04-19
-     */
-    PageData page(Map params);
+    ResiGroupAchievementConfigEntity getLastOne(String achievementType);
 
-    /**
-     * 默认查询
-     *
-     * @param params
-     * @return java.util.List
-     * @author generator
-     * @date 2021-04-19
-     */
-    List list(Map params);
-
-    /**
-     * 单条查询
-     *
-     * @param id
-     * @return ResiGroupMilestoneConfigDTO
-     * @author generator
-     * @date 2021-04-19
-     */
-    ResiGroupAchievementConfigDTO get(String id);
-
-    /**
-     * 默认保存
-     *
-     * @param dto
-     * @return void
-     * @author generator
-     * @date 2021-04-19
-     */
-    void save(ResiGroupAchievementConfigDTO dto);
-
-    /**
-     * 默认更新
-     *
-     * @param dto
-     * @return void
-     * @author generator
-     * @date 2021-04-19
-     */
-    void update(ResiGroupAchievementConfigDTO dto);
-
-    /**
-     * 批量删除
-     *
-     * @param ids
-     * @return void
-     * @author generator
-     * @date 2021-04-19
-     */
-    void delete(String[] ids);
-}
\ No newline at end of file
+    List selectMoreThanOneByValue(String achievementType,int offset,int pageSize);
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementStatsService.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementStatsService.java
index 3b71116fea..4fc8370ad9 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementStatsService.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/ResiGroupAchievementStatsService.java
@@ -110,4 +110,27 @@ public interface ResiGroupAchievementStatsService extends BaseService
      */
     List getUnAchieved(String groupId);
-}
\ No newline at end of file
+
+    /**
+     * desc: 获取最后未实现的成就 实际每种类型 数据库只存在一条未实现的成就
+     *
+     * @param customerId
+     * @param groupId
+     * @param achievementType
+     * @return com.epmet.modules.group.entity.ResiGroupAchievementStatsEntity
+     * @author LiuJanJun
+     * @date 2021/4/22 2:35 下午
+     */
+    ResiGroupAchievementStatsEntity selectLastUnAchieved(String customerId, String groupId, String achievementType);
+
+    /**
+     * desc: 插入或更新成就
+     *
+     * @param haveArrive
+     * @param updateAll
+     * @return int
+     * @author LiuJanJun
+     * @date 2021/4/22 3:03 下午
+     */
+    int saveOrUpdate(List haveArrive, boolean updateAll);
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/StatsAchievementService.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/StatsAchievementService.java
new file mode 100644
index 0000000000..7b532f83e0
--- /dev/null
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/StatsAchievementService.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2018 人人开源 https://www.renren.io
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see  .
+ */
+
+package com.epmet.modules.group.service;
+
+/**
+ * desc:实时计算小组成就完成情况
+ *
+ * @author generator generator@elink-cn.com
+ * @since v1.0.0 2021-04-19
+ */
+public interface StatsAchievementService{
+
+    /**
+     * desc: 计算小组成就 统一入口
+     *
+     * @param achievementType 成就类型  小组人数、话题数、转议题数、小组内问题解决数
+     * @return java.lang.Boolean
+     * @author LiuJanJun
+     * @date 2021/4/20
+     */
+    Boolean calculateAcm(String achievementType);
+
+    /**
+     * desc: 根据小组Id计算小组成就 入口
+     *
+     * @param customerId
+     * @param groupId
+     * @param achievementType 成就类型  小组人数、话题数、转议题数、小组内问题解决数
+     * @return java.lang.Boolean
+     * @author LiuJanJun
+     * @date 2021/4/20
+     */
+    Boolean calculateAcm(String customerId, String groupId, String achievementType);
+
+
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementConfigServiceImpl.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementConfigServiceImpl.java
index 42ff9f7288..85a8077e78 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementConfigServiceImpl.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementConfigServiceImpl.java
@@ -17,23 +17,13 @@
 
 package com.epmet.modules.group.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.epmet.commons.mybatis.service.impl.BaseServiceImpl;
-import com.epmet.commons.tools.page.PageData;
-import com.epmet.commons.tools.utils.ConvertUtils;
-import com.epmet.commons.tools.constant.FieldConstant;
 import com.epmet.modules.group.dao.ResiGroupAchievementConfigDao;
 import com.epmet.modules.group.entity.ResiGroupAchievementConfigEntity;
 import com.epmet.modules.group.service.ResiGroupAchievementConfigService;
-import com.epmet.resi.group.dto.group.ResiGroupAchievementConfigDTO;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
 
 /**
  * 小组成就配置表
@@ -44,57 +34,13 @@ import java.util.Map;
 @Service
 public class ResiGroupAchievementConfigServiceImpl extends BaseServiceImpl implements ResiGroupAchievementConfigService {
 
-
     @Override
-    public PageData page(Map params) {
-        IPage page = baseDao.selectPage(
-                getPage(params, FieldConstant.CREATED_TIME, false),
-                getWrapper(params)
-        );
-        return getPageData(page, ResiGroupAchievementConfigDTO.class);
-    }
-
-    @Override
-    public List list(Map params) {
-        List entityList = baseDao.selectList(getWrapper(params));
-
-        return ConvertUtils.sourceToTarget(entityList, ResiGroupAchievementConfigDTO.class);
-    }
-
-    private QueryWrapper getWrapper(Map params){
-        String id = (String)params.get(FieldConstant.ID_HUMP);
-
-        QueryWrapper wrapper = new QueryWrapper<>();
-        wrapper.eq(StringUtils.isNotBlank(id), FieldConstant.ID, id);
-
-        return wrapper;
+    public ResiGroupAchievementConfigEntity getLastOne(String achievementType) {
+        return baseDao.getLastOne(achievementType);
     }
 
     @Override
-    public ResiGroupAchievementConfigDTO get(String id) {
-        ResiGroupAchievementConfigEntity entity = baseDao.selectById(id);
-        return ConvertUtils.sourceToTarget(entity, ResiGroupAchievementConfigDTO.class);
+    public List selectMoreThanOneByValue(String achievementType,int offset,int pageSize) {
+        return baseDao.selectMoreThanOneByValue(achievementType,offset,pageSize);
     }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void save(ResiGroupAchievementConfigDTO dto) {
-        ResiGroupAchievementConfigEntity entity = ConvertUtils.sourceToTarget(dto, ResiGroupAchievementConfigEntity.class);
-        insert(entity);
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void update(ResiGroupAchievementConfigDTO dto) {
-        ResiGroupAchievementConfigEntity entity = ConvertUtils.sourceToTarget(dto, ResiGroupAchievementConfigEntity.class);
-        updateById(entity);
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void delete(String[] ids) {
-        // 逻辑删除(@TableLogic 注解)
-        baseDao.deleteBatchIds(Arrays.asList(ids));
-    }
-
-}
\ No newline at end of file
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementStatsServiceImpl.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementStatsServiceImpl.java
index 46b0fa5303..3e84f116a3 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementStatsServiceImpl.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupAchievementStatsServiceImpl.java
@@ -131,4 +131,14 @@ public class ResiGroupAchievementStatsServiceImpl extends BaseServiceImpl haveArrive, boolean updateAll) {
+        return baseDao.saveOrUpdate(haveArrive, updateAll);
+    }
+
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupServiceImpl.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupServiceImpl.java
index 7b2bdedcab..47c0dc7bf6 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupServiceImpl.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/ResiGroupServiceImpl.java
@@ -21,6 +21,7 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.epmet.commons.mybatis.service.impl.BaseServiceImpl;
+import com.epmet.commons.rocketmq.messages.GroupAchievementMQMsg;
 import com.epmet.commons.tools.constant.*;
 import com.epmet.commons.tools.exception.EpmetErrorCode;
 import com.epmet.commons.tools.exception.RenException;
@@ -44,6 +45,7 @@ import com.epmet.feign.EpmetMessageOpenFeignClient;
 import com.epmet.group.constant.GroupConstant;
 import com.epmet.feign.EpmetUserOpenFeignClient;
 import com.epmet.modules.constant.UserMessageConstant;
+import com.epmet.modules.enums.AchievementTypeEnum;
 import com.epmet.modules.feign.EpmetMessageFeignClient;
 import com.epmet.modules.feign.EpmetUserFeignClient;
 import com.epmet.modules.feign.GovOrgFeignClient;
@@ -75,6 +77,7 @@ import com.epmet.resi.group.dto.member.ResiGroupMemberInfoRedisDTO;
 import com.epmet.resi.group.dto.member.form.EditAuditSwitchFormDTO;
 import com.epmet.resi.group.dto.member.result.AchievementResultDTO;
 import com.epmet.resi.group.dto.member.result.GroupAchievementDTO;
+import com.epmet.send.SendMqMsgUtil;
 import com.github.pagehelper.PageHelper;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -676,6 +679,13 @@ public class ResiGroupServiceImpl extends BaseServiceImpl msgList = new ArrayList<>();
 		msgList.add(wxSubscribeMessageFormDTO);
 		epmetMessageOpenFeignClient.sendWxSubscribeMessage(msgList);
+
+		//发送小组成就消息
+		boolean flag = SendMqMsgUtil.build().openFeignClient(epmetMessageOpenFeignClient)
+				.sendGroupAchievementMqMsg(new GroupAchievementMQMsg(resiGroupDTO.getCustomerId(),resiGroupDTO.getId(),AchievementTypeEnum.MEMBER.getCode()));
+		if (!flag) {
+			logger.error("发送(小组成就)系统消息到message服务失败");
+		}
 		return new Result();
 	}
 
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/StatsAchievementServiceImpl.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/StatsAchievementServiceImpl.java
new file mode 100644
index 0000000000..74ada0b770
--- /dev/null
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/group/service/impl/StatsAchievementServiceImpl.java
@@ -0,0 +1,218 @@
+package com.epmet.modules.group.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.epmet.commons.tools.constant.NumConstant;
+import com.epmet.commons.tools.exception.EpmetErrorCode;
+import com.epmet.commons.tools.exception.RenException;
+import com.epmet.modules.enums.AchievementTypeEnum;
+import com.epmet.modules.group.entity.ResiGroupAchievementConfigEntity;
+import com.epmet.modules.group.entity.ResiGroupAchievementStatsEntity;
+import com.epmet.modules.group.service.AbstractStatsAchievementService;
+import com.epmet.modules.group.service.StatsAchievementService;
+import com.epmet.modules.member.dao.ResiGroupMemberDao;
+import com.epmet.modules.topic.dao.ResiTopicDao;
+import com.epmet.modules.topic.entity.ResiTopicEntity;
+import com.epmet.resi.group.constant.TopicConstant;
+import com.epmet.resi.group.dto.group.ResiGroupAchievementStatsDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * desc:
+ *
+ * @author: LiuJanJun
+ * @date: 2021/4/20 5:48 下午
+ * @version: 1.0
+ */
+@Slf4j
+@Service
+public class StatsAchievementServiceImpl extends AbstractStatsAchievementService implements StatsAchievementService {
+    @Autowired
+    private ResiGroupMemberDao resiGroupMemberDao;
+    @Autowired
+    private ResiTopicDao resiTopicDao;
+
+
+    /**
+     * desc: 计算小组成就 统一入口
+     *
+     * @param achievementType 成就类型
+     * @return java.lang.Boolean
+     * @author LiuJanJun
+     * @date 2021/4/20
+     */
+    @Override
+    public Boolean calculateAcm(String achievementType) {
+        if (StringUtils.isBlank(achievementType)) {
+            //计算所有类型的  小组人数、话题数、转议题数、小组内问题解决数
+        }
+        return null;
+    }
+
+    /**
+     * desc: 根据小组Id计算小组成就 入口
+     *
+     * @param customerId
+     * @param groupId
+     * @param achievementType 成就类型  小组人数、话题数、转议题数、小组内问题解决数
+     * @return java.lang.Boolean
+     * @author LiuJanJun
+     * @date 2021/4/20
+     */
+    @Override
+    public Boolean calculateAcm(String customerId, String groupId, String achievementType) {
+        AchievementTypeEnum anEnum = AchievementTypeEnum.getEnum(achievementType);
+        if (StringUtils.isBlank(customerId) || StringUtils.isBlank(groupId) || anEnum == null) {
+            return false;
+        }
+        Integer currentValue = null;
+        switch (anEnum) {
+            case TOPIC:
+                //查询话题数
+                QueryWrapper queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda().eq(ResiTopicEntity::getCustomerId,customerId)
+                        .eq(ResiTopicEntity::getGroupId,groupId)
+                        .eq(ResiTopicEntity::getDelFlag,NumConstant.ZERO);
+                currentValue = resiTopicDao.selectCount(queryWrapper);
+                break;
+            case MEMBER:
+                currentValue = resiGroupMemberDao.countMembers(customerId, groupId);
+                break;
+            case TOISSUE:
+                //查询已经转议题的话题数
+                queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda().eq(ResiTopicEntity::getCustomerId,customerId)
+                        .eq(ResiTopicEntity::getGroupId,groupId)
+                        .eq(ResiTopicEntity::getShiftIssue, NumConstant.ONE)
+                        .eq(ResiTopicEntity::getDelFlag,NumConstant.ZERO);
+                currentValue = resiTopicDao.selectCount(queryWrapper);
+                break;
+            case RESOVLE_TOPIC:
+                //查询已经关闭且为已解决的话题数
+                queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda().eq(ResiTopicEntity::getCustomerId,customerId)
+                        .eq(ResiTopicEntity::getGroupId,groupId)
+                        .eq(ResiTopicEntity::getStatus, TopicConstant.CLOSED)
+                        .eq(ResiTopicEntity::getClosedStatus, TopicConstant.RESOLVED)
+                        .eq(ResiTopicEntity::getShiftIssue, NumConstant.ONE)
+                        .eq(ResiTopicEntity::getDelFlag,NumConstant.ZERO);
+                currentValue = resiTopicDao.selectCount(queryWrapper);
+                break;
+            default:
+                log.info("calculateAcm error");
+        }
+        calculateGroupAchievement(customerId, groupId, currentValue, achievementType);
+        return true;
+    }
+
+    /**
+     * desc: 计算小组的人数等级
+     *
+     * @param customerId
+     * @param groupId
+     */
+    private void calculateGroupAchievement(String customerId, String groupId, int currentValue, String achievementType) {
+
+        ResiGroupAchievementStatsEntity one = super.achievementStatsService.selectLastUnAchieved(customerId, groupId, achievementType);
+
+        List haveArrive = new ArrayList<>();
+        //如果没有实现的额成就则说明是初始化
+        if (one == null) {
+            initAchievementStat(customerId, groupId, achievementType, currentValue, haveArrive);
+            super.achievementStatsService.saveOrUpdate(haveArrive,false);
+            return;
+        }
+
+        boolean isBatch = false;
+        Integer targetValue = one.getTargetValue();
+        //改为已实现
+        if (currentValue >= targetValue) {
+            isBatch = true;
+
+            boolean isContinue;
+            int pageNum = NumConstant.ONE;
+            int pageSize = NumConstant.TEN;
+            do {
+                List list = getConfigByType(achievementType,pageNum++,pageSize);
+                isContinue = buildArriveList(customerId, groupId, achievementType, currentValue, one.getTargetValue(), haveArrive, list);
+            }while (isContinue);
+        }
+
+        if (isBatch) {
+            super.achievementStatsService.saveOrUpdate(haveArrive,true);
+        } else {
+            //未实现 只更新当前值
+            ResiGroupAchievementStatsDTO newStat = new ResiGroupAchievementStatsDTO();
+            newStat.setId(one.getId());
+            newStat.setCurrentValue(currentValue);
+            super.achievementStatsService.update(newStat);
+        }
+    }
+
+    private void initAchievementStat(String customerId, String groupId, String achievementType, int currentValue, List haveArrive) {
+
+        boolean isContinue;
+        int pageNum = NumConstant.ONE;
+        int pageSize = NumConstant.TEN;
+        do { //没有任何数据说明是初始化
+            List list = getConfigByType(achievementType,pageNum++,pageSize);
+            //查询和初始化都失败啦
+            if (CollectionUtils.isEmpty(list)) {
+                log.error("calculateMember get config fail");
+                throw new RenException(EpmetErrorCode.INTERNAL_VALIDATE_ERROR.getCode());
+            }
+            isContinue = buildArriveList(customerId, groupId, achievementType, currentValue, null, haveArrive, list);
+        }while (isContinue);
+        if (CollectionUtils.isEmpty(haveArrive)) {
+            throw new RenException("小组达成成就失败");
+        }
+    }
+
+    private boolean buildArriveList(String customerId, String groupId, String achievementType, int currentValue, Integer targetValue, List haveArrive, List list) {
+        boolean isContinue = true;
+        for (ResiGroupAchievementConfigEntity configEntity : list) {
+            if (targetValue != null) {
+                //筛选出已经完成的成就
+                if (configEntity.getTargetValue()= configEntity.getTargetValue()) {
+                statsEntity.setIsArrive(NumConstant.ONE);
+            } else {
+                //如果没有达到则 放入这一条后 退出
+                statsEntity.setIsArrive(NumConstant.ZERO);
+                isContinue = false;
+                break;
+            }
+        }
+        return isContinue;
+    }
+
+    private List getConfigByType(String achievementType,int pageNum,int pageSize) {
+        List list = super.getAchievemnetConfigPage(pageNum, pageSize, achievementType);
+        if (CollectionUtils.isEmpty(list)) {
+            log.warn("获取小组成就配置错误,{}  开始进行初始化规则", achievementType);
+            list = super.initAchievementConfig(achievementType);
+        }
+        return list;
+    }
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/member/dao/ResiGroupMemberDao.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/member/dao/ResiGroupMemberDao.java
index 4205eb483d..f9d9117915 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/member/dao/ResiGroupMemberDao.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/member/dao/ResiGroupMemberDao.java
@@ -168,4 +168,15 @@ public interface ResiGroupMemberDao extends BaseDao {
 	 * @date 2021/4/20 下午4:03
 	 */
 	String selectUserRole(@Param("groupId")String groupId, @Param("userId")String userId);
+
+    /**
+     * desc: 仅统计除组长之外的成员数
+     *
+     * @param customerId
+ 	 * @param groupId
+     * @return int
+     * @author LiuJanJun
+     * @date 2021/4/23 3:14 下午
+     */
+	int countMembers(@Param("customerId") String customerId, @Param("groupId") String groupId);
 }
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/support/GroupAchievementUtils.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/support/GroupAchievementUtils.java
index 0f135804a8..ac90ee00fb 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/support/GroupAchievementUtils.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/support/GroupAchievementUtils.java
@@ -3,6 +3,7 @@ package com.epmet.modules.support;
 import com.epmet.commons.tools.constant.NumConstant;
 import com.epmet.commons.tools.exception.EpmetErrorCode;
 import com.epmet.commons.tools.exception.RenException;
+import com.epmet.modules.enums.AchievementTypeEnum;
 
 /**
  * desc:小组成就下一等级规则工具类
@@ -20,7 +21,7 @@ public class GroupAchievementUtils {
      *
      * @param currentValue
      */
-    public static Integer getNextTopicTargetValue(Integer currentValue) {
+    private static Integer getNextTopicTargetValue(Integer currentValue) {
         if (currentValue < NumConstant.FIVE_HUNDRED) {
             throw new RenException(EpmetErrorCode.INTERNAL_VALIDATE_ERROR.getCode());
         }
@@ -32,7 +33,7 @@ public class GroupAchievementUtils {
      *
      * @param currentValue
      */
-    public static Integer getNextToIssueTargetValue(Integer currentValue) {
+    private static Integer getNextToIssueTargetValue(Integer currentValue) {
         if (currentValue < NumConstant.ONE_HUNDRED) {
             throw new RenException(EpmetErrorCode.INTERNAL_VALIDATE_ERROR.getCode());
         }
@@ -44,10 +45,37 @@ public class GroupAchievementUtils {
      *
      * @param currentValue
      */
-    public static Integer getNextResolveTopicTargetValue(Integer currentValue) {
+    private static Integer getNextResolveTopicTargetValue(Integer currentValue) {
         if (currentValue < NumConstant.ONE_HUNDRED) {
             throw new RenException(EpmetErrorCode.INTERNAL_VALIDATE_ERROR.getCode());
         }
         return currentValue + NumConstant.ONE_HUNDRED;
     }
+
+    /**
+     * desc:获取下一等级的话题数目标值 步长500 起始值 500
+     *
+     * @param currentValue
+     */
+    public static Integer getNextTargetValue(String achievementType, Integer currentValue) {
+        AchievementTypeEnum anEnum = AchievementTypeEnum.getEnum(achievementType);
+        if (anEnum == null){
+            throw new RenException(EpmetErrorCode.INTERNAL_VALIDATE_ERROR.getCode());
+        }
+        Integer next = null;
+        switch (anEnum){
+            case TOPIC:
+                next = getNextTopicTargetValue(currentValue);
+                break;
+            case TOISSUE:
+                next = getNextToIssueTargetValue(currentValue);
+                break;
+            case RESOVLE_TOPIC:
+                next = getNextResolveTopicTargetValue(currentValue);
+                break;
+            default:
+
+        }
+        return next;
+    }
 }
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/controller/ResiTopicController.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/controller/ResiTopicController.java
index aa8158ede0..f47871a741 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/controller/ResiTopicController.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/controller/ResiTopicController.java
@@ -47,6 +47,7 @@ public class ResiTopicController {
      * @Author wangc
      * @Date 2020.03.31 13:15
      **/
+    @Deprecated
     @PostMapping("createtopic")
     public Result createTopic(@LoginUser TokenDto tokenDto, @RequestBody ResiTopicPublishFormDTO topicPublishFormDTO){
 
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/service/impl/ResiTopicServiceImpl.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/service/impl/ResiTopicServiceImpl.java
index d3073e3788..e9de211071 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/service/impl/ResiTopicServiceImpl.java
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/service/impl/ResiTopicServiceImpl.java
@@ -22,6 +22,7 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.epmet.commons.mybatis.service.impl.BaseServiceImpl;
+import com.epmet.commons.rocketmq.messages.GroupAchievementMQMsg;
 import com.epmet.commons.tools.constant.FieldConstant;
 import com.epmet.commons.tools.constant.MqConstant;
 import com.epmet.commons.tools.constant.NumConstant;
@@ -54,6 +55,7 @@ import com.epmet.feign.GovOrgOpenFeignClient;
 import com.epmet.modules.constant.GroupMemberConstant;
 import com.epmet.modules.constant.ResiGroupRedisKeys;
 import com.epmet.modules.constant.WxmpSubscribeConstant;
+import com.epmet.modules.enums.AchievementTypeEnum;
 import com.epmet.modules.feign.EpmetUserFeignClient;
 import com.epmet.modules.feign.GovIssueFeignClient;
 import com.epmet.modules.feign.GovOrgFeignClient;
@@ -100,9 +102,11 @@ import com.epmet.resi.group.dto.topic.form.*;
 import com.epmet.resi.group.dto.topic.result.CheckTopicPublisherResultDTO;
 import com.epmet.resi.group.dto.topic.result.GovTopicIssueInfoResultDTO;
 import com.epmet.resi.group.dto.topic.result.*;
+import com.epmet.send.SendMqMsgUtil;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.google.common.base.CharMatcher;
+import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
@@ -124,6 +128,7 @@ import java.util.stream.Collectors;
  * @author generator generator@elink-cn.com
  * @since v1.0.0 2020-03-31
  */
+@Data
 @Service
 @Slf4j
 public class ResiTopicServiceImpl extends BaseServiceImpl implements ResiTopicService {
@@ -794,6 +799,11 @@ public class ResiTopicServiceImpl extends BaseServiceImpl {
+    @Autowired
+    private StatsAchievementService statsAchievementService;
+
+    @Override
+    public void onMessage(GroupAchievementMQMsg msg) {
+        log.info("receive msg:{}", JSON.toJSONString(msg));
+        if (StringUtils.isBlank(msg.getAchievementType()) || StringUtils.isBlank(msg.getCustomerId())
+                || StringUtils.isBlank(msg.getGroupId())) {
+            log.error("consumer fail,msg:{}", msg);
+            return;
+        }
+        Boolean aBoolean = statsAchievementService.calculateAcm(msg.getCustomerId(), msg.getGroupId(), msg.getAchievementType());
+        log.info("consumer msg success,{}", aBoolean);
+    }
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/mq/type1/GroupAchievementCustomListener.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/mq/type1/GroupAchievementCustomListener.java
new file mode 100644
index 0000000000..1e63735ad3
--- /dev/null
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/mq/type1/GroupAchievementCustomListener.java
@@ -0,0 +1,77 @@
+package com.epmet.mq.type1;
+
+import com.alibaba.fastjson.JSON;
+import com.epmet.commons.rocketmq.messages.GroupAchievementMQMsg;
+import com.epmet.commons.tools.distributedlock.DistributedLock;
+import com.epmet.commons.tools.exception.ExceptionUtils;
+import com.epmet.commons.tools.exception.RenException;
+import com.epmet.commons.tools.utils.SpringContextUtils;
+import com.epmet.modules.group.service.StatsAchievementService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.redisson.api.RLock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @Description 小组成就-监听器
+ * @return
+ * @author wxz
+ * @date 2021.03.03 16:10
+*/
+public class GroupAchievementCustomListener implements MessageListenerConcurrently {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Override
+    public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) {
+        try {
+            msgs.forEach(this::consumeMessage);
+        } catch (Exception e) {
+            logger.error("consumeMessage fail,msg:{}",e.getMessage());
+            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+        }
+        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+    }
+
+    private void consumeMessage(MessageExt messageExt) {
+        String msg = new String(messageExt.getBody());
+        logger.info("receive msg:{}", JSON.toJSONString(msg));
+        GroupAchievementMQMsg msgObj = JSON.parseObject(msg, GroupAchievementMQMsg.class);
+
+        DistributedLock distributedLock = null;
+        RLock lock = null;
+        try {
+            distributedLock = SpringContextUtils.getBean(DistributedLock.class);
+            lock = distributedLock.getLock(String.format("lock:init_customer_org:%s", msgObj.getCustomerId()),
+                    30l, 30l, TimeUnit.SECONDS);
+
+
+
+            if (StringUtils.isBlank(msgObj.getAchievementType()) || StringUtils.isBlank(msgObj.getCustomerId())
+                    || StringUtils.isBlank(msgObj.getGroupId())){
+                logger.error("consumer fail,msg:{}",msgObj);
+                return;
+            }
+            Boolean aBoolean = SpringContextUtils.getBean(StatsAchievementService.class).calculateAcm(msgObj.getCustomerId(), msgObj.getGroupId(), msgObj.getAchievementType());
+            logger.info("consumer msg success,{}",aBoolean);
+        } catch (RenException e) {
+            // 如果是我们手动抛出的异常,说明在业务可控范围内。目前不需要MQ重试
+            logger.error("【RocketMQ】初始化客户组织失败:".concat(ExceptionUtils.getErrorStackTrace(e)));
+        } catch (Exception e) {
+            // 不是我们自己抛出的异常,可以让MQ重试
+            logger.error("【RocketMQ】初始化客户组织失败:".concat(ExceptionUtils.getErrorStackTrace(e)));
+            throw e;
+        } finally {
+            if (distributedLock != null){
+                distributedLock.unLock(lock);
+            }
+        }
+    }
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/mq/type1/RocketMQConsumerRegister.java b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/mq/type1/RocketMQConsumerRegister.java
new file mode 100644
index 0000000000..c15e0ba6b2
--- /dev/null
+++ b/epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/mq/type1/RocketMQConsumerRegister.java
@@ -0,0 +1,63 @@
+package com.epmet.mq.type1;
+
+import com.epmet.commons.rocketmq.constants.ConsomerGroupConstants;
+import com.epmet.commons.rocketmq.constants.TopicConstants;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.client.consumer.listener.MessageListener;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+@Slf4j
+@Component
+public class RocketMQConsumerRegister {
+
+    @Value("${rocketmq.name-server}")
+    private String nameServer;
+
+    /**
+     * @return
+     * @Description 注册监听器
+     * @author wxz
+     * @date 2021.03.03 16:09
+     */
+    @PostConstruct
+    public void registerAllListeners() {
+        try {
+            register(ConsomerGroupConstants.GROUP_ACHIEVEMENT_COMPONENTS_GROUP, MessageModel.CLUSTERING, TopicConstants.GROUP_ACHIEVEMENT, "*", new GroupAchievementCustomListener());
+        } catch (MQClientException e) {
+            log.error("registerAllListeners exception", e);
+        }
+    }
+
+    public void register(String group, MessageModel messageModel, String topic, String subException, MessageListener listener) throws MQClientException {
+        // 实例化消费者
+        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group);
+
+        // 设置NameServer的地址
+        consumer.setNamesrvAddr(nameServer);
+        consumer.setMessageModel(messageModel);
+        consumer.setInstanceName(buildInstanceName());
+        // 订阅一个或者多个Topic,以及Tag来过滤需要消费的消息
+        consumer.subscribe(topic, subException);
+        // 注册回调实现类来处理从broker拉取回来的消息
+        consumer.registerMessageListener(listener);
+        // 启动消费者实例
+        consumer.start();
+    }
+
+    private String buildInstanceName() {
+        String instanceName = "";
+        for (int i = 0; i < 4; i++) {
+            int t = (int) (Math.random() * 10);
+            instanceName = instanceName.concat(t + "");
+        }
+
+        return instanceName;
+    }
+
+}
diff --git a/epmet-module/resi-group/resi-group-server/src/main/resources/bootstrap.yml b/epmet-module/resi-group/resi-group-server/src/main/resources/bootstrap.yml
index f8517a8d56..2ad05a26a0 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/resources/bootstrap.yml
+++ b/epmet-module/resi-group/resi-group-server/src/main/resources/bootstrap.yml
@@ -166,3 +166,8 @@ shutdown:
   graceful:
     enable: true #是否开启优雅停机
     waitTimeSecs: 30 # 优雅停机等待时间,每超过30秒,打印一次错误日志
+
+rocketmq:
+  name-server: @rocketmq.nameserver@
+  producer:
+      group: @rocketmq.producer.group@
diff --git a/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementConfigDao.xml b/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementConfigDao.xml
index 5531c7228e..1728c69e11 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementConfigDao.xml
+++ b/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementConfigDao.xml
@@ -3,20 +3,29 @@
 
 
 
-    
-         
-         
-         
-         
-         
-         
-         
-         
-         
-         
-         
-         
-     
 
 
- 
\ No newline at end of file
+
+
+    
+        SELECT
+            id, customer_id, achievement_name, pre_value, target_value, achievement_type
+        FROM  resi_group_achievement_config
+        WHERE
+            ACHIEVEMENT_TYPE = #{achievementType}
+            AND DEL_FLAG = '0'
+        order by TARGET_VALUE
+        LIMIT #{offset},#{pageSize}
+     
+    
+        SELECT
+            id, customer_id, achievement_name, pre_value, target_value, achievement_type
+        FROM  resi_group_achievement_config
+        WHERE
+            ACHIEVEMENT_TYPE = #{achievementType}
+            AND DEL_FLAG = '0'
+        order by TARGET_VALUE DESC
+        LIMIT 1
+     
+
+
diff --git a/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementStatsDao.xml b/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementStatsDao.xml
index 7705832ba7..a6d3c8e49b 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementStatsDao.xml
+++ b/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/group/ResiGroupAchievementStatsDao.xml
@@ -35,6 +35,67 @@
             CURRENT_VALUE / TARGET_VALUE ASC
         LIMIT 3
     
+    
+        SELECT
+            ID, CUSTOMER_ID, GROUP_ID, ACHIEVEMENT_ID, ACHIEVEMENT_NAME, ACHIEVEMENT_TYPE, ARRIVE_TIME, CURRENT_VALUE, TARGET_VALUE, IS_ARRIVE
+        FROM
+            resi_group_achievement_stats
+        WHERE DEL_FLAG = '0'
+        AND GROUP_ID = #{groupId}
+        AND CUSTOMER_ID = #{customerId}
+        AND ACHIEVEMENT_TYPE = #{achievementType}
+        AND IS_ARRIVE = 0
+     
+    
+        INSERT INTO resi_group_achievement_stats
+        (
+            ID,
+            CUSTOMER_ID,
+            GROUP_ID,
+            ACHIEVEMENT_ID,
+            ACHIEVEMENT_NAME,
+            ACHIEVEMENT_TYPE,
+            ARRIVE_TIME,
+            CURRENT_VALUE,
+            TARGET_VALUE,
+            IS_ARRIVE,
+            DEL_FLAG,
+            REVISION,
+            CREATED_BY,
+            CREATED_TIME,
+            UPDATED_BY,
+            UPDATED_TIME
+        )
+        VALUES
+        
+            (
+            #{item.id},
+            #{item.customerId},
+            #{item.groupId},
+            #{item.achievementId},
+            #{item.achievementName},
+            #{item.achievementType},
+            #{item.arriveTime},
+            #{item.currentValue},
+            #{item.targetValue},
+            #{item.isArrive},
+            #{item.delFlag},
+            #{item.revision},
+            #{item.createdBy},
+            #{item.createdTime},
+            #{item.updatedBy},
+            #{item.updatedTime}
+            )
+         
+        ON DUPLICATE KEY UPDATE
+            
+             CURRENT_VALUE = values(CURRENT_VALUE),
+             TARGET_VALUE = values(TARGET_VALUE),
+             IS_ARRIVE = VALUES(IS_ARRIVE),
+             UPDATED_TIME = VALUES(UPDATED_TIME),
+             
+            UPDATED_BY = VALUES(UPDATED_BY)
+     
 
 
-
\ No newline at end of file
+
diff --git a/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/member/ResiGroupMemberDao.xml b/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/member/ResiGroupMemberDao.xml
index 7cf0ffb00a..fb7457d649 100644
--- a/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/member/ResiGroupMemberDao.xml
+++ b/epmet-module/resi-group/resi-group-server/src/main/resources/mapper/member/ResiGroupMemberDao.xml
@@ -191,6 +191,18 @@
         ORDER BY
             rgm.CREATED_TIME DESC
     
+    
+        SELECT
+            count(*)
+        FROM
+            resi_group_member rgm
+        WHERE
+            rgm.RESI_GROUP_ID = #{groupId}
+            AND rgm.CUSTOMER_ID = #{customerId}
+            and rgm.STATUS = 'approved'
+            AND rgm.GROUP_LEADER_FLAG = 'member'
+
+     
 
     
          SELECT
diff --git a/epmet-module/resi-group/resi-group-server/src/test/com/epmet/modules/group/service/impl/StatsAchievementServiceImplTest.java b/epmet-module/resi-group/resi-group-server/src/test/com/epmet/modules/group/service/impl/StatsAchievementServiceImplTest.java
new file mode 100644
index 0000000000..c8e0e3b19d
--- /dev/null
+++ b/epmet-module/resi-group/resi-group-server/src/test/com/epmet/modules/group/service/impl/StatsAchievementServiceImplTest.java
@@ -0,0 +1,31 @@
+package com.epmet.modules.group.service.impl;
+
+import com.epmet.modules.group.service.StatsAchievementService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class StatsAchievementServiceImplTest {
+    @Autowired
+    private StatsAchievementService statsAchievementService;
+
+    @Test
+    public void calculateAcm() {
+
+//        String customerId = "test_cid";
+//        String groupId = "test_groupId";
+//        String achievementType = "member";
+//        Boolean aBoolean = statsAchievementService.calculateAcm(customerId, groupId, achievementType);
+//        System.out.println(aBoolean);
+
+        String customerId = "test_cid";
+        String groupId = "test_groupId";
+        String achievementType = "toissue";
+        Boolean aBoolean = statsAchievementService.calculateAcm(customerId, groupId, achievementType);
+        System.out.println(aBoolean);
+    }
+}