纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】...

 
   

投诉受理管理模块

接下来,就是来开发我们的投诉受理管理模块了…..我们来看看原型图与需求吧:

查询用户提交的投诉信息,可以根据投诉部门(部门A/B)、投诉时间段、状态进行查询。在列表信息中展示投诉标题、被投诉部门、被投诉人、投诉时间、状态(待受理、已受理、已失效)、操作;其中操作栏内内容为“处理”,点击“处理”则在打开的查询页面中查看具体的投诉信息并且可以多次回复投诉信息;一旦回复则说明已受理该投诉。

投诉详细信息:在本页面中首先要明显地展示出当前投诉是否已经受理;然后再显示投诉人信息、被投诉信息、受理信息(历史受理信息)三部分内容,并且在页面中可以无限次的对本次受理进行回复。投诉人信息包括:是否匿名投诉、投诉人单位、投诉人姓名、投诉人手机,如果是匿名投诉,则不显示投诉人单位、姓名并对手机号中间4位号码使用*号代替。被投诉信息包括:投诉时间、被投诉部门、被投诉人、投诉标题、投诉内容。受理信息:如果有多次回复则将多次的回复信息显示,显示内容包括回复时间、回复部门、回复人、受理回复内容;可以再次回复。

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第1张图片 这里写图片描述 纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第2张图片 这里写图片描述

根据上面两张原型图以及文字说明,我们可以发现:一个投诉信息可对应多个回复。


在“工作主页”中点击“我要投诉”进入页面,添加内容包括:投诉标题、被投诉部门(部门A/B)、被投诉人、投诉详情、是否匿名投诉

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第3张图片 这里写图片描述

关键在于匿名投诉的那一部分,我们该怎么写….


统计:根据年度将相应年度的每个月的投诉数进行统计,并以图表的形式展示在页面中;在页面中可以选择查看当前年度及其前4年的投诉数。在页面中可以选择不同的年度,然后页面展示该年度的曲线统计图。

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第4张图片 这里写图片描述

这个统计图,大概也需要用到组件来生成出来的吧???


自动投诉受理:在每个月月底最后一天对本月之前的投诉进行自动处理;将投诉信息的状态改为 已失效。在后台管理中不能对该类型投诉进行回复。

自动投诉受理??在每个月的最后一天判断投诉信息,程序对其自动受理。。


投诉受理开发

我们首先来画一个流程图看看它的大概思路是怎么样的:

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第5张图片 这里写图片描述

Hibernate逆向工程

我们经过上面的分析,知道了:一个投诉信息可对应多个回复。是一对多的关系。我们下面使用powerdesginer来画出它的概念数据模型图

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第6张图片 这里写图片描述

生成物理模型图:

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第7张图片 这里写图片描述

生成数据库表:

/*==============================================================*//* DBMS name:      MySQL 5.0                                    *//* Created on:     2017/6/12 19:06:20                           *//*==============================================================*/drop table if exists complain;drop table if exists complain_reply;/*==============================================================*//* Table: complain                                              *//*==============================================================*/create table complain(   comp_id              varchar(32) not null,   comp_company         varchar(100),   comp_name            varchar(20),   comp_mobile          varchar(20),   is_NM                bool,   comp_time            datetime,   comp_title           varchar(200) not null,   to_comp_name         varchar(20),   to_comp_dept         varchar(100),   comp_content         text,   state                varchar(1),   primary key (comp_id));/*==============================================================*//* Table: complain_reply                                        *//*==============================================================*/create table complain_reply(   reply_id             varchar(32) not null,   comp_id              varchar(32) not null,   replyer              varchar(20),   reply_dept           varchar(100),   reply_time           datetime,   reply_content        varchar(300),   primary key (reply_id));alter table complain_reply add constraint FK_comp_reply foreign key (comp_id)      references complain (comp_id) on delete restrict on update restrict;
/* DBMS name:      MySQL 5.0                                    */
/* Created on:     2017/6/12 19:06:20                           */
/*==============================================================*/


