网页版在线客服实现代码

第一次写,感觉很乱,后面直接上代码吧,代码也有注释,想看思路的朋友可以看前面。有什么建议和意见欢迎砸过来。

功能:

1、客服需登录进入客服页面。用户无需登录,进入用户页面,直接获取sessionId作为id值。

2、用户进入页面并且发送消息时,客服才会获取到该用户,并在左侧列表显示。

3、点击用户名即可切换聊天对象,正在聊天的用户,用户名为选中状态。

4、每条消息的时间显示在本条消息上方(水平居中)。消息时间间隔不足1分钟,则此不显示时间。

5、每次读取的消息均为最新消息。

6、客服未与其正在聊天的用户发送新消息时应有新消息提示。

7、用户关闭浏览器或长时间无回应时,将用户置为下线。

       客服界面将清空与下线用户的聊天窗口,且下线用户不显示在左侧列表中。

8、用户长时间无回应置为下线后,刷新可继续在线与客服聊天。

9、发送:1)输入框未输入消息时,提示“发送内容不能为空”。

                2)未选择用户时,提示“请选择用户”。

数据库表:

三张表:客服(user),用户(customer),聊天记录(cs_chat_record)。

客服表主要字段:id,name,password,online,currentPeople;

用户表主要字段:id,name,online,headImg;

聊天记录表主要字段:id,userId,customerId,userContent,customerContent,time;

主要思路:

1、用户进入页面:查看当前用户有没有正在被客服人员接待

①正在被接待:设置用户为在线状态(因为刷新会有下线操作)。

②未被接待:获取所有在线客服每个人正在接待的用户人数,并给该用户分配一个当前接待人数少的客服。

                    修改此客服正在接待的人数,将用户添加到用户表中(设置为在线状态)。

                    将用户和客服均存到session中。

2、客服进入页面:常规验证。

4、用户和客服发送消息时,都先将信息保存到数据库。

5、用户和客服界面,都是一秒刷新一次获取最新消息。

6、客服页面:当前正在沟通的用户列表,每秒获取一次,将不在线的用户在列表清除。

7、长时间无回复的用户置为下线,用到数据库定时器。

8、用户关闭浏览器置为下线,用到的是window.onbeforeunload方法。

9、新消息提醒:保存用户消息将用户头像设置成有红点的,获取消息时将用户头像设置为无红点的。

知识点:

1、获取用户id:getRequest().getSession().getId();

2、获取最新聊天记录时,聊天记录表的id是在前端存储的,一定不要在后台用全局变量存储,方便用户刷新页面时再次获取之前所有聊天记录。

3、c:forEach标签只能在服务器端使用,在页面加载完成后需要用js的for循环。

4、用户列表的显示是foreach循环得到的,为显示用户名的label设置class属性,用户点击切换用户时使用。

    列表用户正在聊天的用户用户名设置为选中状态:$("div#"+id).css('background','#00ffff');

    其他用户取消选中状态:$(".CustomerBG").css('background','#ffffff');

   ( ps:这里不是很懂,所以给div设置了两个属性,给背景色和取消背景色用到的不是一个属性。)

5、循环得到的用户名:

    1)点击用户名触发的事件,此方法在$(function(){})外写,能监听js中拼接的节点(此客服系统用的此方法):

            $(document).off("click", ".checkLabel").on("click", ".checkLabel", function(){
                 //点击用户名之后要执行的内容

            });

    2)此方法在$(function(){})内写,不能监听到js中拼接的节点,

            $(".checkLabel").click(function(){

                //要执行的内容

            })

attr:1)$(this).attr("data_id");拿到自定义的属性的值。

        2)$(this).attr("data_id",“value”);给自定义的属性赋值。

6、清空div中的所有内容:

    $("#divId").empty();

    $("#divId").html("");

7、地址栏不能拼接时间参数,时间格式有空格,地址以空格为终点。

8、给myclass的span节点的内容加样式。

样式体现在这

.myclass span{

    //要写的样式

}

9、数据库定时器的格式

    DELIMITER $$

        ALTER DEFINER=`root`@`localhost` EVENT `test` ON SCHEDULE EVERY 1 MINUTE STARTS '2018-04-26 18:40:32'             ON     COMPLETION NOT PRESERVE ENABLE DO BEGIN

                    //要执行的SQL语句

           END$$

    DELIMITER ;

