接下来,就是来开发我们的投诉受理管理模块了…..我们来看看原型图与需求吧:
这里写图片描述 这里写图片描述查询用户提交的投诉信息,可以根据投诉部门(部门A/B)、投诉时间段、状态进行查询。在列表信息中展示投诉标题、被投诉部门、被投诉人、投诉时间、状态(待受理、已受理、已失效)、操作;其中操作栏内内容为“处理”,点击“处理”则在打开的查询页面中查看具体的投诉信息并且可以多次回复投诉信息;一旦回复则说明已受理该投诉。
投诉详细信息:在本页面中首先要明显地展示出当前投诉是否已经受理;然后再显示投诉人信息、被投诉信息、受理信息(历史受理信息)三部分内容,并且在页面中可以无限次的对本次受理进行回复。投诉人信息包括:是否匿名投诉、投诉人单位、投诉人姓名、投诉人手机,如果是匿名投诉,则不显示投诉人单位、姓名并对手机号中间4位号码使用*号代替。被投诉信息包括:投诉时间、被投诉部门、被投诉人、投诉标题、投诉内容。受理信息:如果有多次回复则将多次的回复信息显示,显示内容包括回复时间、回复部门、回复人、受理回复内容;可以再次回复。
根据上面两张原型图以及文字说明,我们可以发现:一个投诉信息可对应多个回复。
这里写图片描述在“工作主页”中点击“我要投诉”进入页面,添加内容包括:投诉标题、被投诉部门(部门A/B)、被投诉人、投诉详情、是否匿名投诉。
关键在于匿名投诉的那一部分,我们该怎么写….
这里写图片描述统计:根据年度将相应年度的每个月的投诉数进行统计,并以图表的形式展示在页面中;在页面中可以选择查看当前年度及其前4年的投诉数。在页面中可以选择不同的年度,然后页面展示该年度的曲线统计图。
这个统计图,大概也需要用到组件来生成出来的吧???
自动投诉受理:在每个月月底最后一天对本月之前的投诉进行自动处理;将投诉信息的状态改为 已失效。在后台管理中不能对该类型投诉进行回复。
自动投诉受理??在每个月的最后一天判断投诉信息,程序对其自动受理。。
我们首先来画一个流程图看看它的大概思路是怎么样的:
这里写图片描述我们经过上面的分析,知道了:一个投诉信息可对应多个回复。是一对多的关系。我们下面使用powerdesginer来画出它的概念数据模型图
这里写图片描述生成物理模型图:
这里写图片描述生成数据库表:
/*==============================================================*//* 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;
生成实体与配置文件:
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都非常简单。记得要把模块的配置文件加载到总配置文件中!
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页面…..得到的效果如下:
这里写图片描述我们来看一下条件查询有几个:可以根据投诉的标题、投诉的时间、投诉的状态进行查询。
这里写图片描述对于投诉标题和投诉的状态我们都可以很容易地拿到条件:
//根据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集合的顺序:
这里写图片描述那么在显示的时候,我们的回复顺序就不会被搞乱了。
在需求中,我们已经看到了,如果投诉的人是匿名投诉的,那么我们不能显示该投诉人的名字、部门。他的号码应该设置成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字符串返回给浏览器了。
这里写图片描述当然了,无论是没有使用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进行格式化。
这里写图片描述那么,我们的代码是这样的:
使用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)
这里写图片描述
再次回到前面分析的,如果本年度的月份还没有到,那么将该月的数据设置为“”,如果是其他年份的的月份查出的数据为null,那么我们应该把这些月份的投诉数设置为0而不是”“…..
但是呢,我们现在有一个办法,可以在查询的时候,不管该月份有没有数据,都得显示出来….这就是左外连接
于是我们自己手动生成一张拥有12个月份的数据表,跟我们的投诉表进行左外连接…
这里写图片描述 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;
这里写图片描述
上面的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
service层拿到Dao层的数据,判断是否是本年度的,如果是本年度的,那么还没有到的月份的数据就设置为”“,如果已经过的了月份,如果没有数据就设置为0.
返回一个List集合嵌套着Map集合,就可以给前台解析了。
@Override public List getAnnualStatisticByYear(int year) { List annualStatisticByYear = complainDao.getAnnualStatisticByYear(year); List
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