SSH系列:(26)投诉受理
1、Hibernate逆向工程
1.1、CDM概念模型
这里虽然用了T_Complain,但是不建议这样做,因为后面生成JavaBean类时,会生成TComplain.java类,而不是Complain.java。
1.2、物理模型
1.3、生成的实体类和Hibernate映射文件
Complain.java
package com.rk.tax.entity;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
public class Complain implements java.io.Serializable {
// Fields
private String compId;
private String compCompany;
private String compName;
private String compMobile;
private Boolean isAnonymous;
private Timestamp compTime;
private String compTitle;
private String toCompName;
private String toCompDept;
private String compContent;
private String state;
private Set complainreplies = new HashSet(0);
//状态
public static String COMPLAIN_STATE_UNDONE = "0";
public static String COMPLAIN_STATE_DONE = "1";
public static String COMPLAIN_STATE_INVALID = "2";
public static Map<String, String> COMPLAIN_STATE_MAP;
static {
COMPLAIN_STATE_MAP = new HashMap<String, String>();
COMPLAIN_STATE_MAP.put(COMPLAIN_STATE_UNDONE, "待受理");
COMPLAIN_STATE_MAP.put(COMPLAIN_STATE_DONE, "已受理");
COMPLAIN_STATE_MAP.put(COMPLAIN_STATE_INVALID, "已失效");
}
// Constructors
public Complain() {
}
public String getCompId() {
return compId;
}
public void setCompId(String compId) {
this.compId = compId;
}
public String getCompCompany() {
return compCompany;
}
public void setCompCompany(String compCompany) {
this.compCompany = compCompany;
}
public String getCompName() {
return compName;
}
public void setCompName(String compName) {
this.compName = compName;
}
public String getCompMobile() {
return compMobile;
}
public void setCompMobile(String compMobile) {
this.compMobile = compMobile;
}
public Boolean getIsAnonymous() {
return isAnonymous;
}
public void setIsAnonymous(Boolean isAnonymous) {
this.isAnonymous = isAnonymous;
}
public Timestamp getCompTime() {
return compTime;
}
public void setCompTime(Timestamp compTime) {
this.compTime = compTime;
}
public String getCompTitle() {
return compTitle;
}
public void setCompTitle(String compTitle) {
this.compTitle = compTitle;
}
public String getToCompName() {
return toCompName;
}
public void setToCompName(String toCompName) {
this.toCompName = toCompName;
}
public String getToCompDept() {
return toCompDept;
}
public void setToCompDept(String toCompDept) {
this.toCompDept = toCompDept;
}
public String getCompContent() {
return compContent;
}
public void setCompContent(String compContent) {
this.compContent = compContent;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Set getComplainreplies() {
return complainreplies;
}
public void setComplainreplies(Set complainreplies) {
this.complainreplies = complainreplies;
}
}
知识点(1):
//状态
public static String COMPLAIN_STATE_UNDONE = "0";
public static String COMPLAIN_STATE_DONE = "1";
public static String COMPLAIN_STATE_INVALID = "2";
public static Map<String, String> COMPLAIN_STATE_MAP;
static {
COMPLAIN_STATE_MAP = new HashMap<String, String>();
COMPLAIN_STATE_MAP.put(COMPLAIN_STATE_UNDONE, "待受理");
COMPLAIN_STATE_MAP.put(COMPLAIN_STATE_DONE, "已受理");
COMPLAIN_STATE_MAP.put(COMPLAIN_STATE_INVALID, "已失效");
}
Complain.hbm.xml
注意:在生成的映射文件中去掉 catalog=”数据库名称”。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.rk.tax.entity.Complain" table="t_complain">
<id name="compId" type="java.lang.String">
<column name="comp_id" length="32" />
<generator class="uuid.hex" />
</id>
<property name="compCompany" type="java.lang.String">
<column name="comp_company" length="100" />
</property>
<property name="compName" type="java.lang.String">
<column name="comp_name" length="20" />
</property>
<property name="compMobile" type="java.lang.String">
<column name="comp_mobile" length="20" />
</property>
<property name="isAnonymous" type="java.lang.Boolean">
<column name="is_anonymous" />
</property>
<property name="compTime" type="java.sql.Timestamp">
<column name="comp_time" length="19" />
</property>
<property name="compTitle" type="java.lang.String">
<column name="comp_title" length="200" not-null="true" />
</property>
<property name="toCompName" type="java.lang.String">
<column name="to_comp_name" length="32" />
</property>
<property name="toCompDept" type="java.lang.String">
<column name="to_comp_dept" length="100" />
</property>
<property name="compContent" type="text">
<column name="comp_content"/>
</property>
<property name="state" type="java.lang.String">
<column name="state" length="1" />
</property>
<set name="complainreplies" inverse="true" lazy="false" cascade="save-update" order-by="reply_time">
<key>
<column name="comp_id" length="32" not-null="true" />
</key>
<one-to-many class="com.rk.tax.entity.Complainreply" />
</set>
</class>
</hibernate-mapping>
知识点(1):
<property name="isAnonymous" type="java.lang.Boolean">
<column name="is_anonymous" />
</property>
知识点(2):
<property name="compTime" type="java.sql.Timestamp">
<column name="comp_time" length="19" />
</property>
知识点(3):
<property name="compContent" type="text">
<column name="comp_content"/>
</property>
对应的类字段
private Boolean isAnonymous;
private Timestamp compTime;
private String compContent;
知识点(4):
<set name="complainreplies" inverse="true" lazy="false" cascade="save-update" order-by="reply_time">
<key>
<column name="comp_id" length="32" not-null="true" />
</key>
<one-to-many class="com.rk.tax.entity.Complainreply" />
</set>
其中
lazy="false" cascade="save-update" order-by="reply_time"
lazy="false"表示不使用懒加载,
cascade="save-update"表示级联保存、更新
order-by="reply-time"是指取出的数据按照reply-time排序。注意:reply_time是数据库的列的名称,这里也可以类的字段replyTime,但是类的字段replyTime与数据库的列名reply_time相比,类的字段replyTime可能在某些版本中存在问题,而数据库的列名reply_time更具有通用性。
<set name="complainreplies" inverse="true" lazy="false" cascade="save-update" order-by="reply_time desc">
另外,也可以对reply-time进行排序,如使用order-by="reply-time desc",它的默认值是asc,可以省略。
Complainreply.java
package com.rk.tax.entity;
import java.sql.Timestamp;
public class Complainreply implements java.io.Serializable {
// Fields
private String replyId;
private Complain complain;
private String replyer;
private String replyDept;
private Timestamp replyTime;
private String replyContent;
// Constructors
public Complainreply() {
}
public Complainreply(Complain complain) {
this.complain = complain;
}
public Complainreply(Complain complain, String replyer,
String replyDept, Timestamp replyTime, String replyContent) {
this.complain = complain;
this.replyer = replyer;
this.replyDept = replyDept;
this.replyTime = replyTime;
this.replyContent = replyContent;
}
public String getReplyId() {
return replyId;
}
public void setReplyId(String replyId) {
this.replyId = replyId;
}
public Complain getComplain() {
return complain;
}
public void setComplain(Complain complain) {
this.complain = complain;
}
public String getReplyer() {
return replyer;
}
public void setReplyer(String replyer) {
this.replyer = replyer;
}
public String getReplyDept() {
return replyDept;
}
public void setReplyDept(String replyDept) {
this.replyDept = replyDept;
}
public Timestamp getReplyTime() {
return replyTime;
}
public void setReplyTime(Timestamp replyTime) {
this.replyTime = replyTime;
}
public String getReplyContent() {
return replyContent;
}
public void setReplyContent(String replyContent) {
this.replyContent = replyContent;
}
}
Complainreply.hbm.xml
注意:在生成的映射文件中去掉 catalog=”数据库名称”。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.rk.tax.entity.Complainreply" table="t_complainreply">
<id name="replyId" type="java.lang.String">
<column name="reply_id" length="32" />
<generator class="uuid.hex" />
</id>
<many-to-one name="complain" class="com.rk.tax.entity.Complain" fetch="select">
<column name="comp_id" length="32" not-null="true" />
</many-to-one>
<property name="replyer" type="java.lang.String">
<column name="replyer" length="20" />
</property>
<property name="replyDept" type="java.lang.String">
<column name="reply_dept" length="100" />
</property>
<property name="replyTime" type="java.sql.Timestamp">
<column name="reply_time" length="19" />
</property>
<property name="replyContent" type="java.lang.String">
<column name="reply_content" length="300" />
</property>
</class>
</hibernate-mapping>
2、从dao到action
dao->service->action->config
2.1、dao层
ComplainDao.java
package com.rk.tax.dao;
import com.rk.core.dao.BaseDao;
import com.rk.tax.entity.Complain;
public interface ComplainDao extends BaseDao<Complain> {
}
ComplainDaoImpl.java
package com.rk.tax.dao.impl;
import com.rk.core.dao.impl.BaseDaoImpl;
import com.rk.tax.dao.ComplainDao;
import com.rk.tax.entity.Complain;
public class ComplainDaoImpl extends BaseDaoImpl<Complain> implements ComplainDao {
}
2.2、service层
ComplainService.java
package com.rk.tax.service;
import com.rk.core.service.BaseService;
import com.rk.tax.entity.Complain;
public interface ComplainService extends BaseService<Complain> {
}
ComplainServiceImpl.java
package com.rk.tax.service.impl;
import java.util.Calendar;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.rk.core.service.Impl.BaseServiceImpl;
import com.rk.core.utils.QueryHelper;
import com.rk.tax.dao.ComplainDao;
import com.rk.tax.entity.Complain;
import com.rk.tax.service.ComplainService;
@Service("complainService")
public class ComplainServiceImpl extends BaseServiceImpl<Complain> implements ComplainService {
private ComplainDao complainDao;
@Resource
public void setComplainDao(ComplainDao complainDao) {
setBaseDao(complainDao);
this.complainDao = complainDao;
}
}
2.3、action层
ComplainAction.java
package com.rk.tax.action;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.util.Date;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.opensymphony.xwork2.ActionContext;
import com.rk.core.action.BaseAction;
import com.rk.core.utils.QueryHelper;
import com.rk.tax.entity.Complain;
import com.rk.tax.entity.Complainreply;
import com.rk.tax.service.ComplainService;
@Controller("complainAction")
@Scope("prototype")
public class ComplainAction extends BaseAction {
private Complain complain;
private String startTime;
private String endTime;
private String state;
private Complainreply reply;
@Resource
private ComplainService complainService;
//列表
public String listUI(){
//加载状态集合
ActionContext.getContext().getContextMap().put("complainStateMap", Complain.COMPLAIN_STATE_MAP);
try {
QueryHelper queryHelper = new QueryHelper(Complain.class, "c");
if(StringUtils.isNotBlank(startTime)){//查询开始时间之后的投诉数据
startTime = URLDecoder.decode(startTime, "utf-8");
queryHelper.addCondition("c.compTime >= ?", DateUtils.parseDate(startTime+":00", "yyyy-MM-dd HH:mm:ss"));
}
if(StringUtils.isNotBlank(endTime)){//查询结束时间之前的投诉数据
endTime = URLDecoder.decode(endTime, "utf-8");
queryHelper.addCondition("c.compTime <= ?", DateUtils.parseDate(endTime+":00", "yyyy-MM-dd HH:mm:ss"));
}
if(StringUtils.isNotBlank(searchContent)){
searchContent = URLDecoder.decode(searchContent, "utf-8");
queryHelper.addCondition("c.compTitle like ?", "%" + searchContent + "%");
}
if(StringUtils.isNotBlank(state)){
queryHelper.addCondition("c.state=?", state);
}
//按照状态升序排序
queryHelper.addOrderByProperty("c.state", QueryHelper.ORDER_BY_ASC);
//按照投诉时间升序排序
queryHelper.addOrderByProperty("c.compTime", QueryHelper.ORDER_BY_ASC);
pageResult = complainService.getPageResult(queryHelper, pageNo, pageSize);
} catch (Exception e) {
e.printStackTrace();
}
return "listUI";
}
//跳转到受理页面
public String dealUI(){
//加载状态集合
ActionContext.getContext().getContextMap().put("complainStateMap", Complain.COMPLAIN_STATE_MAP);
if(complain != null && StringUtils.isNotBlank(complain.getCompId())){
complain = complainService.findById(complain.getCompId());
}
return "dealUI";
}
public String deal(){
if(complain != null && StringUtils.isNotBlank(complain.getCompId())){
Complain temp = complainService.findById(complain.getCompId());
//1、更新投诉的状态为 已受理
if(!Complain.COMPLAIN_STATE_DONE.equals(temp.getState())){
temp.setState(Complain.COMPLAIN_STATE_DONE);
}
//2、保存回复信息
if(reply != null){
reply.setComplain(temp);
reply.setReplyTime(new Timestamp(new Date().getTime()));
temp.getComplainreplies().add(reply);
}
complainService.update(temp);
}
return "list";
}
// Properties
public Complain getComplain() {
return complain;
}
public void setComplain(Complain complain) {
this.complain = complain;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Complainreply getReply() {
return reply;
}
public void setReply(Complainreply reply) {
this.reply = reply;
}
}
知识点(1):级联 保存、更新
在deal()方法中
Complain temp = complainService.findById(complain.getCompId());
//1、更新投诉的状态为 已受理
if(!Complain.COMPLAIN_STATE_DONE.equals(temp.getState())){
temp.setState(Complain.COMPLAIN_STATE_DONE);
}
//2、保存回复信息
if(reply != null){
reply.setComplain(temp);
reply.setReplyTime(new Timestamp(new Date().getTime()));
temp.getComplainreplies().add(reply);
}
complainService.update(temp);
最后只调用complainService.update(temp),而temp是Complain类型的变量,而真正想要保存的的reply变量,这是通过级联保存(更新)实现的,Complain.hbm.xml中设置了cascade="save-update"
<set name="complainreplies" inverse="true" lazy="false" cascade="save-update" order-by="reply_time">
<key>
<column name="comp_id" length="32" not-null="true" />
</key>
<one-to-many class="com.rk.tax.entity.Complainreply" />
</set>
2.4、config
entity层的配置就是*.hbm.xml文件
dao层的配置是将dao类加入到Spring的IOC容器中
service层的配置是将service类加入到Spring的IOC容器中
action层的配置是将action类加入到Spring的IOC容器中,并在struts中对action进行url映射
最后记得将spring和struts的配置都汇总到applicationContext.xml和struts.xml文件中
3、JSP页面
listUI.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%@include file="/common/header.jsp"%>
<title>投诉受理管理</title>
<script type="text/javascript" class="lazy" data-src="${basePath}/js/datepicker/WdatePicker.js"></script>
<script type="text/javascript">
var list_url = "${basePath}/tax/complain_listUI.action";
function doAnnualStatistic(){
// TODO
}
function doDeal(id){
document.forms[0].action = "${basePath}/tax/complain_dealUI.action?complain.compId="+id;
document.forms[0].submit();
}
</script>
</head>
<body class="rightBody">
<form name="form1" action="" method="post">
<div class="p_d_1">
<div class="p_d_1_1">
<div class="content_info">
<div class="c_crumbs"><div><b></b><strong>投诉受理管理</strong></div> </div>
<div class="search_art">
<li>
投诉标题:<s:textfield name="searchContent" cssClass="s_text" cssStyle="width:160px;"/>
</li>
<li>
投诉时间:<s:textfield id="startTime" name="startTime" cssClass="s_text" cssStyle="width:160px;" readonly="true"
onfocus="WdatePicker({'skin':'whyGreen','dateFmt':'yyyy-MM-dd HH:mm'})"/>
-
<s:textfield id="endTime" name="endTime" cssClass="s_text" cssStyle="width:160px;" readonly="true"
onfocus="WdatePicker({'skin':'whyGreen','dateFmt':'yyyy-MM-dd HH:mm'})"/>
</li>
<li>
状态:<s:select name="state" list="#complainStateMap" headerKey="" headerValue="全部"/>
</li>
<li><input type="button" class="s_button" value="搜 索" onclick="doSearch()"/></li>
<li >
<input type="button" value="统计" class="s_button" onclick="doAnnualStatistic()"/>
</li>
</div>
<div class="t_list" >
<table width="100%" border="0">
<tr class="t_tit">
<td align="center">投诉标题</td>
<td width="120" align="center">被投诉部门</td>
<td width="120" align="center">被投诉人</td>
<td width="140" align="center">投诉时间</td>
<td width="100" align="center">受理状态</td>
<td width="100" align="center">操作</td>
</tr>
<s:iterator value="pageResult.items" status="st">
<tr <s:if test="#st.odd"> bgcolor="f8f8f8" </s:if> >
<td align="center"><s:property value="compTitle"/></td>
<td align="center"><s:property value="toCompDept"/></td>
<td align="center"><s:property value="toCompName"/></td>
<td align="center"><s:date name="compTime" format="yyyy-MM-dd HH:mm"/></td>
<td align="center"><s:property value="#complainStateMap[state]"/></td>
<td align="center">
<a href="javascript:doDeal('<s:property value='compId'/>')">受理</a>
</td>
</tr>
</s:iterator>
</table>
</div>
</div>
<%@include file="/common/pageNavigator.jsp" %>
</div>
</div>
</form>
</body>
</html>
知识点(1):WDatePicker
<script type="text/javascript" class="lazy" data-src="${basePath}/js/datepicker/WdatePicker.js"></script>
<s:textfield id="startTime" name="startTime" cssClass="s_text" cssStyle="width:160px;" readonly="true"
onfocus="WdatePicker({'skin':'whyGreen','dateFmt':'yyyy-MM-dd HH:mm'})"/>
知识点(2):<s:select>
<s:select name="state" list="#complainStateMap" headerKey="" headerValue="全部"/>
dealUI.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%@include file="/common/header.jsp"%>
<title>投诉受理管理</title>
</head>
<body class="rightBody">
<form id="form" name="form" action="${basePath}/tax/complain_deal.action" method="post" enctype="multipart/form-data">
<div class="p_d_1">
<div class="p_d_1_1">
<div class="content_info">
<div class="c_crumbs"><div><b></b><strong>投诉受理管理</strong> - 投诉受理</div></div>
<div class="tableH2">投诉详细信息<span >(已受理)</span></div>
<table id="baseInfo" width="100%" align="center" class="list" border="0" cellpadding="0" cellspacing="0" >
<tr><td colspan="2" align="center">投诉人信息</td></tr>
<tr>
<td class="tdBg" width="250px">是否匿名投诉:</td>
<td><s:property value="complain.isAnonymous?'匿名投诉':'非匿名投诉'"/></td>
</tr>
<tr>
<td class="tdBg">投诉人单位:</td>
<td>
<s:if test="!complain.isAnonymous">
<s:property value="complain.compCompany"/>
</s:if>
</td>
</tr>
<tr>
<td class="tdBg">投诉人姓名:</td>
<td>
<s:if test="!complain.isAnonymous">
<s:property value="complain.compName"/>
</s:if>
</td>
</tr>
<tr>
<td class="tdBg">投诉人手机:</td>
<td>
<s:if test="!complain.isAnonymous">
<s:property value="complain.compMobile"/>
</s:if>
<s:elseif test="complain.compMobile.length() > 10">
<s:property value="complain.compMobile.substring(0,3) + '****' + complain.compMobile.substring(7,11)"/>
</s:elseif>
<s:else>
<s:property value="complain.compMobile"/>
</s:else>
</td>
</tr>
<tr><td colspan="2" align="center">投诉信息</td></tr>
<tr>
<td class="tdBg">投诉时间:</td>
<td>
<s:date name="complain.compTime" format="yyyy-MM-dd HH:mm"/>
</td>
</tr>
<tr>
<td class="tdBg">被投诉部门:</td>
<td><s:property value="complain.toCompDept"/></td>
</tr>
<tr>
<td class="tdBg">被投诉人:</td>
<td><s:property value="complain.toCompName"/></td>
</tr>
<tr>
<td class="tdBg">投诉标题:</td>
<td><s:property value="complain.compTitle"/></td>
</tr>
<tr>
<td class="tdBg">投诉内容:</td>
<td><s:property value="complain.compContent" escape="false"/></td>
</tr>
<tr><td colspan="2" align="center">受理信息</td></tr>
<tr>
<td colspan="2">
<s:iterator value="complain.complainreplies" status="st">
<fieldset ><legend >回复<s:property value="#st.count"/> </legend>
<div >
回复部门:<s:property value="replyDept"/>
回复人:<s:property value="replyer"/>
回复时间:<s:date name="replyTime" format="yyyy-MM-dd HH:mm"/>
</div>
<div >
<s:property value="replyContent"/>
</div>
</fieldset>
</s:iterator>
</td>
</tr>
<tr><td colspan="2" align="center">受理操作</td></tr>
<tr>
<td class="tdBg">回复部门:</td>
<td>
<s:property value="#session.SYS_USER.dept"/>
<s:hidden name="reply.replyDept" value="%{#session.SYS_USER.dept}"/>
</td>
</tr>
<tr>
<td class="tdBg">回复人:</td>
<td>
<s:property value="#session.SYS_USER.name"/>
<s:hidden name="reply.replyer" value="%{#session.SYS_USER.name}"/>
</td>
</tr>
<tr>
<td class="tdBg" width="200px">回复内容:</td>
<td><s:textarea name="reply.replyContent" cols="90" rows="8" /></td>
</tr>
</table>
<s:hidden name="complain.compId"/>
<div class="tc mt20">
<input type="submit" class="btnB2" value="保存" />
<input type="button" onclick="javascript:history.go(-1)" class="btnB2" value="返回" />
</div>
</div></div></div>
</form>
</body>
</html>
知识点(1):OGNL字符中长度判断 和 拼接
<s:elseif test="complain.compMobile.length() > 10">
<s:property value="complain.compMobile.substring(0,3) + '****' + complain.compMobile.substring(7,11)"/>
</s:elseif>
知识点(2):<s:date>
<s:date name="complain.compTime" format="yyyy-MM-dd HH:mm"/>
知识点(3):<s:property>和<s:hidden> 似乎对OGNL的支持不同
<s:property value="#session.SYS_USER.name"/>
<s:hidden name="reply.replyer" value="%{#session.SYS_USER.name}"/>
知识点(4):escape
<td class="tdBg">投诉内容:</td>
<td><s:property value="complain.compContent" escape="false"/></td>
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341