10、将30分钟内未发送消息的用户置为下线(觉得不是很容易写,半个多小时才写出来,记录一下)

    UPDATE customer SET online=0

        WHERE id IN

            (SELECT customerId FROM

                     (SELECT customerId,MAX(`time`) maxTime FROM cs_chat_record GROUP BY customerId) temp

                WHERE maxTime


未解决的问题:

1、每秒一次获取用户列表,页面会有闪烁。

2、火狐浏览器只在关闭页面时执行window.onbeforeunload方法,关闭整个浏览器时不执行。

3、“发送内容不为空”和“请选择用户”的判断都是在后台做的,感觉应该在前端做。

主要代码:

客服页:


<%@ page language="java" pageEncoding="utf-8"%>
<%@ include file="/platform/common/jsp/taglibs.jsp"%>


	客服中心
	
	
	
	
	
	
	
	
	
	
	


	
正在沟通的用户

用户页:


<%@ page language="java" pageEncoding="utf-8"%>
<%@ include file="/platform/common/jsp/taglibs.jsp"%>


	客服中心
	
	
	
	
	
	
	
	
	
	
	


	

客服中心

controller:
@Controller
@RequestMapping(value = "/cs")
public class CSController extends SpringController{
	@Autowired
	private CSService csService;
	@Autowired
	private UserService userService;
	/**
	 * 将用户发送的消息保存到数据库
	 * @param userContent
	 * @return
	 */
	@RequestMapping(value = "/saveCustomerChatRecord",method=RequestMethod.POST)
	@ResponseBody
	public AjaxJson saveCustomerChatRecord(@RequestParam(value = "customerContent", required = false) String customerContent) {
		AjaxJson ajaxJson =new AjaxJson();
		CSChatRecord csChatRecord = new CSChatRecord();
		try {
			User user = (User) getRequest().getSession().getAttribute("user");
			Customer customer = (Customer) getRequest().getSession().getAttribute("customer");
			//获取当前时间 
			String datetime = DateUtil.getCurrDateSecondString();
			//封装csChatRecord对象
			csChatRecord.setUserId(user.getId());
			csChatRecord.setCustomerId(customer.getId());
			csChatRecord.setTime(datetime);
			customerContent = customerContent.trim();
			if(customerContent != null && !customerContent.equals("")){
				csChatRecord.setCustomerContent(customerContent);
				//将csChatRecord对象保存到数据库
				csService.saveCustomerChatRecord(csChatRecord);
			}else{
				ajaxJson.setSuccess(false);
				ajaxJson.setMsg("发送内容不能为空");
			}
			customer.setHeadImg("C_new.jpg");
			csService.updateHeadImgState(customer);
			return ajaxJson;
		}catch (Exception e) {
			e.printStackTrace();
			ajaxJson.setSuccess(false);
			ajaxJson.setMsg("服务器跑丢了。。");
			return ajaxJson;
		}
	}

	/**
	 * 将客服发送的消息保存到数据库
	 * @param userContent
	 * @return
	 */
	@RequestMapping(value = "/saveUserChatRecord",method=RequestMethod.POST)
	@ResponseBody
	public AjaxJson saveUserChatRecord(@RequestParam(value = "userContent", required = false) String userContent,
			@RequestParam(value = "id", required = false) String id) {
		AjaxJson ajaxJson = new AjaxJson();
		CSChatRecord csChatRecord = new CSChatRecord();
		try {
			if(id==null || id==""){
				ajaxJson.setSuccess(false);
				ajaxJson.setMsg("请选择用户");
				return ajaxJson;
			}
			User user = (User) getRequest().getSession().getAttribute("user");
			//获取当前时间
			String datetime = DateUtil.getCurrDateSecondString();
			//封装csChatRecord对象
			csChatRecord.setUserId(user.getId());
			csChatRecord.setCustomerId(id);
			csChatRecord.setTime(datetime);
			userContent = userContent.trim();
			if(userContent != null && !userContent.equals("")){
				csChatRecord.setUserContent(userContent);
				//将csChatRecord对象保存到数据库
				csService.saveUserChatRecord(csChatRecord);
			}else{
				ajaxJson.setSuccess(false);
				ajaxJson.setMsg("发送内容不能为空");
			}
			return ajaxJson;
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxJson;
		}
	}
	
	/**
	 * 从数据库读取所有聊天记录,展示在页面上
	 * 客服和用户公用同一个方法,
	 * idTemp:为user_id时表示客服,为customer_id时表示用户
	 * id:客服读消息时用到的用户id
	 * oldId:上一次读取新消息的记录,保证每次读取的都是最新消息
	 * @return
	 */
	@RequestMapping(value = "/getAllChatRecord")
	@ResponseBody
	public AjaxJson getAllChatRecord(@RequestParam(value = "idTemp", required = false) String idTemp,
			@RequestParam(value = "id", required = false) String id,
			@RequestParam(value = "oldId", required = false) int oldId) {
		AjaxJson ajaxJson =new AjaxJson();
		CSChatRecord csChatRecord = new CSChatRecord();
		User user = (User) getRequest().getSession().getAttribute("user");
		Customer customer = new Customer();
		try {
			//判断是用户页面还是客服页面读取数据库消息
			if(idTemp.equals("user_id")){//客服
				csChatRecord.setCustomerId(id);
				customer.setId(id);
				customer.setHeadImg("C.jpg");
				csService.updateHeadImgState(customer);
			}else if(idTemp.equals("customer_id")){
				customer = (Customer) getRequest().getSession().getAttribute("customer");
				csChatRecord.setCustomerId(customer.getId());
			}
			csChatRecord.setUserId(user.getId());
			csChatRecord.setId(oldId);
			List alllist = csService.getAllChatRecord(csChatRecord);
			if(alllist.size()>0){
				ajaxJson.setObj(alllist);
			}
			return ajaxJson;
		} catch (Exception e) {
			e.printStackTrace();
			return ajaxJson;
		}
	}
	/**
	 * 客服界面
	 * @return
	 */
	@RequestMapping(value = "/goUser")
	public String goUser() {
		try {
			return "module/cs/jsp/weChat_user";
		} catch (Exception e) {
			e.printStackTrace();
			return "module/weChat/jsp/weChat_404";
		}
	}
	/**
	 * 用户界面
	 * @return
	 */
	@RequestMapping(value = "/goCustomer")
	public String goCustomer() {
		int temp = 0;
		User userTemp = new User();
		Customer customer = new Customer();
		try {
			Customer customer2 = (Customer) getRequest().getSession().getAttribute("customer");
			if(customer2 == null){
				//获取所有在线客服每个人正在接待的用户人数
				List userList = userService.getAllUserState();
				userTemp = userList.get(0);
				temp = userTemp.getCurrentPeople();
				for (User user : userList) {
					if(user.getCurrentPeople() customerList = csService.getCustomerList(user.getId());
		if(customerList.size()>0)
			ajaxJson.setObj(customerList);
		return ajaxJson;
	}
}

你可能感兴趣的:(yt)