欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

kFeedback开源啦

程序员文章站 2024-03-18 09:16:22
...

kFeedback的更多介绍,请详见:http://my.oschina.net/kzhou/blog/98855

为什么开发kFeedback?

我像很多人一样,平时在闲暇之余做一些app,本人的作品主要有:


  1. 基于HTML5(jQuery Mobile)的企业通讯录,后来通过PhoneGap封装成apk,她的名字是kLink。目前使用人数350人;
  2. 黑龙江省交通违章信息推送系统,当你的车有交通违法信息时,会通过短信息第一时间通知车主;目前使用人数200人
  3. ... ...

今后还会有更多的app发布,我在想,好的app离不开用户的反馈,如果每一个app内嵌一个反馈(又叫留言)的话,反馈信息会分散,不利于作者进行统一的受理,所以才有了今天的kFeedback。kFeedback发布几天来,目前已有60人在试用,而我现在唯一担心的是,CloudFoundry能不能顶住?

废话不多说了,接下来我将kFeedback源码发出,感兴趣的朋友可以参考,由于系统比较简单,我想下边的源码可能也就会对初学者有点帮助,老手们不要“耻笑”。

kFeedback用了哪些技术?


jsp + html5 + BootStrap + jQuery + servlet + spring(jdbcTemplate) + mySQL 

源码:

工程目录结构:

kFeedback开源啦

Action.java - 一个DispatchServlet

Demo.java - 一个基于HttpClient的测试类

Service.java - 封装了所有业务的Dao

index.jsp - 首页

main.jsp - 主页面

其它的没啥了,都是一些基本(标准)的配置文件。

我们从Service.java说起:

code:

package k.feedback;

import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.jdbc.core.JdbcTemplate;

import sun.misc.BASE64Encoder;

import com.alibaba.fastjson.JSON;

