如何给FineReport设置自定义消息提醒工具

简介:

FineReport设计器有自动的消息推送功能可设置报表定时推送和常规的日报周报推送。官方有自己的消息推送的接口,不过有些用户旺旺希望自己开发,符合自己需求的推送界面。

下面这个方案就从逻辑层面简单阐述一个通讯类应该怎么实现。

废话不多说直接上代码,为了保证新手能够看懂,这个代码基本上只需要了解JSJQ的常规写法就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
;
( function ($){
         /*定义一个工具对象,所有的工具以后都放进去*/
         HG = {};
         /*定义我们第一个基础类OBJ*/
         HG.OBJ =  function (options){
                 //保证子类能够继承父类的默认成员变量
                 this .options = $.extend( this ._defaultOptions(), options);
                 //初始化对象
                 this ._init();
         };
         $.extend(HG.OBJ.prototype, {
                 _defaultOptions:  function  () {
                         return  {classType: "OBJ" };
                 },
                 _init: function (){}
         });
         /*定义用于生成子类的方法*/
         HG.extend= function (parent,options){
                 var  son = $.extend(parent,{});
                 son.prototype = $.extend(parent.prototype,options);
                 return  son;
         };
         /*第一个就是要构建我们的通讯对象*/
         /****定义一些通讯用的私有成员和方法*****/
         //发送通道的状态,为了减轻服务器压力,采取单通道发送
         var  status =  true ;
         var  sendMsgList = [];
         var  receiveMsgList = [];
         var  server =  null ;
         var  sendType =  null ;
         var  dataType =  null ;
         //最终发送消息的方法
         var  send= function (msg,onReceive,onComplete,onFailed){
                 if (!msg.inList){
                         msg.inList =  true ;
                         sendMsgList.push(msg);
                 }
                 if (status){
                         status =  false ;
                         var  tempSendMsgList = sendMsgList;
                         sendMsgList = [];
                         FR.ajax({  
                                 url: server,  
                                 type: sendType,
                                 dataType:dataType,
                                 data:{msgList:tempSendMsgList},
                                 success :  function (receiveMsgList){
                                         status =  true ;
                                         onReceive(receiveMsgList);
                                 },
                                 complete:  function (XMLHttpRequest,textStatus){
                                         status =  true ;
                                         onComplete(XMLHttpRequest,textStatus);
                                 },
                                 error:  function (XMLHttpRequest, textStatus, errorThrown){
                                         status =  true ;
                                         onFailed(XMLHttpRequest, textStatus, errorThrown);
                                 }
                         });
                 } else {
                         setTimeout( function (){
                                 send(msg,onReceive,onComplete,onFailed);
                         },1000);
                 }
         };
         var  formatDate =  function (date){
                 var  d =  new  Date(date);
                 return  d.getFullYear()+ "-" +d.getMonth()+ "-" +d.getDate()+ "  " +d.getHours()+ ":" +d.getMinutes()+ ":" +d.getSeconds();
         };
         //通讯类,可以自己重写onReceive的方法来实现自己的消息工具,消息的内容为JSON格式,自己定义就好了
         HG.CommunicationClient = HG.extend(HG.OBJ,{
                 _defaultOptions:  function  () {
                         return  {
                                 classType: "CommunicationClient" ,
                                 //默认只跟当前的服务器进行联络
                                 server:FR.servletURL+ "?op=msgserver" ,
                                 sendType: "POST" ,
                                 dataType: "JSON" ,
                                 //轮询的频率,默认3秒1次,越快服务器和客户端压力越大
                                 pollingRate:3000
                         };
                 },
                 _init: function (){
                         server =  this .options.server;
                         sendType =  this .options.sendType;
                         dataType =  this .options.dataType;
                         this .polling4Receive();
                 },
                 send: function (msg){
                         var  self =  this ;
                         send(msg,self.onReceive, self.onComplete, self.onFailed);
                 },
                 //给某个用户发文本消息
                 sendText: function (toUserId,text){
                         this .send({action: "send" ,userId:toUserId,time: new  Date().getTime(),content:{text:text}})
                 },
                 onReceive: function (msg){
                         if (msg.length>0){
                                 for var  i=0; i<msg.length; i++ ){
                                         console.info(formatDate(msg[i].time)+ "  " +msg[i].name+ " " +decodeURI( "%E8%AF%B4%EF%BC%9A" )+ " " +msg[i].content.text);
                                 }
                         }
                 },
                 onFailed: function (XMLHttpRequest, textStatus, errorThrown){
                 },
                 onComplete: function (XMLHttpRequest, textStatus){
                 },
                 /*向服务器轮询,检查是否有自己的消息*/
                 polling4Receive: function (){
                         var  self =  this ;
                         self.send({action: "findMessage" ,inList: false });
                         setTimeout( function (){
                                 self.polling4Receive();
                         },self.options.pollingRate);
                 }
         });
         //先生成一个对话工具
         HG.Talk =  new  HG.CommunicationClient();
})(jQuery);

 在任意一个你需要的系统或者界面引入这段JS