drop table if exists complain;

drop table if exists complain_reply;

/*==============================================================*/
/* Table: complain                                              */
/*==============================================================*/
create table complain
(
  comp_id              varchar(32) not null,
  comp_company         varchar(100),
  comp_name            varchar(20),
  comp_mobile          varchar(20),
  is_NM                bool,
  comp_time            datetime,
  comp_title           varchar(200) not null,
  to_comp_name         varchar(20),
  to_comp_dept         varchar(100),
  comp_content         text,
  state                varchar(1),
  primary key (comp_id)
);

/*==============================================================*/
/* Table: complain_reply                                        */
/*==============================================================*/
create table complain_reply
(
  reply_id             varchar(32) not null,
  comp_id              varchar(32) not null,
  replyer              varchar(20),
  reply_dept           varchar(100),
  reply_time           datetime,
  reply_content        varchar(300),
  primary key (reply_id)
);

alter table complain_reply add constraint FK_comp_reply foreign key (comp_id)
     references complain (comp_id) on delete restrict on update restrict;

生成实体与配置文件:

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第8张图片 这里写图片描述

Intellij idea下生成出来的映射文件是没有对应的关联关系的。也就是说:一对多或多对多的关系,它是不会帮你自动生成的【好像是这样子的】。。。因此,需要我们自己添加Set【如果需要】

                                                                    
           <key>
               <column name="comp_id" length="32" not-null="true" />
           key>
           <one-to-many class="zhongfucheng.complain.entity.ComplainReply" />
       set>

编写dao、service、action

编写dao、service、action都非常简单。记得要把模块的配置文件加载到总配置文件中!

ComplainAction代码如下:

public class ComplainAction extends BaseAction {    /*************注入Service************************/    @Autowired    private ComplainService complainServiceImpl;    /************数据自动封装,给出setter和getter*************************/    private Complain complain;    public Complain getComplain() {        return complain;    }    public void setComplain(Complain complain) {        this.complain = complain;    }    /************Action中7大方法*************************/    //抛出Action异常    public String listUI() throws ServiceException, UnsupportedEncodingException {        //把状态的集合带过去        QueryHelper queryHelper = new QueryHelper(Complain.class, "c");        //当前页数没有值,那么赋值为1        if (currentPageCount == 0) {            currentPageCount = 1;        }        //把状态带过去给JSP页面        ActionContext.getContext().getContextMap().put("complainStateMap", Complain.COMPLAIN_STATE_MAP);        pageResult = complainServiceImpl.getPageResult(queryHelper,currentPageCount);        return "listUI";    }}class ComplainAction extends BaseAction {

   /*************注入Service************************/
   @Autowired
   private ComplainService complainServiceImpl;
   /************数据自动封装,给出setter和getter*************************/
   private Complain complain;
   public Complain getComplain() {
       return complain;
   }
   public void setComplain(Complain complain) {
       this.complain = complain;
   }

   /************Action中7大方法*************************/
   //抛出Action异常
   public String listUI() throws ServiceException, UnsupportedEncodingException {

       //把状态的集合带过去
       QueryHelper queryHelper = new QueryHelper(Complain.class, "c");

       //当前页数没有值,那么赋值为1
       if (currentPageCount == 0) {
           currentPageCount = 1;
       }
       //把状态带过去给JSP页面
       ActionContext.getContext().getContextMap().put("complainStateMap", Complain.COMPLAIN_STATE_MAP);
       pageResult = complainServiceImpl.getPageResult(queryHelper,currentPageCount);
       return "listUI";
   }

}

导入对应的JSP页面…..得到的效果如下:

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第9张图片 这里写图片描述

条件查询

我们来看一下条件查询有几个:可以根据投诉的标题、投诉的时间、投诉的状态进行查询。

640?wx_fmt=png 这里写图片描述