public class Service {

final static int PAGE_QTY = 15;//每页展示的记录数

private JdbcTemplate jdbcTemplate;

public void setDataSource(DataSource dataSource) {
	this.jdbcTemplate = new JdbcTemplate(dataSource);
}

//初始化数据库表结构
public void initDB(){
	//drop table
	this.jdbcTemplate.execute("drop table IF EXISTS feedback");
	this.jdbcTemplate.execute("drop table IF EXISTS app");
	this.jdbcTemplate.execute("drop table IF EXISTS emp");
	System.out.println("table drop ok");
	
	StringBuilder emp = new StringBuilder();
	emp.append(" CREATE TABLE emp(                              ");
	emp.append("     emp_id           INT       AUTO_INCREMENT, ");
	emp.append("     emp_email        VARCHAR(128),             ");
	emp.append("     emp_login_pwd    VARCHAR(40),             ");
	emp.append("     cdate            TIMESTAMP,                ");
	emp.append("     PRIMARY KEY (emp_id)                       ");
	emp.append(" )ENGINE=MYISAM                                 ");

	StringBuilder app = new StringBuilder();
	app.append(" CREATE TABLE app(                                ");
	app.append("     app_id       INT             AUTO_INCREMENT, ");
	app.append("     emp_id       INT,                            ");
	app.append("     app_name     VARCHAR(255),                   ");
	app.append("     app_desc     VARCHAR(255),                   ");
	app.append("     app_token    VARCHAR(40),                   ");
	app.append("     app_feedback_qty    INT,                   ");
	app.append("     cdate        TIMESTAMP,                      ");
	app.append("     PRIMARY KEY (app_id)                         ");
	app.append(" )ENGINE=MYISAM                                   ");

	StringBuilder feedback = new StringBuilder();
	feedback.append(" CREATE TABLE feedback(					  ");
	feedback.append("     feedback_id      INT    AUTO_INCREMENT, ");
	feedback.append("     emp_id           INT,                   ");
	feedback.append("     app_id           INT,                   ");
	feedback.append("     feedback_time    TIMESTAMP,             ");
	feedback.append("     feedback_info    TEXT,         		  ");
	feedback.append("     PRIMARY KEY (feedback_id)               ");
	feedback.append(" )ENGINE=MYISAM                              ");

	String alter1 = "ALTER TABLE app ADD CONSTRAINT Refemp1 FOREIGN KEY (emp_id) REFERENCES emp(emp_id)";
	String alter2 = "ALTER TABLE feedback ADD CONSTRAINT Refemp2 FOREIGN KEY (emp_id) REFERENCES emp(emp_id)";
	String alter3 = "ALTER TABLE feedback ADD CONSTRAINT Refapp3 FOREIGN KEY (app_id) REFERENCES app(app_id)";

	String createIndex4Emp = "create unique index idx_email_pwd on emp(emp_email,emp_login_pwd)";
	String createIndex4App = "create unique index idx_token on app(app_token)";
	
	this.jdbcTemplate.execute(emp.toString());
	System.out.println("emp table created");
	this.jdbcTemplate.execute(app.toString());
	System.out.println("app table created");
	this.jdbcTemplate.execute(feedback.toString());
	System.out.println("feedback table created");
	this.jdbcTemplate.execute(alter1);
	this.jdbcTemplate.execute(alter2);
	this.jdbcTemplate.execute(alter3);
	System.out.println("alter ok");
	this.jdbcTemplate.execute(createIndex4Emp);
	this.jdbcTemplate.execute(createIndex4App);
	//创建默认账户
	this.jdbcTemplate.update("INSERT INTO emp(emp_id,emp_email, emp_login_pwd ) values(1,?,?)","aaa@qq.com",encodeByMd5("111111"));
	System.out.println("kFeedback default user create ok");
	//创建默认app
	this.jdbcTemplate.update("INSERT INTO app(app_id, emp_id, app_name, app_desc, app_token, app_feedback_qty)	VALUES (1, 1, 'kFeedback-云反馈', '把你的产品反馈信息放在云上进行统一管理', 'kFeedback', 0)");
	System.out.println("kFeedback default app create ok");
	System.out.println("kFeedback db create ok");
}

//开发者注册
public int reg(String email,String pwd){
	//check email is exist
	int rv = this.jdbcTemplate.queryForInt("select count(*) from emp where emp_email = ?",email);
	if(rv == 0){
		final String sql = "INSERT INTO emp(emp_email, emp_login_pwd ) values(?,?)";
		return this.jdbcTemplate.update(sql,email,encodeByMd5(pwd));
	}else{
		return -999;
	}
}
//开发者修改密码
public void updPwd(String empId,String newPwd){
	final String sql = "update emp set emp_login_pwd = ? where emp_id = ?";
	this.jdbcTemplate.update(sql,encodeByMd5(newPwd),empId);
}
//登录
public String login(String email,String pwd){
	final String sql = "select convert(emp_id,char) as emp_id,emp_email from emp where emp_email = ? and emp_login_pwd = ?";
	Map<String,Object> map = new HashMap<String,Object>();
	try {
		map = this.jdbcTemplate.queryForMap(sql,email,encodeByMd5(pwd));
		map.put("result", "1");
		return JSON.toJSONString(map);
	} catch (Exception e) {
		map.put("result", "0");
		return JSON.toJSONString(map);
	}
}
//忘记密码
public int forgetPwd(String email){
	int rv = this.jdbcTemplate.queryForInt("select count(*) from emp where emp_email = ?",email);
	if(rv > 0){
		//get new pwd
		String newPwd = this.getAppToken();
		//upd emp pwd
		this.jdbcTemplate.update("update emp set emp_login_pwd = ? where emp_email = ?",encodeByMd5(newPwd),email);
		//send new pwd to email box
		StringBuilder msg = new StringBuilder();
		msg.append("您好,您的kFeedback新密码为:").append(newPwd).append("\n\n").append("请重新登录;http://kfeedback.cloudfoundry.com");
		this.sendEmail("来自kFeedback的密码重置邮件", email, msg.toString());
		return 1;//成功
	}else{
		return 0;
	}
}
//新增产品-strings[0],strings[1],strings[2]=emp_id,app_name,app_desc
public void insApp(String...strings){
	final String sql = "INSERT INTO app (emp_id, app_name, app_desc,app_feedback_qty, app_token) values(?,?,?,0,?)";
	this.jdbcTemplate.update(sql,strings[0],strings[1],strings[2],getAppToken());
}
//删除产品
public void delApp(String appId){
	this.jdbcTemplate.update("delete from feedback where app_id = ?",appId);
	this.jdbcTemplate.update("delete from app where app_id = ?",appId);
}
//修改产品-strings[0],strings[1],strings[2]=app_name,app_desc,app_id
public void updApp(String...strings){
	final String sql = "update app set app_name=?,app_desc=? where app_id = ?";
	this.jdbcTemplate.update(sql,strings[0],strings[1],strings[2]);
}
//查询产品
public String getApp(String empId){
	if(empId.equals("1")){
		return JSON.toJSONString(this.jdbcTemplate.queryForList("select convert(app_id,char) as app_id,convert(emp_id,char) as emp_id,app_name,app_desc,app_token,convert(app_feedback_qty,char) as app_feedback_qty,convert(DATE_FORMAT(cdate,'%Y-%m-%d'),char) as cdate from app where emp_id = ?",empId));
	}else{
		return JSON.toJSONString(this.jdbcTemplate.queryForList("select convert(app_id,char) as app_id,convert(emp_id,char) as emp_id,app_name,app_desc,app_token,convert(app_feedback_qty,char) as app_feedback_qty,convert(DATE_FORMAT(cdate,'%Y-%m-%d'),char) as cdate from app where app_id = 1 union all select convert(app_id,char) as app_id,convert(emp_id,char) as emp_id,app_name,app_desc,app_token,convert(app_feedback_qty,char) as app_feedback_qty,convert(DATE_FORMAT(cdate,'%Y-%m-%d'),char) as cdate from app where emp_id = ?",empId));
	}
}
//根据app_token反查app_id
private Map<String,Object> getAppIdByToken(String token){
	return this.jdbcTemplate.queryForMap("select convert(a.emp_id,char) as emp_id,convert(a.app_id,char) as app_id,e.emp_email,a.app_name from app a,emp e where a.emp_id = e.emp_id and a.app_token = ?",token);
}
//根据产品查询反馈信息
public String getFeedback(String appId){
	final String sql = "select convert(feedback_id,char) as feedback_id,convert(DATE_FORMAT(feedback_time,'%Y-%m-%d %H:%i:%s'),char) as feedback_time,feedback_info from feedback where app_id = ? order by feedback_time";
	return JSON.toJSONString(this.jdbcTemplate.queryForList(sql,appId));
}
//删除反馈信息
public void delFeedback(String feedbackId){
	this.jdbcTemplate.update("delete from feedback where feedback_id = ?",feedbackId);
}

//开放api
//新增反馈-strings[0],strings[1]]=app_token,feedback_info
public void insFeedback(String...strings){
	Map<String,Object> map = getAppIdByToken(strings[0]);
	String appId = map.get("app_id").toString();
	final String sql = "INSERT INTO feedback (emp_id, app_id, feedback_info) values(?,?,?)";
	this.jdbcTemplate.update(sql,map.get("emp_id"),appId,strings[1]);
	int feedbackQty = this.jdbcTemplate.queryForInt("select count(*) from feedback where app_id = ?",appId);
	this.jdbcTemplate.update("update app set app_feedback_qty=? where app_id = ?",feedbackQty,appId);
	//send email to app creator
//		StringBuilder msgTitle = new StringBuilder();
//		msgTitle.append("[来自kFeedback]:您的<").append(map.get("app_name").toString()).append(">App收到了新的反馈信息");
//		StringBuilder msg = new StringBuilder();
//		msg.append("[来自kFeedback]:您的<").append(map.get("app_name").toString()).append(">App收到了新的反馈信息").append("\n\n");
//		msg.append("新的反馈信息为:\n\n");
//		msg.append("TA说:  ").append(strings[1]).append("\n\n").append("请访问;http://kfeedback.cloudfoundry.com").append("\n\n");
//		this.sendEmail(msgTitle.toString(), map.get("emp_email").toString(), msg.toString());
}
//开发api end


//MD5
private String encodeByMd5(String str) {
	MessageDigest md5;
	try {
		md5 = MessageDigest.getInstance("MD5");
		BASE64Encoder base64en = new BASE64Encoder();
		return base64en.encode(md5.digest(str.getBytes("utf-8")));
	} catch (Exception e) {
		return str;
	}
}
//UUID
public String getAppToken(){
	return System.currentTimeMillis()+"";
}

/**
 * 发送电子邮件
 * @param title
 * @param emailAddr
 * @param msg
 * @throws EmailException
 */
public void sendEmail(String title,String emailAddr,String msg){
	try {
		Email email = new SimpleEmail();
		email.setHostName("smtp.163.com");
		email.setAuthentication("username", "password");
		email.setFrom("aaa@qq.com");
		email.setSubject(title);
		email.setCharset("utf8");
		email.setMsg(msg);
		email.addTo(emailAddr);
		email.send();
	} catch (Exception e) {
	}
}
}