然后最基本的文本消息发送

                                                HG.Talk.sendText(接收者的用户名,文本消息的内容);

当然,我们实际需求中需要的远远不止是发个文本这么简单,对于任意消息的发送该怎么搞呢?

有两种方法:

继承HG.CommunicationClient实现新的自己的通讯类,或者重写 HG.Talk的方法,两种方式都是修改onReceive方法,上面的代码中是把消息直接显示到控制台当中的。

你可以根据你自己的需要发送任意JSON格式的msg并在onReceive中去实现你想要的展现方法。当然如果你想真正的了解它是怎么运作的,可以花5分钟看一遍代码就清楚了

下面看看后台,因为暂时只说逻辑,所以很多东西都不考虑,后台就会非常的简单,只需要有点JAVA基础,并且了解FineReportservice接口就应该能看懂.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package  com.hg.plugin.plate.msgutils;
  
import  java.io.PrintWriter;
import  java.util.ArrayList;
import  java.util.Date;
import  java.util.HashMap;
import  java.util.List;
import  java.util.Map;
  
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;
  
import  com.fr.fs.control.UserControl;
import  com.fr.fs.web.service.ServiceUtils;
import  com.fr.json.JSONArray;
import  com.fr.json.JSONObject;
import  com.fr.stable.fun.Service;
import  com.fr.web.utils.WebUtils;
  
public  class  MessageServer  implements  Service {
         
         class  Message{
                 private  long  time = - 1 ;
                 private  String fuserId =  "" ;
                 private  String tuserId =  "" ;
                 private  JSONObject content = JSONObject.create();
                 
                 public  Message(String fromUserId,String toUserId,JSONObject content){
                         this .fuserId = fromUserId;
                         this .tuserId = toUserId;
                         this .content = content;
                         time =  new  Date().getTime();
                 }
                 
                 public  JSONObject toJSON()  throws  Exception{
                         JSONObject jo = JSONObject.create();
                         jo.put( "userId" , fuserId);
                         jo.put( "name" , UserControl.getInstance().getByUserName(fuserId).getRealname());
                         jo.put( "content" , content);
                         jo.put( "time" , time);
                         return  jo;
                 }
         }
         
         private  static  Map<String,List<Message>> messageStore =  new  HashMap<String,List<Message>>();
         
         @Override
         public  String actionOP() {
                 return  "msgserver" ;
         }
         
         @Override
         public  void  process(HttpServletRequest req, HttpServletResponse res,String op, String sessionID)  throws  Exception {
                 String msgListStr = WebUtils.getHTTPRequestParameter(req,  "msgList" );
                 JSONArray msgListJa =  new  JSONArray(msgListStr);
                 List<JSONObject> msgList = sortMessageList(msgListJa);
                 String fromUserId = ServiceUtils.getCurrentUserName(req);
                 //投递给别人的信件
                 for (JSONObject msg : msgList){
                         String tuserId = msg.getString( "userId" );
                         if (!messageStore.containsKey(tuserId)){
                                 messageStore.put(tuserId,  new  ArrayList<Message>());
                         }
                         messageStore.get(tuserId).add( new  Message(fromUserId,tuserId,msg.getJSONObject( "content" )));
                 }
                 //查看是否有自己的信件
                 if (!messageStore.containsKey(fromUserId)){
                         messageStore.put(fromUserId,  new  ArrayList<Message>());
                 }
                 List<Message> sendList = messageStore.get(fromUserId);
                 JSONArray result = JSONArray.create();
                 for (Message msg : sendList){
                         result.put(msg.toJSON());
                 }
                 messageStore.put(fromUserId,  new  ArrayList<Message>());
                 res.setContentType( "text/html;charset=UTF-8" );
                 res.setCharacterEncoding( "UTF-8" );
                 PrintWriter  write = res.getWriter();
                 write.write(result.toString());
                 write.flush();
                 write.close();
         }
         
