基于App接口的消息灵活通知的接口设计和数据库设计及其代码实现

1.接口设计:主要是消息的接收体和必要的校验参数;

2.数模设计(MySQL):

 

建表语句如下: 

CREATE TABLE `app_msg` (
  `msg_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键:消息编号',
  `msg_content` text NOT NULL COMMENT '消息内容',
  `create_date_time` datetime NOT NULL COMMENT '消息创建时间',
  `creater` bigint(20) unsigned NOT NULL COMMENT '消息创建人',
  `modify_date_time` datetime DEFAULT NULL COMMENT '消息修改时间',
  `modifier` bigint(20) unsigned DEFAULT NULL COMMENT '消息修改人ID',
  `effective_start_time` datetime NOT NULL COMMENT '消息有效开始时间',
  `effective_end_time` datetime NOT NULL COMMENT '消息有效结束时间',
  `show_times` int(11) unsigned DEFAULT '0' COMMENT '通知时间间隔(单位:小时)',
  `msg_title` varchar(32) NOT NULL DEFAULT '' COMMENT '消息标题名称',
  `msg_type` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '消息通知类型:1 有效期内通知一次; 2 有效期内每次启动都通知;3 有效期内每隔n时间通知一次;',
  PRIMARY KEY (`msg_id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT='APP端弹窗消息体具体内容'; 
CREATE TABLE `app_msg_device_relation` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键:消息推送关系编号',
  `msg_id` bigint(20) unsigned NOT NULL COMMENT '消息编号',
  `device_id` varchar(64) NOT NULL COMMENT '推送设备编号',
  `user_id` bigint(20) unsigned DEFAULT NULL COMMENT '推送用户编号',
  `last_msg_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上次通知时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='平台端设置的消息体推送到app端与用户及设备之间的关系'; 

3.接口代码实现:

  • AppMsgController逻辑:
    /**
    	 * @Description: app端获取重要的通知信息
    	 * @author 
    	 * @date 2018年06月05日 14:31:38
    	 * @param param
    	 * @return
    	 *
    	 */
    	@NoAuth
    	@NoSignCheck
    	@ResponseBody
    	@RequestMapping(value = "getNoticeList", method = RequestMethod.POST)
    	public Object getNoticeList(@RequestParam HashMap<String, Object> param) {
    		Map<String, Object> returnMap=new HashMap<>();
    		List<Map<String, Object>> msgList=new ArrayList<Map<String, Object>>();
    		String errorMsg = "";
    
    		try {
    			// 校验传参
    			if (StringUtil.isNullOrEmpty((String) param.get("userId"))
    					|| StringUtil.isNullOrEmpty((String) param.get("deviceId"))
    					|| StringUtil.isNullOrEmpty((String) param.get("cityName"))) {
    				return MspAppResult.setFailedModelMap("参数传递错误",
    						HttpCode.MOBILE_STATUS_PARAM_ERROR);
    			}
    
    			Long userId=Long.valueOf((String) param.get("userId"));
    			String deviceId=(String) param.get("deviceId");
    			String cityName=(String) param.get("cityName");
    
    			//有效期内的通知消息列表处理
    			msgList=appMsgSerive.solveAppMsgList(userId,deviceId,cityName);
    
    		} catch (BusinessException e) {
    			log.error(e.getMessage(), e);
    			return MspAppResult.setFailedModelMap(e.getMessage(),
    					e.getHttpCode());
    		} catch (Exception e) {
    			errorMsg = "查询通知消息异常";
    			log.error(errorMsg, e);
    			return MspAppResult.setFailedModelMap(errorMsg,
    					HttpCode.MOBILE_STATUS_EXCEPTION);
    		}
    		log.info("getNoticeList接口调用成功" );
            //包装map
    		returnMap.put("list",msgList);
    
    		return MspAppResult.setSuccessModelMap(returnMap);
    	}
  • AppMsgServiceImpl实现逻辑:
     /**
         * @Description: 处理app通知消息逻辑
         * @author 
         * @date 2018年06月07日 19:05:08
         * @param userId
         * @param deviceId
         * @return
         *
         */
        @Override
        public List<Map<String, Object>> solveAppMsgList(Long userId, String deviceId,String cityName) {
            List<Map<String, Object>> returnList=new ArrayList<Map<String, Object>>();
            List<AppMsgBO> addAppMsgBOList=new ArrayList<AppMsgBO>();
    
            //1.查询有效期内的消息列表(不存在消息则直接返回空)
            AppMsgQueryBO queryBO=new AppMsgQueryBO();
            queryBO.setNowDateTime(new Date());
            List<AppMsgBO> appMsgLists=appMsgDao.queryEffictiveList(queryBO);
            if(null==appMsgLists){
                log.error("查询有效期内的消息列表为空");
                return returnList;
            }
            //拆分三种类型的消息列表
            List<AppMsgBO> twoTypeList=getTypeList(CommonConstants.APP_MSG_TYPE_2,appMsgLists);
            List<AppMsgBO> threeTypeList=getTypeList(CommonConstants.APP_MSG_TYPE_3,appMsgLists);
            List<AppMsgBO> oneTypeList=getTypeList(CommonConstants.APP_MSG_TYPE_1,appMsgLists);
            //与设备相关,则查询该设备有效期内已通知的消息列表
            List<AppMsgBO> deviceAppMsgLists=new ArrayList<AppMsgBO>();
            if(!threeTypeList.isEmpty()||!oneTypeList.isEmpty()){
                AppMsgQueryBO queryEfBo=new AppMsgQueryBO();
                //如果是多条同时通知,则根据msgId来查询
                if(appMsgLists.size()>1){
                    List<Long>msgIds=new ArrayList<>(appMsgLists.size());
                    for(AppMsgBO ao:appMsgLists){
                        msgIds.add(ao.getMsgId());
                    }
                    queryEfBo.setMsgIds(msgIds);
                }
                queryEfBo.setNowDateTime(new Date());
                queryEfBo.setDeviceId(deviceId);
                deviceAppMsgLists=appMsgDao.queryDeviceEffictiveList(queryEfBo);
            }
    
            //2.有效期内每次启动都通知;(跟设备无关系)
            if(!twoTypeList.isEmpty()){
                //未通知消息集合
                List<AppMsgBO> unMsgList=getUnMsgList(twoTypeList,null,CommonConstants.APP_MSG_TYPE_2);
                //批量返回消息通知
                returnList.addAll(getReturnAppMsg(unMsgList));
            }
    
            //3.有效期内每隔n时间通知一次;(跟设备有关系,与时间间隔也有关系)
            if(!threeTypeList.isEmpty()){
                List<AppMsgBO> threeDeviceTypeList=new ArrayList<>();
                if(null!=deviceAppMsgLists&&deviceAppMsgLists.size()>0){
                    threeDeviceTypeList=getTypeList(CommonConstants.APP_MSG_TYPE_3,deviceAppMsgLists);
                }
                //未通知消息集合
                List<AppMsgBO> unMsgList=getUnMsgList(threeTypeList,threeDeviceTypeList,CommonConstants.APP_MSG_TYPE_3);
                //批量返回消息通知(包括修改的部分)
                returnList.addAll(getReturnAppMsg(unMsgList));
                //循环删除不需要通知的对象(去掉修改的部分)
                for(AppMsgBO bo:threeDeviceTypeList){
                    for(int i=unMsgList.size()-1;i>=0;i--){
                        if(Objects.equals(unMsgList.get(i).getMsgId(), bo.getMsgId())){
                            unMsgList.remove(unMsgList.get(i));
                        }
                    }
                }
                //批量新增消息通知(已去掉修改的部分)
                addAppMsgBOList.addAll(unMsgList);
    
            }
    
    
            //4.有效期内通知一次;(与设备及其通知次数有关系)
            if(!oneTypeList.isEmpty()){
                List<AppMsgBO> oneDeviceTypeList=null;
                if(null!=deviceAppMsgLists&&deviceAppMsgLists.size()>0){
                    oneDeviceTypeList=getTypeList(CommonConstants.APP_MSG_TYPE_1,deviceAppMsgLists);
                }
                //未通知消息集合
                List<AppMsgBO> unMsgList=getUnMsgList(oneTypeList,oneDeviceTypeList,CommonConstants.APP_MSG_TYPE_1);
                //批量返回消息通知
                returnList.addAll(getReturnAppMsg(unMsgList));
                //批量新增消息通知
                addAppMsgBOList.addAll(unMsgList);
    
            }
    
            //5.处理批量新增的消息
            if(null!=addAppMsgBOList&&addAppMsgBOList.size()>0){
                List<AppMsgDeviceRelation> adList=new ArrayList<AppMsgDeviceRelation>(addAppMsgBOList.size());
                AppMsgDeviceRelation ar;
                for(AppMsgBO bo:addAppMsgBOList){
                    ar=new AppMsgDeviceRelation();
                    ar.setMsgId(bo.getMsgId());
                    ar.setDeviceId(deviceId);
                    ar.setUserId(userId);
                    ar.setLastMsgTime(new Date());
                    adList.add(ar);
                }
                appMsgDeviceRelationDao.insertBatchEntity(adList);
            }
    
    
            return returnList;
        }
 /**
     * @Description: 获取某个类型的list
     * @author 
     * @date 2018年06月08日 15:13:11
     * @param type
     * @param list
     * @return
     *
     */
    public List<AppMsgBO> getTypeList(Byte type,List<AppMsgBO> list){
        List<AppMsgBO> newList=new ArrayList<>(list.size());
        for (AppMsgBO bo:list){
             if(Objects.equals(bo.getMsgType(),type)){
                 newList.add(bo);
             }
        }

        return newList;
    }

/**
     * @Description: 获取未通知的信息列表
     * @author 
     * @date 2018年06月08日 16:30:20
     * @param allList 全部通知集合
     * @param yesList 已通知集合
     * @param msgType 通知类型
     * @return
     *
     */
    public List<AppMsgBO> getUnMsgList(List<AppMsgBO> allList,List<AppMsgBO> yesList,Byte msgType){
        //1.已通知集合为空,则全部为未通知
        if(null==yesList){
           return allList;
        }
        //2.获取未通知部分
        List<AppMsgBO> addList=new ArrayList<>(yesList.size());//收集新增消息体集合
        List<AppMsgBO> updateList=new ArrayList<>(yesList.size());//收集修改消息体集合
        for (AppMsgBO all:allList){
            for(AppMsgBO yes:yesList){
                if(Objects.equals(yes.getMsgId(), all.getMsgId())){
                    addList.add(all);
                    updateList.add(yes);
                }
            }
        }

        if(!addList.isEmpty()){
            //msgType=1时,获得未通知的部分
            if(Objects.equals(msgType, CommonConstants.APP_MSG_TYPE_1)){
                allList.removeAll(addList);
            }
            //msgType=3时获得已通知的部分即updateList(此处需批量修改间隔时间,注意:对间隔时间的部分要进行计算再决定是否通知)
            if(Objects.equals(msgType, CommonConstants.APP_MSG_TYPE_3) &&!updateList.isEmpty()){
                List<AppMsgDeviceRelation> upList=new ArrayList<AppMsgDeviceRelation>(updateList.size());
                AppMsgDeviceRelation ar;
                for(AppMsgBO bo:updateList){
                    if(System.currentTimeMillis()-bo.getLastMsgTime().getTime()>=bo.getShowTimes()*60*60*1000){
                        ar=new AppMsgDeviceRelation();
                        ar.setId(bo.getId());
                        ar.setLastMsgTime(new Date());
                        upList.add(ar);
                    }else{
                        //循环删除不需要通知的对象
                        for(int i=allList.size()-1;i>=0;i--){
                            if(Objects.equals(allList.get(i).getMsgId(), bo.getMsgId())){
                                allList.remove(allList.get(i));
                            }
                        }
                    }
                }
                //批量更新时间
                if(!upList.isEmpty()){
                    appMsgDeviceRelationDao.updateBatchEntity(upList);
                }
            }
        }

        return allList;
    }
/**
     * @Description: 封装返回结果
     * @author 
     * @date 2018年06月08日 16:17:06
     * @param list
     * @return
     *
     */
    public List<Map<String, Object>> getReturnAppMsg(List<AppMsgBO> list){
        List<Map<String, Object>> returnList=new ArrayList<Map<String, Object>>();
        Map<String, Object> returnMap;
        for(AppMsgBO bo:list){
            returnMap=new HashMap<>(3);
            returnMap.put("title",bo.getMsgTitle());
            returnMap.put("content",bo.getMsgContent());
            returnMap.put("noticeId",bo.getMsgId());
            returnList.add(returnMap);
        }

        return returnList;
    }

4.mybatis对应的文件:

  • AppMsgDeviceRelationMapper.xml文件部分:
    <!-- 批量更新实体的部分字段 -->
      <update id="updateBatchEntity" parameterType="java.util.List">
        update app_msg_device_relation
        <trim prefix="set" suffixOverrides=",">
          <trim prefix="last_msg_time =case" suffix="end,">
            <foreach collection="list" item="item" index="index">
              when id=#{item.id} then #{item.lastMsgTime}
            </foreach>
          </trim>
        </trim>
        where id in
        <foreach collection="list" index="index" item="item" separator="," open="(" close=")">
          #{item.id,jdbcType=BIGINT}
        </foreach>
      </update>
    
      <!-- 批量新增实体关系 -->
      <insert id="insertBatchEntity" parameterType="list">
        INSERT INTO app_msg_device_relation
        (msg_id, device_id, user_id, last_msg_time)
        VALUES
        <foreach collection="list" item="re" index="index"
                 separator=",">
         (#{re.msgId,jdbcType=BIGINT},
          #{re.deviceId,jdbcType=VARCHAR},
          #{re.userId,jdbcType=BIGINT},
          #{re.lastMsgTime,jdbcType=TIMESTAMP})
        </foreach>
      </insert>
  • AppMsgMapper.xml部分内容:
     <!--根据条件查询当前有效期内的消息通知列表(目前只取最新的一条)-->
        <select id="queryEffictiveList" parameterType="com.hikvision.bo.AppMsgQueryBO" resultType="com.hikvision.bo.AppMsgBO">
            SELECT
            <include refid="Base_Column_List"/>
            ,
            <include refid="Blob_Column_List"/>
            FROM app_msg
            WHERE  #{nowDateTime} BETWEEN effective_start_time AND  effective_end_time
    
            ORDER BY create_date_time DESC,effective_end_time DESC
            LIMIT 1
        </select>
    
        <!--根据条件查询设备有效期内的消息通知列表-->
        <select id="queryDeviceEffictiveList" parameterType="com.hikvision.bo.AppMsgQueryBO" resultType="com.hikvision.bo.AppMsgBO">
            SELECT a.id,a.device_id,a.user_id,a.last_msg_time,
                   b.msg_id,b.effective_start_time,b.effective_end_time,b.msg_title,b.msg_content,b.msg_type,b.show_times
            FROM app_msg_device_relation a,app_msg b
            WHERE a.msg_id=b.msg_id
                  AND  #{nowDateTime} BETWEEN b.effective_start_time AND b.effective_end_time
                  AND  a.device_id = #{deviceId,jdbcType=VARCHAR}
                  <if test="msgIds != null and msgIds.size()>0 ">
                    AND a.msg_id in
                      <foreach collection="msgIds" index="index" item="item" separator="," open="(" close=")">
                          #{item,jdbcType=BIGINT}
                      </foreach>
                  </if>
    
            ORDER BY b.create_date_time DESC,b.effective_end_time DESC
    
        </select>
    

5.web端配置效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值