Action.java

code:

package k.feedback;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * Servlet implementation class Action
 */
public class Action extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private WebApplicationContext ctx = null;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Action() {
        super();
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		ctx = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		request.setCharacterEncoding("utf-8");
//		response.setCharacterEncoding("utf-8");
		response.setHeader("Cache-Control", "no-cache"); 
		response.setContentType("text/javascript");
		Service service = (Service)ctx.getBean("service");
		String callback = request.getParameter("callback");
		String method = request.getParameter("m");
		System.out.println("request method : " + method);
		if(method == null || method.trim().length() == 0){
			response.getWriter().print("您的请求是非法的!");
		}else{
		 if(method.equals("login")){
				this.login(service,request,response,callback);
			}else if(method.equals("reg")){
				this.reg(service,request,response,callback);
			}else if(method.equals("updPwd")){
				this.updPwd(service,request,response,callback);
			}else if(method.equals("insApp")){
				this.insApp(service,request,response,callback);
			}else if(method.equals("getApp")){
				this.getApp(service,request,response,callback);
			}else if(method.equals("getFeedback")){
				this.getFeedback(service,request,response,callback);
			}else if(method.equals("updApp")){
				this.updApp(service,request,response,callback);
			}else if(method.equals("delApp")){
				this.delApp(service,request,response,callback);
			}else if(method.equals("insFeedback")){
				this.insFeedback(service,request,response,callback);
			}
		}
	}

	private void insFeedback(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String token = request.getParameter("token");
		String fb = request.getParameter("fb");
		service.insFeedback(token,fb);
		response.getWriter().write(callback+"({\"result\" : \"1\"})");
	}

	private void delApp(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String appId =request.getParameter("appId");
		service.delApp(appId);
		response.getWriter().write(callback+"({\"result\" : \"1\"})");
	}

	private void updApp(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String appId = request.getParameter("appId");
		String appName = request.getParameter("appName");
		String appDesc = request.getParameter("appDesc");
		service.updApp(appName,appDesc,appId);
		response.getWriter().write(callback+"({\"result\" : \"1\"})");
	}

	private void getFeedback(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String appId = request.getParameter("appId");
		String feedbackJson = service.getFeedback(appId);
		response.getWriter().write(callback+"("+feedbackJson+")");
	}

	private void getApp(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String empId = request.getParameter("empId");
		String appJson = service.getApp(empId);
		response.getWriter().write(callback+"("+appJson+")");
	}

	private void insApp(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String empId = request.getParameter("empId");
		String appName = request.getParameter("appName");
		String appDesc = request.getParameter("appDesc");
		service.insApp(empId,appName,appDesc);
		response.getWriter().write(callback+"({\"result\" : \"1\"})");
	}

	private void updPwd(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String empId = request.getParameter("empId");
		String newPwd = request.getParameter("newPwd");
		service.updPwd(empId, newPwd);
		response.getWriter().write(callback+"({\"result\" : \"1\"})");
	}

	private void reg(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException {
		String reg_email = request.getParameter("reg_email");
		String reg_pwd = request.getParameter("reg_pwd");
		int rv = service.reg(reg_email, reg_pwd);
		String output = callback+"({})";
		if(rv == 1){
			output = callback+"({\"result\" : \"1\"})";//reg成功
		}else{
			output = callback+"({\"result\" : \"0\"})";//reg失败
		}
		response.getWriter().write(output);
	}

	private void login(Service service, HttpServletRequest request,HttpServletResponse response, String callback) throws IOException, ServletException {
		String email = request.getParameter("email");
		String pwd = request.getParameter("pwd");
		String loginInfo = service.login(email, pwd);
		response.getWriter().write(callback+"("+loginInfo+")");
	}
}
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
    <title>kFeedback - 云反馈!</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="feedback system on Cloud Foundry">
    <meta name="author" content="zhoukai">

    <!-- Le styles -->
    <link href="css/bootstrap.css" rel="stylesheet">
    <style type="text/css">
      body {
        padding-top: 15px;
      }
    </style>
    <link href="css/bootstrap-responsive.css" rel="stylesheet">

    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>
  <body>
    <div class="container">

      <!-- Main hero unit for a primary marketing message or call to action -->
      <div class="hero-unit">
		<h1>kFeedback - 云反馈!</h1>
		<p>kFeedback是一个极简主义作品。</p>
		<p>成功的产品离不开用户的反馈;kFeedback就是你的产品与最终用户之间的沟通桥梁。</p>
      </div>

      <!-- Example row of columns -->
      <div class="row">
        <div class="span4">
			<blockquote>
				<p><strong>kFeedback基本路径(Guide).</strong></p>
				<small>kFeedback使用指南</small>
			</blockquote>
			<p>
				<ol>
				<li>注册kFeedback账号(Reg account)</li>
				<li>登录kFeedback(Login)</li>
				<li>创建App(New app)</li>
				<li>将系统生成的API嵌入到你的产品中(Embed kFeedback post-api in your projduct)</li>
				<li>OK</li>
				</ol>
			</p>
        </div>
        <div class="span4">
			<blockquote>
				<p><strong>登录kFeedback系统(Login).</strong></p>
				<small>用您注册的电子邮件和密码登录系统</small>
			</blockquote>
			<p>
				<label class="control-label" for="login_email">电子邮件(Email)</label>
				  <input type="text" id="login_email" placeholder="Email">
				<label class="control-label" for="login_pwd">登录密码(Password)</label>
				  <input type="password" id="login_pwd" placeholder="Password">
				<p>
				  <button id="btn_login" class="btn btn-primary">登录(Login now!)</button>
				</p>
			</p>
       </div>
        <div class="span4">
			<blockquote>
				<p><strong>注册kFeedback账号(Register).</strong></p>
				<small>提供您的电子邮件及登录密码,瞬间即可完成注册</small>
			</blockquote>		  
			<p>
				<label class="control-label" for="reg_email">电子邮件</label>
				  <input type="text" id="reg_email" placeholder="Login email">
				<label class="control-label" for="reg_pwd">登录密码</label>
				  <input type="password" id="reg_pwd" placeholder="Login pwd">
				<label class="control-label" for="reg_repwd">确认密码</label>
				  <input type="password" id="reg_repwd" placeholder="Confirm pwd">
				<p><button id="btn_reg" class="btn btn-primary">注册(Register now!)</button></p>
			</p>
        </div>
      </div>

      <hr>

      <footer>
		<div class="row">
			<div class="span4">&copy; <i class="icon-user"></i>恺哥作品 - <a href="mailto:aaa@qq.com?subject=to 恺哥">aaa@qq.com</a></div>
			<div class="span4"></div>
			<div class="span4">
				<a target="_blank" href="http://www.oschina.net" title="OSChina"><img src="img/osc.ico" alt="OSChina"></a>
				<a target="_blank" href="http://www.cloudfoundry.com/" title="CloudFoundry"><img src="img/cf.ico" alt="Cloudfoundry"></a>
				<a target="_blank" href="http://twitter.github.com/bootstrap/" title="Bootstrap"><img src="img/bootstrap.ico" alt="Bootstrap"></a>
			</div>
		</div>
      </footer>


	<!-- dialog -->
		<div id="myAlertModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
              <h3 id="myModalLabel">kFeedback信息提示窗</h3>
            </div>
            <div class="modal-body">
            	<div id="alertInfo"></div>
            </div>
            <div class="modal-footer">
              <button class="btn" data-dismiss="modal">Close</button>
            </div>
        </div>

    </div> <!-- /container -->
				
    <!-- Le javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="js/jquery-1.8.3.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/javascript">
    	var app = "http://kfeedback.cloudfoundry.com";
	    var url = app + "/Action?callback=?";
	    $(document).ready(function() {
	    	//login email focus
	    	var localStorageLoginInfo = localStorage.getItem("login_email");
	    	if(!$.isEmptyObject(localStorageLoginInfo)){
	    		$("#login_email").val(localStorageLoginInfo);
	    		$("#login_pwd").focus();
	    	}else{
		    	$("#login_email").focus();
	    	}
	    	
	    	$("#btn_reg").click(function(){
	    		var reg_email = $("#reg_email").val();
	    		var reg_pwd = $("#reg_pwd").val();
	    		var reg_repwd = $("#reg_repwd").val();
	    		var alertInfo = checkRegForm(reg_email,reg_pwd,reg_repwd);
	    		if($.isEmptyObject(alertInfo)){
	        		$.getJSON(url,{m:"reg",reg_email:reg_email,reg_pwd:reg_pwd},function(json){
	        			if(json.result == "1"){
	        				//init login form
	        				$("#login_email").val(reg_email);
	        				$("#login_pwd").val(reg_pwd);
	        				$("#alertInfo").html("<p class=\"text-success\">账号注册成功,请登录kFeedback!</p>");
	        				$('#myAlertModal').modal('show');
	        			}else{
	        				$("#alertInfo").html("<p class=\"text-error\">账号注册失败,您提供的电子邮件已被使用,请重新尝试!</p>");
	        				$('#myAlertModal').modal('show');
	        			}
	        		});
	    		}else{
					$("#alertInfo").html(alertInfo);
					$('#myAlertModal').modal('show');
		    	}
	    	});
	    	
	    	$("#login_pwd").keydown(function(e){
	    		if(e.keyCode==13){ //回车
	    			$("#btn_login").click();
	    		}
	    	});
	    	
	    	$("#btn_login").click(function(){
	    		var login_email = $("#login_email").val();
	    		var login_pwd = $("#login_pwd").val();
				if($.isEmptyObject(login_email) || $.isEmptyObject(login_pwd)){
    				$("#alertInfo").html("<p class=\"text-error\">登录时,电子邮件和登录密码是必须的.</p>");
    				$('#myAlertModal').modal('show');
				}else{
	        		$.getJSON(url,{m:"login",email:login_email,pwd:login_pwd},function(json){
	        			if(json.result == "0"){
	        				$("#alertInfo").html("<p class=\"text-error\">登录失败,用户名或密码错误,请重新尝试!</p>");
	        				$('#myAlertModal').modal('show');
	        			}else{
	    					sessionStorage.setItem("email", login_email);
	    					sessionStorage.setItem("empId", json.emp_id);
	    					localStorage.setItem("login_email",login_email);
	        				location.href=app+"/main.jsp";
	        			}
	        		});
				}

	    	});
	  	});
	    
	    //check reg form
	    function checkRegForm(reg_email,reg_pwd,reg_repwd){
	    	var alertInfo = "";
			//check reg_email
			if($.isEmptyObject(reg_email)){
				alertInfo += "<p class=\"text-error\">注册时,电子邮件不能为空.</p>";
			}
			if(!verifyEmail(reg_email)){
				alertInfo += "<p class=\"text-error\">您提供的电子邮件格式不合法.</p>";
			}
			if($.isEmptyObject(reg_pwd)){
				alertInfo += "<p class=\"text-error\">注册时,登录密码不能为空.</p>";
		  		}
			if(reg_pwd != reg_repwd){
				alertInfo += "<p class=\"text-error\">登录密码不一致,请重新检查.</p>";
			}
			return alertInfo;
	    }
	    
		//email checker
	    function verifyEmail(emailStr){
		    var emailRegEx = /^[A-Z0-9._%+-]aaa@qq.com[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
			if(emailStr.search(emailRegEx) == -1) {
				return false;
			}else{
				return true;
			}
	    } 	    
    </script>

  </body>
</html>
main.html
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>kFeedback - 云反馈!</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="feedback system on Cloud Foundry">
    <meta name="author" content="zhoukai">

    <!-- Le styles -->
    <link href="css/bootstrap.css" rel="stylesheet">
    <style type="text/css">
      body {
        padding-top: 60px;
        padding-bottom: 5px;
      }
    </style>
    <link href="css/bootstrap-responsive.css" rel="stylesheet">
    <link href="css/prettify.css" rel="stylesheet">
    <script src="js/prettify.js"></script>
    

    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->

  </head>

  <body onload="prettyPrint()">
    <div class="navbar navbar-inverse navbar-fixed-top">
      <div class="navbar-inner">
        <div class="container">
          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </a>
          <a class="brand" href="#">kFeedback - 云反馈!</a>
          <div class="nav-collapse collapse">
            <ul class="nav">
              <li><a href="#" id="goto_index">首页(Home)</a></li>
              <li><a href="#" id="goto_about">关于(About)</a></li>
              <li><a href="#" id="goto_demo">示例(Demo)</a></li>
              <li><a href="#" id="goto_updpwd">修改密码(Upd pwd)</a></li>
              <li class="active"><a href="#"><i class="icon-user icon-white"></i><span id="login_email"></span></a></li>
            </ul>
          </div><!--/.nav-collapse -->
        </div>
      </div>
    </div>


	<div class="container">
		<h2>App反馈监控台(App feedback console)</h2>
		<hr>
		<div class="tabbable tabs-left">
		  <ul id="appList" class="nav nav-tabs">
			<li class="active"><a href="#addApp" data-toggle="tab"><i class="icon-plus"></i>新增App(New App)</a></li>
		  </ul>
		  <div id="appList_content" class="tab-content">
		  <!-- 固定存在 -->
			<div class="tab-pane active" id="addApp">
			  <p>
				  <div class="control-group">
					<label class="control-label" for="app_name">App名称(&lt;=100个字.)</label>
					<div class="controls">
					  <input class="input-xlarge" type="text" id="app_name" maxlength="100" placeholder="App name">
					</div>
				  </div>
				  <div class="control-group">
					<label class="control-label" for="app_desc">App描述(&lt;=150个字.)</label>
					<div class="controls">
					  <textarea maxlength="150" class="input-xlarge" id="app_desc" rows="3"></textarea>
					</div>
				  </div>
				  <div class="control-group">
					<div class="controls">
					  <button id="btn_addApp" class="btn btn-primary">新增App(New app now!)</button>
					</div>
				  </div>
			  </p>
			</div>
			<!-- 固定存在 end-->
		  </div>
		</div>	
	
	
		<hr>

      <footer>
		<div class="row">
			<div class="span4">&copy; <i class="icon-user"></i>恺哥作品 - <a href="mailto:aaa@qq.com?subject=to 恺哥">aaa@qq.com</a></div>
			<div class="span4"></div>
			<div class="span4">
				<a target="_blank" href="http://www.oschina.net" title="OSChina"><img src="img/osc.ico" alt="OSChina"></a>
				<a target="_blank" href="http://www.cloudfoundry.com/" title="CloudFoundry"><img src="img/cf.ico" alt="cloudfoundry"></a>
				<a target="_blank" href="http://twitter.github.com/bootstrap/" title="Bootstrap"><img src="img/bootstrap.ico" alt="Bootstrap"></a>
			</div>
		</div>
      </footer>
      
	<!-- dialog -->
	<div id="updPwdModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
              <h3 id="myModalLabel">kFeedback信息提示窗</h3>
            </div>
            <div class="modal-body">
            	<h4><span id="loginer"></span>修改密码</h4>
            	<div id="updPwd_error_info"></div>
            	<p>
				<label class="control-label" for="upd_new_pwd">新密码</label>
				  <input type="password" id="upd_new_pwd" placeholder="New pwd">
				<label class="control-label" for="upd_new_repwd">确认新密码</label>
				  <input type="password" id="upd_new_repwd" placeholder="Confirm new pwd">
				</p>
            </div>
            <div class="modal-footer">
              <button class="btn" data-dismiss="modal">Close</button>
              <button id="btn_updpwd" class="btn btn-primary">提交(Update now!)</button>
            </div>
    </div>
	<div id="updAppModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
              <h3 id="myModalLabel">kFeedback信息提示窗</h3>
            </div>
            <div class="modal-body">
            	<h4>修改App信息</h4>
            	<div id="updApp_error_info"></div>
            	<p>
				<label class="control-label" for="upd_app_token">App Token</label>
				  <input type="text" disabled="disabled" class="input-xlarge uneditable-input" id="upd_app_token" placeholder="">
				<label class="control-label" for="upd_app_name">App名称(<=100个字.)</label>
				  <input type="text" maxlength="100" class="input-xlarge" id="upd_app_name" placeholder="">
				  <input type="hidden" id="upd_app_id" >
				<label class="control-label" for="upd_app_desc">App描述(<=150个字.)</label>
				  <textarea maxlength="150" class="input-xlarge" id="upd_app_desc" rows="3"></textarea>
				</p>
            </div>
            <div class="modal-footer">
              <button class="btn" data-dismiss="modal">Close</button>
              <button id="btn_updApp" class="btn btn-primary">提交(Update now!)</button>
            </div>
    </div>
	<div id="myAlertModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
           <div class="modal-header">
             <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
             <h3 id="myModalLabel">kFeedback信息提示窗</h3>
           </div>
           <div class="modal-body">
           	<div id="alertInfo"></div>
           </div>
           <div class="modal-footer">
             <button class="btn" data-dismiss="modal">Close</button>
           </div>
     </div>
	<div id="myAlertModal4Reload" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
           <div class="modal-header">
             <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
             <h3 id="myModalLabel">kFeedback信息提示窗</h3>
           </div>
           <div class="modal-body">
           	<div id="alertInfo4Reload"></div>
           </div>
           <div class="modal-footer">
             <button class="btn" data-dismiss="modal">Close</button>
           </div>
     </div>
	<div id="delAppModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
           <div class="modal-header">
             <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
             <h3 id="myModalLabel">kFeedback信息提示窗</h3>
           </div>
           <div class="modal-body">
			<h4>删除App - <span id="delAppName"></span></h4>
			<p>删除App的同时,也会删除该App的所有反馈信息,请注意.</p>
			<p>删除App点击[删除App]按钮,取消删除操作请点击[取消]按钮.</p>
			<input type="hidden" id="del_app_id" >
           </div>
           <div class="modal-footer">
             <button class="btn" data-dismiss="modal">取消(Cancel)</button>
             <button id="btn_delApp" class="btn btn-primary">删除App(Delete app now!)</button>
           </div>
     </div>
	<div id="aboutModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
           <div class="modal-header">
             <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
             <h3 id="myModalLabel">关于kFeedback</h3>
           </div>
           <div class="modal-body">
           	     <div class="thumbnail">
                  <img src="img/me.png" alt="恺哥">
                  <div class="caption">
                    <h4>周恺(<a href="http://weibo.com/u/2697324452" target="_blank">@新浪微博</a>)</h4>
                    <p>联通系统集成有限公司黑龙江省分公司 信息系统开发部 技术经理.</p>
                  </div>
                </div>
           </div>
           <div class="modal-footer">
             <button class="btn" data-dismiss="modal">Close</button>
           </div>
     </div>
	<div id="demoModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
           <div class="modal-header">
             <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
             <h3 id="myModalLabel">kFeedback Demo(示例)</h3>
           </div>
           <div class="modal-body">
                  <h4>如何将Post-API嵌入到您的产品中</h4>
                  <div class="caption">
                    <h5>基于Apache HttpClient(推荐)</h5>
                    <p>
<pre class="prettyprint ">
public static void sendFeedback(String appToken,String fb){
  DefaultHttpClient httpclient = new DefaultHttpClient();
  StringBuilder url = new StringBuilder();
  url.append("http://kfeedback.cloudfoundry.com/Action");
  try {
    HttpPost httpost = new HttpPost(url.toString());
    List<NameValuePair> params = new ArrayList<NameValuePair>(); 
	params.add(new BasicNameValuePair("m", "insFeedback")); 
	params.add(new BasicNameValuePair("token", appToken)); 
	params.add(new BasicNameValuePair("fb", fb)); 
	httpost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
	ResponseHandler<String> responseHandler = new BasicResponseHandler();
	httpclient.execute(httpost, responseHandler);
  } catch (Exception e) {
  }finally{httpclient.getConnectionManager().shutdown();}
}
</pre>
					</p>
                </div>
           </div>
           <div class="modal-footer">
             <button class="btn" data-dismiss="modal">Close</button>
           </div>
     </div>

    </div> <!-- /container -->

    <!-- Le javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="js/jquery-1.8.3.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
    	var app = "http://kfeedback.cloudfoundry.com";
	    var url = app + "/Action?callback=?";
    	//init login_info
    	$("#login_email").html(sessionStorage.getItem("email")+"("+sessionStorage.getItem("empId")+")");
    	
    	//init app tab
    	$("#appList").empty();//清空列表
    	$("#appList").append("<li class=\"active\"><a href=\"#addApp\" data-toggle=\"tab\"><i class=\"icon-plus\"></i>新增App(New App)</a></li>");
   		$.getJSON(url,{m:"getApp",empId:sessionStorage.getItem("empId")},function(json){
			$.each(json, function(i,item){
				var appInfo = "<li><a id=\""+item.app_id+"\" href=\"#"+item.app_id+"t\" data-toggle=\"tab\" title=\""+item.app_desc+"\">"+item.app_name+" - <span class=\"badge badge-info\">"+item.app_feedback_qty+"</span></a></li>";
				$("#appList").append(appInfo);
				
				$("#"+item.app_id).bind("click",function(){
					if(item.app_id == 1){
						if(sessionStorage.getItem("empId") == "1"){
		    				//init app detail info
							var appTabContent = "<div class=\"tab-pane\" id=\""+item.app_id+"t\">";
							appTabContent += "	<p> <div class=\"row\">                       					";
							if(item.app_feedback_qty > 0){
								appTabContent += "	  <div class=\"span3\"><i class=\"icon-list\"></i><strong><a href=\"#\" id=\"loadAppFB"+item.app_id+"\">加载"+item.app_name+"的反馈信息</a></strong></div>   ";
							}else{
								appTabContent += "	  <div class=\"span3\"><i class=\"icon-list\"></i><strong>"+item.app_name+"无信息</strong></div>   ";
							}
							appTabContent += "	  <div class=\"span3\"><i class=\"icon-edit\"></i><strong><a href=\"#\" id=\"go2updApp"+item.app_id+"\">修改"+item.app_name+"的信息</a></strong></div>  			";
							appTabContent += "	  <div class=\"span3\"><i class=\"icon-remove\"></i><strong><a href=\"#\" id=\"go2delApp"+item.app_id+"\">删除"+item.app_name+"的所有信息</a></strong></div>     		";
							appTabContent += "	</div><hr>	                     					";
							appTabContent += "	<div class=\"row\">                       					";
							appTabContent += "	  <div class=\"span2\"><p><strong>创建时间</strong></p><p>"+item.cdate+"</p></div>  			";
							appTabContent += "	  <div class=\"span4\"><p><strong>描述</strong></p><p>"+item.app_desc+"</p></div>     		";
							appTabContent += "	  <div class=\"span3\"><p><strong>Token</strong></p><p>"+item.app_token+"</p></div>   ";
							appTabContent += "	</div>	</p>  <hr>                      					";
							//init feedback info
							appTabContent += "  <p>                                                                         ";
							appTabContent += "	<table class=\"table table-striped\">                                         ";
							appTabContent += "	  <thead>                                                                   ";
							appTabContent += "		<tr>                                                                    ";
							appTabContent += "		  <th>#</th>                                                            ";
							appTabContent += "		  <th><i class=\"icon-time\"></i>反馈时间(Feedback time)</th>             ";
							appTabContent += "		  <th><i class=\"icon-info-sign\"></i>反馈内容(Feedback content)</th>     ";
							appTabContent += "		  <th><i class=\"icon-wrench\"></i>操作(Operate)</th>                     ";
							appTabContent += "		</tr>                                                                   ";
							appTabContent += "	  </thead>                                                                  ";
							appTabContent += "	  <tbody id=\"fb_tbody"+item.app_id+"\">                                                                   ";
							appTabContent += "	  </tbody>                                                                  ";
							appTabContent += "	</table>                                                                    ";
							appTabContent += " </p>                                                                         ";
							appTabContent += "</div>";
							$("#appList_content").append(appTabContent);
						}else{
		    				//init app detail info
							var appTabContent = "<div class=\"tab-pane\" id=\""+item.app_id+"t\">";
							appTabContent += "<div class=\"input-append\">";
							appTabContent += "  <input class=\"span6\" placeholder=\"留下您对kFeedback的感受\" id=\"feedback_info\" type=\"text\">";
							appTabContent += "  <button class=\"btn btn-info\" id=\"bth_addFeedback"+item.app_id+"\" type=\"button\">提交反馈</button>";
							if(item.app_feedback_qty > 0){
								appTabContent += "  <button class=\"btn btn-primary\" id=\"btnLoadAppFB"+item.app_id+"\" type=\"button\">加载反馈信息</button>";
							}
							
							appTabContent += "</div>";
							
							appTabContent += "	<hr>	                     					";
							appTabContent += "	<div class=\"row\">                       					";
							appTabContent += "	  <div class=\"span2\"><p><strong>创建时间</strong></p><p>"+item.cdate+"</p></div>  			";
							appTabContent += "	  <div class=\"span4\"><p><strong>描述</strong></p><p>"+item.app_desc+"</p></div>     		";
							appTabContent += "	  <div class=\"span3\"><p><strong>Token</strong></p><p>"+item.app_token+"</p></div>   ";
							appTabContent += "	</div>	</p>  <hr>                      					";
							//init feedback info
							appTabContent += "  <p>                                                                         ";
							appTabContent += "	<table class=\"table table-striped\">                                         ";
							appTabContent += "	  <thead>                                                                   ";
							appTabContent += "		<tr>                                                                    ";
							appTabContent += "		  <th>#</th>                                                            ";
							appTabContent += "		  <th><i class=\"icon-time\"></i>反馈时间(Feedback time)</th>             ";
							appTabContent += "		  <th><i class=\"icon-info-sign\"></i>反馈内容(Feedback content)</th>     ";
							appTabContent += "		  <th><i class=\"icon-wrench\"></i>操作(Operate)</th>                     ";
							appTabContent += "		</tr>                                                                   ";
							appTabContent += "	  </thead>                                                                  ";
							appTabContent += "	  <tbody id=\"fb_tbody"+item.app_id+"\">                                                                   ";
							appTabContent += "	  </tbody>                                                                  ";
							appTabContent += "	</table>                                                                    ";
							appTabContent += " </p>                                                                         ";
							appTabContent += "</div>";
							$("#appList_content").append(appTabContent);
						}
					}else{
	    				//init app detail info
						var appTabContent = "<div class=\"tab-pane\" id=\""+item.app_id+"t\">";
						appTabContent += "	<p> <div class=\"row\">                       					";
						if(item.app_feedback_qty > 0){
							appTabContent += "	  <div class=\"span3\"><i class=\"icon-list\"></i><strong><a href=\"#\" id=\"loadAppFB"+item.app_id+"\">加载"+item.app_name+"的反馈信息</a></strong></div>   ";
						}else{
							appTabContent += "	  <div class=\"span3\"><i class=\"icon-list\"></i><strong>"+item.app_name+"无信息</strong></div>   ";
						}
						appTabContent += "	  <div class=\"span3\"><i class=\"icon-edit\"></i><strong><a href=\"#\" id=\"go2updApp"+item.app_id+"\">修改"+item.app_name+"的信息</a></strong></div>  			";
						appTabContent += "	  <div class=\"span3\"><i class=\"icon-remove\"></i><strong><a href=\"#\" id=\"go2delApp"+item.app_id+"\">删除"+item.app_name+"的所有信息</a></strong></div>     		";
						appTabContent += "	</div><hr>	                     					";
						appTabContent += "	<div class=\"row\">                       					";
						appTabContent += "	  <div class=\"span2\"><p><strong>创建时间</strong></p><p>"+item.cdate+"</p></div>  			";
						appTabContent += "	  <div class=\"span4\"><p><strong>描述</strong></p><p>"+item.app_desc+"</p></div>     		";
						appTabContent += "	  <div class=\"span3\"><p><strong>Token</strong></p><p>"+item.app_token+"</p></div>   ";
						appTabContent += "	</div>	</p>  <hr>                      					";
						//init feedback info
						appTabContent += "  <p>                                                                         ";
						appTabContent += "	<table class=\"table table-striped\">                                         ";
						appTabContent += "	  <thead>                                                                   ";
						appTabContent += "		<tr>                                                                    ";
						appTabContent += "		  <th>#</th>                                                            ";
						appTabContent += "		  <th><i class=\"icon-time\"></i>反馈时间(Feedback time)</th>             ";
						appTabContent += "		  <th><i class=\"icon-info-sign\"></i>反馈内容(Feedback content)</th>     ";
						appTabContent += "		  <th><i class=\"icon-wrench\"></i>操作(Operate)</th>                     ";
						appTabContent += "		</tr>                                                                   ";
						appTabContent += "	  </thead>                                                                  ";
						appTabContent += "	  <tbody id=\"fb_tbody"+item.app_id+"\">                                                                   ";
						appTabContent += "	  </tbody>                                                                  ";
						appTabContent += "	</table>                                                                    ";
						appTabContent += " </p>                                                                         ";
						appTabContent += "</div>";
						$("#appList_content").append(appTabContent);
					}
					
					$("#bth_addFeedback"+item.app_id).bind("click",function(){
						var fbInfo = $("#feedback_info").val();
						if($.isEmptyObject(fbInfo)){
	        				$("#alertInfo").html("<p class=\"text-error\">提交反馈失败!反馈信息不能为空!</p>");
	        				$('#myAlertModal').modal('show');
						}else{
			        		$.getJSON(url,{m:"insFeedback",token:"kFeedback",fb:fbInfo},function(json){
			        			if(json.result == "1"){
			        	    		$("#feedback_info").val("");
			        				$("#alertInfo4Reload").html("<p class=\"text-success\">新增成功!感谢您对kFeedback的支持.</p>");
			        				$('#myAlertModal4Reload').modal('show');
			        			}else{
			        				$("#alertInfo").html("<p class=\"text-error\">新增失败!</p>");
			        				$('#myAlertModal').modal('show');
			        			}
			        		});
						}
					});
					
					$("#btnLoadAppFB"+item.app_id).bind("click",function(){
						$.getJSON(url,{m:"getFeedback",appId:item.app_id},function(json){
							//clear tbody
							$("#fb_tbody"+item.app_id).empty();
							var tbody = "";
		        			if(json.length > 0){
				   				$.each(json, function(j,feedbackItem){
				   					tbody += "<tr>";
				   					tbody += "<td>" + feedbackItem.feedback_id + "</td>";
				   					tbody += "<td>" + feedbackItem.feedback_time + "</td>";
				   					tbody += "<td>" + feedbackItem.feedback_info + "</td>";
				   					tbody += "<td><i class=\"icon-comment\"></i><strong><a href=\"#\">预留</a></strong></td>";
				   					tbody += "</tr>";
				   				});
				   				$("#fb_tbody"+item.app_id).append(tbody);
		        			}
		        		});
					});
					
					//bind load feedback info click event
					$("#loadAppFB"+item.app_id).bind("click",function(){
						$.getJSON(url,{m:"getFeedback",appId:item.app_id},function(json){
							//clear tbody
							$("#fb_tbody"+item.app_id).empty();
							var tbody = "";
		        			if(json.length > 0){
				   				$.each(json, function(j,feedbackItem){
				   					tbody += "<tr>";
				   					tbody += "<td>" + feedbackItem.feedback_id + "</td>";
				   					tbody += "<td>" + feedbackItem.feedback_time + "</td>";
				   					tbody += "<td>" + feedbackItem.feedback_info + "</td>";
				   					tbody += "<td><i class=\"icon-comment\"></i><strong><a href=\"#\">预留</a></strong></td>";
				   					tbody += "</tr>";
				   				});
				   				$("#fb_tbody"+item.app_id).append(tbody);
		        			}
		        		});
					});
					
					//bind updApp and delApp click event
					$("#go2updApp"+item.app_id).bind("click",function(){
						$("#upd_app_id").val(item.app_id);
						$("#upd_app_token").val(item.app_token);
						$("#upd_app_name").val(item.app_name);
						$("#upd_app_desc").val(item.app_desc);
						$('#updAppModal').modal('show');
					});
					$("#go2delApp"+item.app_id).bind("click",function(){
						$("#del_app_id").val(item.app_id);
						$("#delAppName").html("<strong>"+item.app_name+"</strong>");
						$('#delAppModal').modal('show');
					});
					
				});
				
			});

   		});
   		//init app tab end
   		
    	$("#goto_index").click(function(){
    		//clear sessionStorage
    		sessionStorage.clear();
    		//forward
    		location.href = app + "/index.jsp";
    	});
    	
    	$("#goto_about").click(function(){
    		$('#aboutModal').modal('show');
    	});
    	
       	$("#goto_demo").click(function(){
    		$('#demoModal').modal('show');
    	});
    	
    	
   		
    	$("#goto_updpwd").click(function(){
    		$("#updPwd_error_info").html("");
    		$("#upd_new_pwd").val("");
    		$("#upd_new_repwd").val("");
    		$("#loginer").html(sessionStorage.getItem("email")+"("+sessionStorage.getItem("empId")+")");
    		$('#updPwdModal').modal('show');
    	});
    	$("#btn_updpwd").click(function(){
    		var upd_new_pwd = $("#upd_new_pwd").val();
    		var upd_new_repwd = $("#upd_new_repwd").val();
			if(!$.isEmptyObject(upd_new_pwd) && (upd_new_pwd == upd_new_repwd)){
        		$.getJSON(url,{m:"updPwd",empId:sessionStorage.getItem("empId"),newPwd:upd_new_pwd},function(json){
        			if(json.result == "1"){
        				$("#updPwd_error_info").html("<p class=\"text-success\">修改密码成功.</p>");
        	    		$("#upd_new_pwd").val("");
        	    		$("#upd_new_repwd").val("");
        			}else{
        				$("#updPwd_error_info").html("<p class=\"text-error\">修改密码失败.</p>");        			}
        		});
			}else{
				$("#updPwd_error_info").html("<p class=\"text-error\">修改密码失败,新密码为空或密码不一致,请重新尝试.</p>");
			}
    	});
    	
    	$("#btn_addApp").click(function(){
    		var app_name = $("#app_name").val();
    		var app_desc = $("#app_desc").val();
    		if(!$.isEmptyObject(app_name) && !$.isEmptyObject(app_desc)){
        		$.getJSON(url,{m:"insApp",empId:sessionStorage.getItem("empId"),appName:app_name,appDesc:app_desc},function(json){
        			if(json.result == "1"){
        	    		$("#app_name").val("");
        	    		$("#app_desc").val("");
        				$("#alertInfo4Reload").html("<p class=\"text-success\">App新增成功!</p>");
        				$('#myAlertModal4Reload').modal('show');
        			}else{
        				$("#alertInfo").html("<p class=\"text-error\">App新增失败!</p>");
        				$('#myAlertModal').modal('show');
        			}
        		});
    		}else{
				$("#alertInfo").html("<p class=\"text-error\">App名称与描述为必填字段!</p>");
				$('#myAlertModal').modal('show');
    		}
    	});
    	
    	$("#btn_updApp").click(function(){
    		var upd_app_id = $("#upd_app_id").val();
    		var upd_app_name = $("#upd_app_name").val();
    		var upd_app_desc = $("#upd_app_desc").val();
    		if(!$.isEmptyObject(upd_app_id) && !$.isEmptyObject(upd_app_name) && !$.isEmptyObject(upd_app_desc)){
        		$.getJSON(url,{m:"updApp",appId:upd_app_id,appName:upd_app_name,appDesc:upd_app_desc},function(json){
        			if(json.result == "1"){
        	    		$("#upd_app_id").val("");
        	    		$("#upd_app_token").val("");
        	    		$("#upd_app_name").val("");
        	    		$("#upd_app_desc").val("");
        	    		$('#updAppModal').modal('hide');
       					$("#alertInfo4Reload").html("<p class=\"text-success\">App修改成功!</p>");
        				$('#myAlertModal4Reload').modal('show');
        			}else{
        				$("#alertInfo").html("<p class=\"text-error\">App修改失败!</p>");
        				$('#myAlertModal').modal('show');
        			}
        		});
    		}else{
				$("#updApp_error_info").html("<p class=\"text-error\">App名称与描述为必填字段!</p>");
    		}
    	});

    	
    	$("#btn_delApp").click(function(){
       		$.getJSON(url,{m:"delApp",appId:$("#del_app_id").val()},function(json){
       			if(json.result == "1"){
       	    		$("#del_app_id").val("");
       	    		$('#delAppModal').modal('hide');
      				$("#alertInfo4Reload").html("<p class=\"text-success\">App删除成功!</p>");
       				$('#myAlertModal4Reload').modal('show');
       			}else{
       				$("#alertInfo").html("<p class=\"text-error\">App删除失败!</p>");
       				$('#myAlertModal').modal('show');
       			}
       		});
    	});
    	
    	$('#myAlertModal4Reload').on('hidden', function () {
    		location.reload(true);//是的,我承认我偷懒了
    	});
    });
    
    </script>
  </body>
</html>
以上就是kFeedback的所有代码,配置文件比较简单,我就不提供了,如有需要,可给我留言。


为了方便大家学习和调试代码,我将完整的工程提供给大家,欢迎斧正

https://github.com/kongit/kFeedback

http://git.oschina.net/kzhou-hrb/kfeedback


转载于:https://my.oschina.net/kzhou/blog/100731