对于投诉标题和投诉的状态我们都可以很容易地拿到条件:

        //根据complain标题是否为null来判断是否是条件查询。如果complain为空,那么是查询所有。        if (complain != null) {            if (org.apache.commons.lang.StringUtils.isNotBlank(complain.getCompTitle())) {                selectCondition =  URLDecoder.decode(complain.getCompTitle(),"UTF-8");                complain.setCompTitle(selectCondition);                queryHelper.addCondition(" c.compTitle like ? ", "%" + complain.getCompTitle() + "%");            }            //投诉状态并不需要编码,因为它并不是中文。            if (org.apache.commons.lang.StringUtils.isNotBlank(complain.getState())) {                queryHelper.addCondition(" c.state like ? ", "%" + complain.getState() + "%");            }        }
       if (complain != null) {
           if (org.apache.commons.lang.StringUtils.isNotBlank(complain.getCompTitle())) {
               selectCondition =  URLDecoder.decode(complain.getCompTitle(),"UTF-8");
               complain.setCompTitle(selectCondition);
               queryHelper.addCondition(" c.compTitle like ? ", "%" + complain.getCompTitle() + "%");
           }
           //投诉状态并不需要编码,因为它并不是中文。
           if (org.apache.commons.lang.StringUtils.isNotBlank(complain.getState())) {
               queryHelper.addCondition(" c.state like ? ", "%" + complain.getState() + "%");
           }
       }

那么根据投诉时间来进行查询,我们要怎么做呢???我们约定时间是这样的格式:yyyy-MM-dd HH:mm。这样的格式Struts2默认是不支持解析的,那么我们怎么获取呢???

有的同学可能会想到类型转换器,我们在Struts2的时候的确是学过类型转换器。。。但是呢,这种方法并不是最好的。我们可以使用DateUtils工具类来得到日期数据!

    //先判断时间,通过时间进行筛选后,再进行like模糊查询。那么性能会好一些    if (StringUtils.isNotBlank(startTime)) {        startTime =  URLDecoder.decode(startTime,"UTF-8");        queryHelper.addCondition(" c.compTime >= ? ", DateUtils.parseDate(startTime, new String[]{"yyyy-MM-dd HH:mm"}));    }    if (StringUtils.isNotBlank(endTime)) {        endTime =  URLDecoder.decode(endTime,"UTF-8");        queryHelper.addCondition(" c.compTime <= ? ", DateUtils.parseDate(endTime, new String[]{"yyyy-MM-dd HH:mm"}));    }
   if (StringUtils.isNotBlank(startTime)) {
       startTime =  URLDecoder.decode(startTime,"UTF-8");
       queryHelper.addCondition(" c.compTime >= ? ", DateUtils.parseDate(startTime, new String[]{"yyyy-MM-dd HH:mm"}));
   }

   if (StringUtils.isNotBlank(endTime)) {
       endTime =  URLDecoder.decode(endTime,"UTF-8");
       queryHelper.addCondition(" c.compTime <= ? ", DateUtils.parseDate(endTime, new String[]{"yyyy-MM-dd HH:mm"}));
   }

我们在JSP页面上也使用datepicker组件来让用户选择日期

       投诉时间:          -          
         -
        <s:textfield id="endTime" name="endTime" cssClass="s_text"  cssStyle="width:160px;" readonly="true" onfocus="WdatePicker({'skin':'whyGreen','dateFmt':'yyyy-MM-dd HH:mm'});"/>

受理回复

提供处理受理的UI界面。根据id查找投诉的全部信息。

    //提供受理的UI    public String dealUI() {        //把状态传递过去        ActionContext.getContext().getContextMap().put("complainStateMap", Complain.COMPLAIN_STATE_MAP);        //得到想要受理的记录        if (complain != null) {            complain = complainServiceImpl.findObjectById(complain.getCompId());        }        return "dealUI";    }
   public String dealUI() {

       //把状态传递过去
       ActionContext.getContext().getContextMap().put("complainStateMap", Complain.COMPLAIN_STATE_MAP);

       //得到想要受理的记录
       if (complain != null) {
           complain = complainServiceImpl.findObjectById(complain.getCompId());
       }
       return "dealUI";
   }

