说一下需求:这个功能类似于邮件功能,当用户在站点中提交一些建议及意见后。后台将其存入到Oracle数据库中。然后管理员登录站点,会看到还没有读过以及读过的意见及建议,并能够将未读过的意见及建议标记为已读。
以下上图。这是管理员的查看界面:
点击已读切换到这个界面:
以下開始贴出代码。
首先我们须要一个Tab切换选项卡,CSS代码例如以下:
.tabPanel ul{height:30px;border-bottom:1px solid #aaa;} .tabPanel ul li{ float:left;margin:0 2px 0 0;border:1px solid #aaa;font-size:14px;height:29px;line-height:30px;111px;text-align:center;cursor:pointer; text-shadow:0 1px 0 #fff; border-radius:4px 4px 0 0; box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.5); background:#ddd; background:-moz-linear-gradient(top, #eee, #ddd); background:-webkit-gradient(linear, left top, left bottom, from(#eee), to(#ddd)); } .tabPanel .hit{ border-bottom:1px solid #fff;cursor:pointer;color:black;text-shadow:0 1px 0 #fff; background:#fff; background:-webkit-gradient(linear, left top, left bottom, from(#e1e1e1), to(#fff)); background:-moz-linear-gradient(top, #e1e1e1, #fff); } .pane{border:1px solid #aaa;border-top:0;min-height:100px;background-color:#fff;display:none;} .pane p{padding:15px 15px 0 10px;} .pane h4{padding:15px 15px 0 10px;font-size:18px;font-weight:bold;}
还须要一小段JS来控制tab选项卡,给它赋hit的class和移除hit的class已完毕点击切换效果:
<script type="text/javascript"> $(function(){ $('.tabPanel ul li').click(function(){ $(this).addClass('hit').siblings().removeClass('hit'); $('.panes>div:eq('+$(this).index()+')').show().siblings().hide(); }) }) </script>
这个部分是从网上找的,你也能够自己写一个合适的。
选项卡的HTML模板代码例如以下:
<div class="tabPanel"> <ul> <li class="hit">Tab1</li> <li>Tab2</li> <li>Tab3</li> </ul> <div class="panes"> <div class="pane" style="display:block;"><h4>First tab content</h4><p>First tab content</p></div> <div class="pane"><h4>Secend tab content</h4><p>First tab content</p></div> <div class="pane"><h4>Third tab content</h4><p>First tab content</p></div> </div> </div>
前端部分大致完毕!
接下来写后台。
首先我们看一下数据库的表结构:
然后依据此表字段写action代码。这里面,我们主要有两个操作,一是查询出全部的表中数据然后将其分别放在两个Tab选项中;第二个操作则是将看过的信息标记为已读。在这里我仅仅写一个action类,用flag字段来推断进行哪个操作。当flag=1时进行第一个操作;当flag=3时进行第二个操作。
这样我的action类代码例如以下:
package com.cn.useraction; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; //import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.cn.beans.UserBean; import com.cn.util.DBConnection; @SuppressWarnings({ "serial", "unused" }) public class AdminCommentAction extends ActionSupport { private static Log log = LogFactory.getLog(AdminCommentAction.class); private List<UserBean> userlist; private String commentid; private String flag; static int i = 0; public String getCommentid() { return commentid; } public void setCommentid(String commentid) { this.commentid = commentid; } public String getFlag() { return flag; } public void setFlag(String flag) { this.flag = flag; } public List<UserBean> getUserlist() { return userlist; } public void setUserlist(List<UserBean> userlist) { this.userlist = userlist; } /** * 查看用户意见及建议 * * @return List<UserBean> list */ private List<UserBean> adminComment() { log.info("get admin comment info ..."); List<UserBean> list = new ArrayList<UserBean>(); UserBean user; String sql=null; Connection conn = DBConnection.getConn(); sql ="select * from ts_comment order by create_date desc "; PreparedStatement pstmt; try { pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { user = new UserBean(); user.setUsername(rs.getString("username")); user.setContact(rs.getString("contact")); user.setComment(rs.getString("commented")); user.setCommentid(rs.getString("comment_id")); user.setAdminflag(rs.getString("admin_flag")); user.setDate(rs.getString("create_date")); list.add(user); } } catch (SQLException e) { e.printStackTrace(); } return list; } /** * 管理员标记已读 * * @return i */ private static int adminflagUpdate(String commentid) { Connection conn = DBConnection.getConn(); String sql=null; sql ="update ts_comment set admin_flag=1 where comment_id='"+commentid+"'"; PreparedStatement pstmt; try { pstmt = conn.prepareStatement(sql); i = pstmt.executeUpdate(); System.out.println("update resutl: " + i); pstmt.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } return i; } public String admin_comment() throws Exception { log.info("admin_comment.action..."); if (flag.equals("3")) { //标记已读的操作 System.out.println(commentid); adminflagUpdate(commentid); if (i==0) { return "error"; } else { return "success_read"; } } else { userlist = adminComment(); if (userlist.size() > 0) { return "success"; } else { return "error"; } } } }
UserBean我就不贴了,就是几个get和set。
触发这个action的前台代码例如以下(即从一个界面跳转到这个界面):
<input style="cursor:pointer;border-radius:4px 4px 4px 4px;padding:5px;100%;margin:2px 0;" type="button" onclick="window.location.href='admin_comment.action?flag=0'" value="查看用户意见建议">
另外这里有个小技巧,就是我点击“标记为已读”后,直接页面刷新,显示操作后的结果,而不跳转到其他界面。这就用到了struts2的一个action跳转到还有一个action的功能,即完毕第二个操作的action后,跳转到第一个操作的action。这里面,struts.xml应该这么配置:
<action name="admin_comment" class="com.cn.useraction.AdminCommentAction" method="admin_comment"> <result name="success">/admin_comment.jsp</result> <result name="success_read" type="redirectAction">/admin_comment.action?flag=1</result> <result name="error">/error.jsp</result> </action>
后台结束。
最后就是前端的显示了。
我是从后台将未读的数据和已读的数据(数据库中admin_flag各自等于0和1)都查询出来,在前端须要分类显示,这时候就用到了struts2的<s:if>标签了,即admin_flag=0的数据放到未读中,等于1的数据放到已读中。
最后再加一些CSS特效,就形成上面的样子了。
这部分前端代码例如以下(替换掉上面Tab选项卡的模板代码):
<div class="tabPanel" style="900px;margin:30px auto;"> <ul style="list-style:none;"> <li class="hit">未读</li> <li>已读</li> </ul> <div class="panes"> <div class="pane" style="display:block;"><h4>用户意见及建议</h4> <p> <s:iterator value="userlist" var="user"> <s:if test="#user.adminflag == 0"> <li style="list-style:none;margin:22px 10px 2px 10px;padding:0 5px;background:#bcbcbc;clear:both;" id="title"> 用户 <b><s:property value="username" /></b> 的留言(联系方式:<b><s:property value="contact" /></b>)说: <input type="button" value="标记为已读" style="float:right;margin:7px 0 0 0;" onclick="window.location.href='admin_comment.action?flag=3&commentid=<s:property value="commentid" />'"></input> <span style="float:right;margin:0 15px 0 0;"><s:property value="date" /></span></li> <li style="list-style:none;margin:0 30px;" id="comment"><s:property value="comment" /></li> </s:if></s:iterator> </p> </div> <div class="pane"><h4>用户意见及建议</h4> <p> <s:iterator value="userlist" var="user"> <s:if test="#user.adminflag == 1"> <li style="list-style:none;margin:22px 10px 2px 10px;padding:0 5px;background:#bcbcbc;clear:both;" id="title"> 用户 <b><s:property value="username" /></b> 的留言(联系方式:<b><s:property value="contact" /></b>)说: <span style="float:right;margin:0 15px 0 0;"><s:property value="date" /></span></li> <li style="list-style:none;margin:0 30px;" id="comment"><s:property value="comment" /></li> </s:if></s:iterator> </p> </div> </div> </div>
这样整个由前到后由后到前的一个过程就完毕了。效果还是不错的!