         private  static  List<JSONObject> sortMessageList(JSONArray msgListJa)  throws  Exception{
                 List<JSONObject> result =  new  ArrayList<JSONObject>();
                 for ( int  i= 0 ; i<msgListJa.length(); i++){
                         JSONObject msgJo = msgListJa.getJSONObject(i);
                         //去除轮询的请求
                         if ( "findMessage" .equals(msgJo.getString( "action" ))){
                                 continue ;
                         }
                         if (result.size()== 0 ){
                                 result.add(msgJo);
                         } else {
                                 boolean  add =  false ;
                                 for ( int  j= 0 ;j<result.size();j++){
                                         JSONObject tempMsgJo = result.get(j);
                                         if (tempMsgJo.getLong( "time" )>=msgJo.getLong( "time" )){
                                                 result.add(j, msgJo);
                                                 add =  true ;
                                                 break ;
                                         }
                                 }
                                 if (!add){
                                         result.add(msgJo);
                                 }
                         }
                 }
                 return  result;
         }
}

逻辑是什么呢?这么说你就懂了,在还是写信通讯的年代,负责通讯的就是邮局,邮局是怎么处理事务的呢?

发件人把信投递到邮局,邮局根据收件人地址进行分类,然后由不同的邮递员分别送到各个收件人的家里,

这里情况比较特殊,就是当某些地方邮局不派送信件的地方,当地人怎么取信呢?当有同村的进城的时候就拜托他到邮局看看有没有自己的信件有的话就带回来。

我们上面的代码就是类似后面这种特俗情况。

每个客户端,每隔一段时间都发送一个请求到服务器询问有没有自己的信件,有的话就打包全部接收进来。

每次发送信件出去也是一样,可能有多个信息同时被投递,交给服务器去分类保存。

这个代码实在没啥说的~基本上逻辑一目了然~

然后怎么用呢?编译后注册成为插件就可以使用了~当然要用到项目中需要自己对消息队列进行持久化和线程同步互斥的管理,不然并发多了队列可能就会混乱的哟~~


本文转自 雄霸天下啦 51CTO博客,原文链接:http://blog.51cto.com/10549520/1885069,如需转载请自行联系原作者

相关文章
|
3月前
|
移动开发 运维 小程序
【4月开发者日回顾】小程序审核驳回增加页面截图;H5域名白名单的配置将实时生效……
【4月开发者日回顾】小程序审核驳回增加页面截图;H5域名白名单的配置将实时生效……
53 0
|
7月前
|
小程序 NoSQL JavaScript
【易售小程序项目】”我的“界面实现+“信息修改“界面实现+登出账号实现+图片上传组件【基于若依管理系统开发】
【易售小程序项目】”我的“界面实现+“信息修改“界面实现+登出账号实现+图片上传组件【基于若依管理系统开发】
61 0
|
10月前
|
前端开发 JavaScript
漏刻有时后台左侧菜单默认隐藏的解决方案
漏刻有时后台左侧菜单默认隐藏的解决方案
41 0
|
10月前
|
前端开发 定位技术
百度地图开发自定义信息窗口openInfoWindow样式的解决方案
百度地图开发自定义信息窗口openInfoWindow样式的解决方案
834 0
|
12月前
|
移动开发 JSON API
h5调起原生分享面板,展示更多功能方案
h5调起原生分享面板,展示更多功能方案
200 0
KgCaptcha 行为验证码自定义语言/预警信息设置
KgCaptcha 行为验证码自定义语言/预警信息设置
KgCaptcha 行为验证码自定义语言/预警信息设置
|
JavaScript BI 数据库
FineReport 使用JS实现决策报表对数据库更新(自动更新,不用点击按钮)
数据库中部分表数据按照一段时间需要更新(如:每个月更新一次),这样数据库中的数据相关数据的部分值是相同的,需要让每一个月的月份更新后,数据库中其他表对应的关系也自动更新,这里介绍相关操作方法。
871 0
FineReport 使用JS实现决策报表对数据库更新(自动更新,不用点击按钮)
|
小程序
符合预期的留言板小程序,新增消息通知功能!快来试用吧
符合预期的留言板小程序,新增消息通知功能!快来试用吧
222 0
符合预期的留言板小程序,新增消息通知功能!快来试用吧