在处理受理的JSP页面上要把投诉的id给发送给Action处理。不然在保存信息的时候,就会把投诉信息丢失了!。在Action中通过id重新查找回投诉的信息!

    //受理    public String deal() {        //修改投诉信息的处理状态        if (complain != null) {            //查找到信息            complain = complainServiceImpl.findObjectById(complain.getCompId());            //如果状态是已处理了,那么就不用再修改了            if (!complain.getState().equals(Complain.COMPLAIN_STATE_DONE)) {                complain.setState(Complain.COMPLAIN_STATE_DONE);            }        }        //保存回复的信息        if (reply != null) {            //更新回复的日期            reply.setReplyTime(new Timestamp(new Date().getTime()));            //把回复信息添加到投诉信息中【关联关系】            reply.setComplain(complain);            complain.getComplainReplies().add(reply);        }        //级联更新        complainServiceImpl.update(complain);        return "list";    }
   public String deal() {

       //修改投诉信息的处理状态
       if (complain != null) {
           //查找到信息
           complain = complainServiceImpl.findObjectById(complain.getCompId());
           //如果状态是已处理了,那么就不用再修改了
           if (!complain.getState().equals(Complain.COMPLAIN_STATE_DONE)) {
               complain.setState(Complain.COMPLAIN_STATE_DONE);
           }
       }
       //保存回复的信息
       if (reply != null) {
           //更新回复的日期
           reply.setReplyTime(new Timestamp(new Date().getTime()));

           //把回复信息添加到投诉信息中【关联关系】
           reply.setComplain(complain);
           complain.getComplainReplies().add(reply);
       }

       //级联更新
       complainServiceImpl.update(complain);

       return "list";
   }

显示回复信息

我们在处理投诉的时候,应该把回复的历史信息给处理的人看…..

把回复的信息遍历出来。

                            <%--得到所有回复的信息--%>                                
                       回复                          
                       回复部门:                        回复人:                        回复时间:                        
                       
                   
                           

       <tr>
           <%--得到所有回复的信息--%>

           <td colspan="2">

                   <fieldset style="border: solid 1px #c0c0c0;margin-top:5px;"><legend style="color:green;font-weight:bold;">
                       回复<s:property
                           value="#st.count"/>
 legend>
                       <div style="width:100%; text-align:center;color:#ccc;maring-top:5px;">
                       回复部门:<s:property value="replyDept"/>
                       回复人:<s:property value="replyer"/>
                       回复时间:<s:date name="replyTime" format="yyyy-MM-dd HH:mm"/>
                       div>
                       <div style="width:100%;maring-top:10px;font-size:13px;padding-left:5px;"><s:property value="replyContent"/>div>
                   fieldset>

           td>
       tr>
       s:iterator>

现在有一个问题,就是我们使用的是set集合,它所有的回复信息并不是按照顺序来排列的。我们可以在hbm配置文件中指定我们set集合的顺序

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第10张图片 这里写图片描述

那么在显示的时候,我们的回复顺序就不会被搞乱了。

匿名投诉

在需求中,我们已经看到了,如果投诉的人是匿名投诉的,那么我们不能显示该投诉人的名字、部门。他的号码应该设置成1372342类型的

其实我们只要在显示对应值的前面判断该投诉人是否是匿名投诉就行了。

                                    <%--138****2342类型--%>                                                                            
           <s:if test="%{complain.isNm==0}">
               <%--138****2342类型--%>
               <s:property value="complain.compMobile"/>
           s:if>
           <s:else>
               <s:property value="%{complain.compMobile.substring(0,3)+'****'+complain.compMobile.substring(7,11)}"/>
           s:else>
       td>

我要投诉二级联动

用户可以在首页上通过“我要投诉”超链接对工作人员进行投诉..当然了,用户点击“我要投诉”超链接的时候,应该在新的页面上给出对应的页面,所以指定target为“_blank”..

我们在指定部门的时候,下拉菜单应该在后台给出对应的的员工。这就需要我们用到ajax进行二级菜单的二级联动了。

我们在返回JSON格式有两种方式:第一种就是没有使用Struts2框架的时候,
使用三个开发包commons-beanutils-1.8.0,ezmorph-1.0.6,json-lib-2.3-jdk15。使用JSONObject对象来构建JSON字符串,使用流对象返回给浏览器。

我们如果使用了Struts2框架的话,直接导入:struts2-json-plugin-2.3.20这么一个开发包,并且在配置文件中指定继承json-defalut包,返回的类型是JSON的话。那么Struts2框架就会自动帮我们在该Action中所拥有getter方法的属性就生成JSON格式返回给浏览器。。。当然了,我们可能不想Struts2把全部带有getter的属性都生成JSON返回给浏览器,我们只要在返回JSON类型上指定参数root,就可以指定生成哪一个属性自动生成JSON字符串返回给浏览器了。

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第11张图片 这里写图片描述

当然了,无论是没有使用Struts2框架,还是有使用Struts2框架,我们都是有过Demo的。详情请参考博文:http://blog.csdn.net/hon_3y/article/details/72468761和http://blog.csdn.net/hon_3y/article/details/72480126

另外,我们手动访问Acttion给出对应的参数,就可以看到服务器返回的JSON是什么了。最后我们使用HiJson这样的工具,就可以把返回的JSON进行格式化。

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第12张图片 这里写图片描述

那么,我们的代码是这样的:

使用ajax返回服务器。

        function doSelectDept() {            var $dept = $("#toCompDept option:selected").val();            //初始化清空           if($dept =="0"){               $("#toCompName").empty();            }            $.ajax({                type: "post",                url: "${basePath}sys/home_getUserJson.action",                data: {"dept":$dept},                dataType: "json",                success: function (data) {                    if("success" == data.msg){                        var toCompName = $("#toCompName");                        toCompName.empty();                        $.each(data.userList, function(index, user){                            toCompName.append("");                        });                    } else {alert("获取被投诉人列表失败!");}                },                error: function () {                    alert("失败咯")                }            });        }
           var $dept = $("#toCompDept option:selected").val();

           //初始化清空
          if($dept =="0"){
              $("#toCompName").empty();
           }

           $.ajax({
               type: "post",
               url: "${basePath}sys/home_getUserJson.action",
               data: {"dept":$dept},
               dataType: "json",
               success: function (data) {
                   if("success" == data.msg){
                       var toCompName = $("#toCompName");
                       toCompName.empty();
                       $.each(data.userList, function(index, user){
                           toCompName.append(" + user.name + "");
                       });
                   } else {alert("获取被投诉人列表失败!");}
               },
               error: function () {
                   alert("失败咯")
               }
           });
       }

使用一个Map集合装载这些数据,Struts2自动把Map集合的数据转成是JSON格式的,返回给浏览器。

    private Map return_map;    public Map getReturn_map() {        return return_map;    }      public String getUserJson() {            //得到带过来的dept            String dept = ServletActionContext.getRequest().getParameter("dept");            if (dept != null) {                //根据部门查询所有的员工                QueryHelper queryHelper = new QueryHelper(User.class, "u");                queryHelper.addCondition(" u.dept like ? ", "%" +dept);                //2、根据部门查询用户列表                return_map = new HashMap();                return_map.put("msg", "success");                return_map.put("userList", userServiceImpl.findObjects(queryHelper));            }            return "success";        }

   public Map getReturn_map() {
       return return_map;
   }

     public String getUserJson() {
           //得到带过来的dept
           String dept = ServletActionContext.getRequest().getParameter("dept");
           if (dept != null) {
               //根据部门查询所有的员工
               QueryHelper queryHelper = new QueryHelper(User.class, "u");
               queryHelper.addCondition(" u.dept like ? ", "%" +dept);

               //2、根据部门查询用户列表
               return_map = new HashMap();
               return_map.put("msg", "success");
               return_map.put("userList", userServiceImpl.findObjects(queryHelper));
           }

           return "success";
       }

我要投诉保存信息

我们在投诉的内容上添加上富文本框,让用户可以在文本域上传上图片….

加上一个富文本框是非常简单的,只要导入对应的js文件,在textarea上写上ueditor的id就可以完成效果了。。。

                     "utf-8" src="${basePath}js/ueditor/ueditor.config.js">script>
   
       //页面一加载就执行方法
       $(function () {
           doAnnualStatistic();
       });


       //根据年份获取投诉数
       function doAnnualStatistic() {
           //获取当前年份
           var $year = $("#year option:selected").val();

           //一进来,如果没有选择任何的年数,就显示当前年份的
           if($year=="" || $year==undefined) {
              $year = "${year}";
           }
           //2、统计年度投诉数据并展示图表
           $.ajax({
               url: "${basePath}complain/complain_getAnnualStatisticData.action",
               type: "post",
               dataType: "json",
               data: {"year",$year},
               success: function (backData) {
                   if(backData!=null && backData!=""){
                       var revenueChart = new FusionCharts({
                           "type": "line",
                           "renderAt": "chartContainer",
                           "width": "600",
                           "height": "400",
                           "dataFormat": "json",
                           "dataSource": {
                               "chart": {
                                   "caption": "年度统计投诉数",
                                   "xAxisName": "月   份",
                                   "yAxisName": "投  诉 数",
                                   "theme": "fint"
                               },
                               "data":backData.chartData
                           }
                       });
                       revenueChart.render();
                   }
               },
               error:function () {
                   alert("统计投诉数失败!");
               }
           });
       }
   </script>

后端分析

我们的后端就是根据年份,获取对应的值,返回一个JSON格式给浏览器,那就行了…

但是呢,我们还有其他的细节需要考虑:今年是2017年7月,但是在查询年度投诉数是要把整个年的信息查询出来,8-12月的投诉数肯定是没有的。那么我们会将还没到的时间设置成“”,如果在2016年的某月是没有投诉数的,我们应该将其替换成0,而不是“"….

在action中,我们得获取到用户传递过来的年份,我们调用service、dao层的方法获取该年度对应每个月的投诉数,转换成JSON格式输出就行了。

我们知道前端需要的JSON格式是一个对象数组,最终目的就是数组:Struts2框架在最后解析的时候,会把集合解析成是数组。对象数组在java编程语言就是List集合中嵌套着Map集合。

在后端中,还有一个难点,就是我们的SQL语句该怎么写????我们要从数据库查询的是该年份每个月的投诉数….

通过该年而查询每个月,我们可以很快地想到要用到分组查询。但是还有一个问题,我们在进行分组查询的时候,如果表中是没有1月或2月等数组的话,分组查询出来的数据是没有这些月份的。而我们的统计图是需要所有月份的数据的。咋看一下,我们是需要把查询出来的数据做循环判断,得看看有没有该月份,如果没有该月份还得把数据填充进去。。还得判断该月份是不是本年度的….这样想一下就觉得麻烦了……

select month(comp_time) as '月份',count(*) '总数'from complainwhere year(comp_time)=?group by month(comp_time)month(comp_time) as '月份',count(*) '总数'
from complain
where year(comp_time)=?
group by month(comp_time)
纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第24张图片 这里写图片描述

再次回到前面分析的,如果本年度的月份还没有到,那么将该月的数据设置为“”,如果是其他年份的的月份查出的数据为null,那么我们应该把这些月份的投诉数设置为0而不是”“…..

但是呢,我们现在有一个办法,可以在查询的时候,不管该月份有没有数据,都得显示出来….这就是左外连接

于是我们自己手动生成一张拥有12个月份的数据表,跟我们的投诉表进行左外连接…

纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第25张图片 这里写图片描述
    select imonth, count(comp_id)    from t_month left join complain on imonth=month(comp_time)                                      and year(comp_time)=2017    group by imonth    order by imonth;count(comp_id)
   from t_month left join complain on imonth=month(comp_time)
                                     and year(comp_time)=2017
   group by imonth
   order by imonth;
纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】..._第26张图片 这里写图片描述

上面的sql语句的查询效率是有点低的,我们改造一下,改成是子查询:

select imonth,c2from t_month left join (select month(comp_time) c1, count(comp_id) c2 from complain where year(comp_time)=? group by month(comp_time)) ton imonth = c1order by imonth;
from t_month left join (select month(comp_time) c1, count(comp_id) c2 from complain where year(comp_time)=? group by month(comp_time)) t
on imonth = c1
order by imonth;

代码实现

dao层根据年份查询出每个月份的投诉数据

    /**     *     * @param year 根据年获取数据     * @return  返回的是一个列表数组     */    @Override    public List getAnnualStatisticByYear(int year) {        //拼接SQL语句        StringBuffer buffer = new StringBuffer();        buffer.append(" SELECT imonth,c2 ")        .append(" FROM t_month")        .append(" LEFT JOIN (SELECT month(comp_time) c1, count(comp_id) c2 FROM complain WHERE YEAR(comp_time)=? GROUP BY MONTH(comp_time)) t")        .append(" ON imonth = c1")        .append(" ORDER BY imonth;");        SQLQuery sqlQuery = getSession().createSQLQuery(buffer.toString());        sqlQuery.setParameter(0, year);        List list = sqlQuery.list();        return list;    }
   @Override
   public List getAnnualStatisticByYear(int year) {


       //拼接SQL语句
       StringBuffer buffer = new StringBuffer();
       buffer.append(" SELECT imonth,c2 ")
       .append(" FROM t_month")
       .append(" LEFT JOIN (SELECT month(comp_time) c1, count(comp_id) c2 FROM complain WHERE YEAR(comp_time)=? GROUP BY MONTH(comp_time)) t")
       .append(" ON imonth = c1")
       .append(" ORDER BY imonth;");
       SQLQuery sqlQuery = getSession().createSQLQuery(buffer.toString());
       sqlQuery.setParameter(0, year);

       List list = sqlQuery.list();
       return list;
   }

service层拿到Dao层的数据,判断是否是本年度的,如果是本年度的,那么还没有到的月份的数据就设置为”“,如果已经过的了月份,如果没有数据就设置为0.

返回一个List集合嵌套着Map集合,就可以给前台解析了。

    @Override    public List getAnnualStatisticByYear(int year) {        List annualStatisticByYear = complainDao.getAnnualStatisticByYear(year);        List returnList = new ArrayList<>();        //得到本年度和本月份        int curYear = Calendar.getInstance().get(Calendar.YEAR);        //Calerdar月份从0开始,        int curMonth = Calendar.getInstance().get(Calendar.MONTH)+1;        //使用Map集合装载着数据        Map map = null;        for (Object[] objects : annualStatisticByYear) {            map = new HashedMap();            //得到月份            Integer month = Integer.valueOf(objects[0] + "");            map.put("label", month + "月");            if (curYear == year) { //是本年度,那么看看月份是否大于本月份                if (month > curMonth) {                    //将数据设置为""                    map.put("value", "");                } else {                    if (objects[1] != null) {                        map.put("value", objects[1]);                    } else {                        map.put("value", "0");                    }                }            }else {//不是本年度                if (objects[1] != null) {                    map.put("value", objects[1]);                } else {                    map.put("value", "0");                }            }            returnList.add(map);        }        return returnList;    }
   public List getAnnualStatisticByYear(int year) {

       List annualStatisticByYear = complainDao.getAnnualStatisticByYear(year);

       List returnList = new ArrayList<>();

       //得到本年度和本月份
       int curYear = Calendar.getInstance().get(Calendar.YEAR);
       //Calerdar月份从0开始,
       int curMonth = Calendar.getInstance().get(Calendar.MONTH)+1;

       //使用Map集合装载着数据
       Map map = null;
       for (Object[] objects : annualStatisticByYear) {
           map = new HashedMap();
           //得到月份
           Integer month = Integer.valueOf(objects[0] + "");
           map.put("label", month + "月");
           if (curYear == year) { //是本年度,那么看看月份是否大于本月份
               if (month > curMonth) {
                   //将数据设置为""
                   map.put("value", "");
               } else {
                   if (objects[1] != null) {
                       map.put("value", objects[1]);
                   } else {
                       map.put("value", "0");
                   }
               }
           }else {//不是本年度
               if (objects[1] != null) {
                   map.put("value", objects[1]);
               } else {
                   map.put("value", "0");
               }
           }
           returnList.add(map);
       }
       return returnList;
   }

action层把service层的数据封装到Map集合中,嵌套ajax解析Map集合,得到的就是对象数组了。

    //返回JSON格式的数据,这里我们就直接用Struts2框架来返回对应的数据就行了。    public String getAnnualStatisticData() {        //获取用户传递过来的年份        String str_year = ServletActionContext.getRequest().getParameter("year");        if (str_year != null) {            int year = Integer.valueOf(str_year);            //根据年份去获取每个月的投诉数            map.put("msg", "success");            map.put("chartData", complainServiceImpl.getAnnualStatisticByYear(year));        }        return "getAnnualStatisticData";    }
   public String getAnnualStatisticData() {

       //获取用户传递过来的年份
       String str_year = ServletActionContext.getRequest().getParameter("year");
       if (str_year != null) {
           int year = Integer.valueOf(str_year);
           //根据年份去获取每个月的投诉数
           map.put("msg", "success");
           map.put("chartData", complainServiceImpl.getAnnualStatisticByYear(year));
       }
       return "getAnnualStatisticData";
   }

前台把年份提交给Action,解析出后台返回的数据,渲染成折线图….

 function doAnnualStatistic() {            //获取当前年份            var $year = $("#year option:selected").val();            //一进来,如果没有选择任何的年数,就显示当前年份的            if($year=="" || $year==undefined) {               $year = "${year}";            }            //2、统计年度投诉数据并展示图表            $.ajax({                url: "${basePath}complain/complain_getAnnualStatisticData.action",                type: "post",                dataType: "json",                data: {"year":$year},                success: function (backData) {                    if(backData!=null && backData!=""){                        var revenueChart = new FusionCharts({                            "type": "line",                            "renderAt": "chartContainer",                            "width": "600",                            "height": "400",                            "dataFormat": "json",                            "dataSource": {                                "chart": {                                    "caption": "年度统计投诉数",                                    "xAxisName": "月   份",                                    "yAxisName": "投  诉 数",                                    "theme": "fint"                                },                                "data":backData.chartData                            }                        });                        revenueChart.render();                    }                },                error:function () {                    alert("统计投诉数失败!");                }            });        }
           //获取当前年份
           var $year = $("#year option:selected").val();

           //一进来,如果没有选择任何的年数,就显示当前年份的
           if($year=="" || $year==undefined) {
              $year = "${year}";
           }
           //2、统计年度投诉数据并展示图表
           $.ajax({
               url: "${basePath}complain/complain_getAnnualStatisticData.action",
               type: "post",
               dataType: "json",
               data: {"year":$year},
               success: function (backData) {
                   if(backData!=null && backData!=""){
                       var revenueChart = new FusionCharts({
                           "type": "line",
                           "renderAt": "chartContainer",
                           "width": "600",
                           "height": "400",
                           "dataFormat": "json",
                           "dataSource": {
                               "chart": {
                                   "caption": "年度统计投诉数",
                                   "xAxisName": "月   份",
                                   "yAxisName": "投  诉 数",
                                   "theme": "fint"
                               },
                               "data":backData.chartData
                           }
                       });
                       revenueChart.render();
                   }
               },
               error:function () {
                   alert("统计投诉数失败!");
               }
           });
       }

总结

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y


你可能感兴趣的:(纳税服务系统七(投诉管理模块)【显示投诉信息、处理回复、我要投诉、Quartz自动受理、统计图FusionCharts】...)