1.新增对 web 客户端的实现【重大更新】

2.后台界面修改
This commit is contained in:
xiajun@doweidu.com 2014-09-15 18:24:31 +08:00
parent f324368a45
commit 3e6ce2c0cd
97 changed files with 1774 additions and 447 deletions

View File

@ -36,6 +36,17 @@ public interface CIMConstant {
public static final String HEARTBEAT_KEY ="heartbeat"; public static final String HEARTBEAT_KEY ="heartbeat";
/**
* FLEX 客户端socket请求发的安全策略请求需要特殊处理返回安全验证报文
*/
public static final String FLEX_POLICY_REQUEST ="<policy-file-request/>";
public static final String FLEX_POLICY_RESPONSE ="<?xml version=\"1.0\"?><cross-domain-policy><site-control permitted-cross-domain-policies=\"all\"/><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>\0";
/** /**
* 对应ichat spring-cim.xml > bean:mainIoHandler >handlers * 对应ichat spring-cim.xml > bean:mainIoHandler >handlers
* 服务端处理对应的handlers应该继承与com.farsunset.cim.nio.handle.AbstractHandler * 服务端处理对应的handlers应该继承与com.farsunset.cim.nio.handle.AbstractHandler

View File

@ -1,9 +1,12 @@
package com.farsunset.cim.nio.filter; package com.farsunset.cim.nio.filter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession; import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder; import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
@ -20,7 +23,9 @@ import com.farsunset.cim.nio.mutual.SentBody;
* *
*/ */
public class ServerMessageDecoder extends CumulativeProtocolDecoder { public class ServerMessageDecoder extends CumulativeProtocolDecoder {
protected final Logger logger = Logger.getLogger(ServerMessageDecoder.class);
private final Charset charset = Charset.forName("UTF-8");
private IoBuffer buff = IoBuffer.allocate(320).setAutoExpand(true); private IoBuffer buff = IoBuffer.allocate(320).setAutoExpand(true);
@Override @Override
public boolean doDecode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out) throws Exception { public boolean doDecode(IoSession iosession, IoBuffer iobuffer, ProtocolDecoderOutput out) throws Exception {
@ -35,7 +40,12 @@ public class ServerMessageDecoder extends CumulativeProtocolDecoder {
complete = true; complete = true;
break; break;
} else { }else if(b == '\0')//flex客户端 安全策略验证时会收到<policy-file- request/>\0的消息忽略此消息内容
{
complete = true;
break;
}
else {
buff.put(b); buff.put(b);
} }
} }
@ -43,22 +53,35 @@ public class ServerMessageDecoder extends CumulativeProtocolDecoder {
buff.flip(); buff.flip();
byte[] bytes = new byte[buff.limit()]; byte[] bytes = new byte[buff.limit()];
buff.get(bytes); buff.get(bytes);
String message = new String(bytes, "UTF-8");
buff.clear();
SentBody body = new SentBody();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(message.getBytes("UTF-8")));
body.setKey(doc.getElementsByTagName("key").item(0).getTextContent());
NodeList items = doc.getElementsByTagName("data").item(0).getChildNodes();
for (int i = 0; i < items.getLength(); i++) {
Node node = items.item(i);
body.getData().put(node.getNodeName(), node.getTextContent());
}
out.write(body); String message = new String(bytes, "UTF-8");
logger.warn("ServerMessageDecoder:" + message);
buff.clear();
try{
SentBody body = new SentBody();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(bytes));
body.setKey(doc.getElementsByTagName("key").item(0).getTextContent());
NodeList datas = doc.getElementsByTagName("data");
if(datas!=null&&datas.getLength()>0)
{
NodeList items = datas.item(0).getChildNodes();
for (int i = 0; i < items.getLength(); i++) {
Node node = items.item(i);
body.getData().put(node.getNodeName(), node.getTextContent());
}
}
out.write(body);
}catch(Exception e){
//e.printStackTrace();
logger.warn(e.getMessage());
out.write(message);
}
} }
return complete; return complete;
} }

View File

@ -1,5 +1,5 @@
package com.farsunset.cim.nio.handle; package com.farsunset.cim.nio.handler;
/** /**
* 请求处理接口,所有的请求实现必须实现此接口 * 请求处理接口,所有的请求实现必须实现此接口

View File

@ -1,5 +1,5 @@
package com.farsunset.cim.nio.handle; package com.farsunset.cim.nio.handler;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;

View File

@ -1,5 +1,5 @@
package com.farsunset.cim.nio.handle; package com.farsunset.cim.nio.handler;
import java.util.HashMap; import java.util.HashMap;
@ -40,6 +40,15 @@ public class MainIOHandler extends IoHandlerAdapter {
throws Exception { throws Exception {
logger.debug("message: " + message.toString()); logger.debug("message: " + message.toString());
/**
* flex 客户端安全策略请求需要返回特定报文
*/
if(CIMConstant.FLEX_POLICY_REQUEST.equals(message))
{
ios.write(CIMConstant.FLEX_POLICY_RESPONSE);
return ;
}
CIMSession cimSession =new CIMSession(ios); CIMSession cimSession =new CIMSession(ios);
ReplyBody reply = new ReplyBody(); ReplyBody reply = new ReplyBody();
SentBody body = (SentBody) message; SentBody body = (SentBody) message;

View File

@ -19,7 +19,6 @@
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/antlr-2.7.6.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/antlr-2.7.6.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/asm.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/asm.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/aspectjweaver.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/aspectjweaver.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/cim-core.1.5.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-fileupload-1.2.1.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-fileupload-1.2.1.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-io-2.4.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-io-2.4.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-lang-2.3.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-lang-2.3.jar"/>
@ -39,5 +38,6 @@
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/struts2-core-2.1.8.1.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/struts2-core-2.1.8.1.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/xstream-1.3.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/xstream-1.3.jar"/>
<classpathentry kind="lib" path="WebRoot/WEB-INF/lib/xwork-core-2.1.6.jar"/> <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/xwork-core-2.1.6.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/cim-core"/>
<classpathentry kind="output" path="WebRoot/WEB-INF/classes"/> <classpathentry kind="output" path="WebRoot/WEB-INF/classes"/>
</classpath> </classpath>

View File

@ -1,4 +1,5 @@
#Tue May 06 16:51:02 CST 2014 #Mon Sep 15 17:02:27 CST 2014
eclipse.preferences.version=1 eclipse.preferences.version=1
encoding//WebRoot/console/webclient/cim.js=UTF-8
encoding//src/main/java/com/farsunset/ichat/api/action/MessageAction.java=gbk encoding//src/main/java/com/farsunset/ichat/api/action/MessageAction.java=gbk
encoding/<project>=UTF-8 encoding/<project>=UTF-8

View File

@ -26,7 +26,7 @@
</map> </map>
</property> </property>
</bean> </bean>
<bean id="mainIoHandler" class="com.farsunset.cim.nio.handle.MainIOHandler" > <bean id="mainIoHandler" class="com.farsunset.cim.nio.handler.MainIOHandler" >
<property name="handlers"> <property name="handlers">
<map> <map>
@ -37,7 +37,7 @@
<bean class="com.farsunset.ichat.cim.handler.LogoutHandler" /> <bean class="com.farsunset.ichat.cim.handler.LogoutHandler" />
</entry> </entry>
<entry key="client_heartbeat"> <entry key="client_heartbeat">
<bean class="com.farsunset.cim.nio.handle.HeartbeatHandler"/> <bean class="com.farsunset.cim.nio.handler.HeartbeatHandler"/>
</entry> </entry>
<entry key="sessionClosedHander"> <entry key="sessionClosedHander">
<bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/> <bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/>

View File

@ -1,8 +1,10 @@
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page language="java" pageEncoding="UTF-8"%>
<% <%
String headerBasePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ request.getContextPath(); String headerBasePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
Object admin = session.getAttribute("admin");
%> %>
<script type="text/javascript"> <script type="text/javascript">
function showUserMenu() function showUserMenu()
@ -33,6 +35,31 @@
}); });
function doLogin()
{
var account = $('#account').val();
var password = $('#password').val();
if($.trim(account)=='' || $.trim(password)=='')
{
return;
}
showProcess('正在登录请稍后......');
$.post("<%=headerBasePath%>/system/system_login.action", {account:account,password:password},
function(data){
hideProcess();
if(data == 403)
{
showETip("账号或者密码错误");
return ;
}
doHideDialog('LoginDialog');
$("#loginButton").text("系统管理员");
$("#loginButton").removeAttr("onclick");
});
}
</script> </script>
@ -41,53 +68,76 @@
<!-- 头部 --> <!-- 头部 -->
<div id="_main_header_banner" class="header"> <div id="_main_header_banner" class="header">
<div id="_main_header_cnt" class="header-cnt"> <div id="_main_header_cnt" class="header-cnt">
<div class="logo" style="left: -200px;"> </div> <div class="logo" style="left: -200px;">
<!-- 头像 -->
<div id="_main_face" data-no-selection="" class="header-right" style="cursor: pointer;" onclick="showUserMenu();">
<span class="user-info"> <span
class="user-avatar" style="width: 80px;"> <img
src="<%=headerBasePath %>/resource/img/icon.png"><i
class="ui-arr"></i> </span> </span>
</div> </div>
<!-- 头像下方的菜单 -->
<div id="_main_face_menu" style="display:none;" class="ui-pop ui-pop-user" >
<div class="ui-pop-head">
<span id="_main_nick_name" class="user-nick" style="text-align: center;font-weight: bold;color: #555168;font-size: 18px;">管理员</span>
<span class="user-nick" style="line-height: 10px;text-align: center;font-weight: bold;color: #3B20BB;font-size: 12px;">admin</span>
</div>
<ul class="ui-menu"> <div class="btn-group" style="float: right; margin-top: 50px;">
<a type="button" class="btn btn-primary"
onclick="doShowDialog('aboutDialog')">关于</a>
<li>
<a id="_main_logout" href="javascript:doShowDialog('aboutDialog')"><i class="icon-fedbk"></i>关于</a>
</li>
</ul>
<i class="ui-arr"></i>
<i class="ui-arr ui-tarr"></i>
</div> </div>
</div> </div>
</div> </div>
<!--web的导航在左侧--> <!--web的导航在左侧-->
</div> </div>
<div class="panel panel-primary gdialog" id="aboutDialog" style="display: none;width: 400px;position: absolute;">
<div class="panel-heading">关于 <div class="panel panel-primary gdialog" id="aboutDialog"
<a class="close" onclick="doHideDialog('aboutDialog')">&times;</a> style="display: none; width: 400px; position: absolute;">
</div> <div class="panel-heading">
<div class="panel-body"> 关于
<ul class="list-group"> <a class="close" onclick="doHideDialog('aboutDialog')">&times;</a>
<li class="list-group-item">CIM即时通讯后台管理系统</li> </div>
<li class="list-group-item">Email:3979434@qq.com</li> <div class="panel-body" style="padding: 0px;">
<li class="list-group-item">QQ:3979434</li> <div style="text-align: center;background: #5FA0D3;height: 150px;">
</ul> <img src="<%=headerBasePath%>/resource/img/icon.png" style="margin-top: 35px;height: 80px;height: 80px;"/>
</div> </div>
<ul class="list-group">
<li class="list-group-item">
CIM即时通讯后台管理系统
</li>
<li class="list-group-item">
Email:3979434@qq.com
</li>
<li class="list-group-item">
QQ:3979434
</li>
</ul>
</div>
</div>
<div class="panel panel-primary gdialog" id="LoginDialog"
style="display: none; width: 300px; position: absolute; height: 395px;">
<div class="panel-heading">
系统管理员登录
<a class="close" onclick="doHideDialog('LoginDialog')">&times;</a>
</div>
<div style="text-align: center; background: #5FA0D3; height: 100px;">
</div>
<div class="panel-body">
<div class="form-group" style="margin-top: 20px;">
<label style="width: 50px;">
<font color="red">*</font>账号:
</label>
<input type="text" class="form-control" id="account" maxlength="15"
style="display: inline; width: 200px; height: 50px;" />
</div>
<div class="form-group" style="margin-top: 20px;">
<label style="width: 50px;">
<font color="red">*</font>密码:
</label>
<input type="password" class="form-control" id="password"
maxlength="32" style="display: inline; width: 200px; height: 50px;" />
</div>
</div>
<div class="panel-footer" style="text-align: center;">
<a type="button" class="btn btn-success btn-lg" onclick="doLogin()"
style="width: 200px;"> 登录</a>
</div>
</div> </div>
<div id="global_mask"
<div id="global_mask" style="display: none; position: absolute; top: 0px; left: 0px; z-index: 998; background-color: rgb(190, 209, 216); opacity: 0.5; width: 100%; height: 100%; overflow: hidden; background-position: initial initial; background-repeat: initial initial;"></div> style="display: none; position: absolute; top: 0px; left: 0px; z-index: 998; background-color: rgb(190, 209, 216); opacity: 0.5; width: 100%; height: 100%; overflow: hidden; background-position: initial initial; background-repeat: initial initial;"></div>

View File

@ -1,39 +1,5 @@
<%@ page language="java" pageEncoding="utf-8"%> <%@ page language="java" pageEncoding="utf-8"%>
<% <%
String path = request.getContextPath(); response.sendRedirect("admin/session_list.action");
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%> %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>CIM管理系统</title>
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/webbase.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/main-layout.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/base-ui.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/bootstrap/css/bootstrap.min.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/dialog.css" />
<script type="text/javascript" src="<%=basePath%>/resource/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script>
</head>
<body class="web-app ui-selectable">
<br />&lt;<br /><%@include file="header.jsp"%>
<%@include file="nav.jsp"%>
<div id="mainWrapper" style="padding-top: 25px;" >
</div>
<script>
$('#indexMenu').addClass('current');
</script>
</body>
</html>

View File

@ -1,20 +1,27 @@
<% <%
String navBasePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ request.getContextPath(); String navBasePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
%> %>
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page language="java" pageEncoding="UTF-8"%>
<div id="_main_nav" class="ui-vnav"> <div id="_main_nav" class="ui-vnav">
<ul class="ui-nav-inner"> <ul class="ui-nav-inner">
<li class="ui-bar"> <li style="height: 50px; text-align: center; margin-top: 10px;">
<b class="ui-bd"></b> <div class="btn-group" style="margin-top: 5px;">
<a type="button" class="btn btn-danger" target="_blank"
href="javascript:openWebclient();">CIM for
Web(测试版)</a>
</div>
</li> </li>
<li class="ui-item" id="sessionMenu"> <li style="border-bottom: 1px solid #D1D6DA;"></li>
<a href="<%=navBasePath %>/admin/session_list.action"> <li class="ui-item" id="sessionMenu">
<span class="ui-text">在线用户</span> <i class="ui-bg nav-recycle"></i> </a> <a href="<%=navBasePath%>/admin/session_list.action"> <span
</li> class="ui-text">在线用户</span> <i class="ui-bg nav-recycle"></i> </a>
</li>
</ul> </ul>
<!-- 阴影 -->
<b class="ui-shd"></b>
</div> </div>

View File

@ -1,6 +1,5 @@
<%@ page language="java" pageEncoding="utf-8"%> <%@ page language="java" pageEncoding="utf-8"%>
<%@ page import="java.util.Collection"%> <%@ page import="java.util.Collection"%>
<%@ page import="com.farsunset.ichat.common.util.StringUtil"%>
<%@ page import="com.farsunset.cim.nio.session.CIMSession"%> <%@ page import="com.farsunset.cim.nio.session.CIMSession"%>
<% <%
String path = request.getContextPath(); String path = request.getContextPath();
@ -27,33 +26,18 @@
<script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script> <script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script>
<script> <script>
function doOffLine(account)
{
var setting = {hint:"确定让这个用户强制下线吗?",
onConfirm:function(){
$.post("<%=basePath%>/admin/session_offline.action", {account:account},
function(data){
showSTip("下线成功");
$('#'+account).fadeOut().fadeIn().fadeOut();
doHideConfirm();
});
}};
doShowConfirm(setting);
}
function showMessageDialog(account) function showMessageDialog(account)
{ {
doShowDialog("messageDialog"); doShowDialog("messageDialog");
$('#account').val(account); $('#Saccount').val(account);
} }
function doSendMessage() function doSendMessage()
{ {
var message = $('#message').val(); var message = $('#message').val();
var account = $('#account').val(); var account = $('#Saccount').val();
if($.trim(message)=='') if($.trim(message)=='')
{ {
return; return;
@ -69,6 +53,20 @@
}); });
} }
function onImageError(obj)
{
obj.src="<%=basePath%>/webclient/images/icon_head_default.png";
}
function openWebclient(){
var height = $(document).height();
var width = $(document).width();
window.open ("<%=basePath%>/console/webclient/main.jsp", "","height="+height+", width="+width+", top=0, left=0, toolbar=no,menubar=no, scrollbars=no, resizable=no,location=no, status=no");
}
</script> </script>
</head> </head>
<body class="web-app ui-selectable"> <body class="web-app ui-selectable">
@ -79,24 +77,28 @@
<%@include file="../nav.jsp"%> <%@include file="../nav.jsp"%>
<div id="mainWrapper"> <div id="mainWrapper">
<div class="panel panel-default">
<div class="panel-heading"> <div class="lay-main-toolbar">
在线用户
</div> </div>
<div class="panel-body" style="padding: 5px;">
<div>
<form action="<%=basePath%>/admin/user_manage.action" method="post" <form action="<%=basePath%>/admin/user_manage.action" method="post"
id="searchForm" style="padding: 0px;"> id="searchForm" style="padding: 0px;">
<input type="hidden" name="currentPage" id="currentPage" /> <input type="hidden" name="currentPage" id="currentPage" />
<table style="margin: 5px;width: 100%" class="utable"> <table style="width: 100%" class="utable">
<thead> <thead>
<tr class="tableHeader"> <tr class="tableHeader">
<th width="4%">头像</th>
<th width="15%">账号</th> <th width="15%">账号</th>
<th width="15%">终端来源</th> <th width="10%">终端</th>
<th width="15%">终端ID</th> <th width="10%">设备型号</th>
<th width="15%">终端型号</th> <th width="10%">在线时长</th>
<th width="15%">在线时长</th> <th width="28%">位置</th>
<th width="10%">操作</th> <th width="12%">操作</th>
</tr> </tr>
</thead> </thead>
@ -105,39 +107,41 @@
<% <%
for(CIMSession ios:sessionList) for(CIMSession ios:sessionList)
{ {
if(ios.getAccount()!=null)
{
%> %>
<tr id="<%=ios.getAccount()%>"> <tr id="<%=ios.getAccount() %>" style=" height: 50px;">
<td>
<img width="40px" height="40px" onerror='onImageError(this)' src="http://cim.oss-cn-hangzhou.aliyuncs.com/UI_<%=ios.getAccount() %>"/>
</td>
<td> <td>
<%=ios.getAccount() %> <%=ios.getAccount() %>
</td> </td>
<td> <td>
<%=ios.getChannel() %> <%=ios.getChannel()%>
</td> </td>
<td> <td>
<%=ios.getDeviceId() %> <%=ios.getDeviceModel()==null?"":ios.getDeviceModel()%>
</td>
<td>
<%=ios.getDeviceModel() %>
</td> </td>
<td> <td>
<%=(System.currentTimeMillis()-ios.getBindTime())/1000 %>秒 <%=(System.currentTimeMillis()-ios.getBindTime())/1000 %>秒
</td> </td>
<td>
<%=ios.getAttribute("location")==null?"":ios.getAttribute("location") %>
</td>
<td> <td>
<div class="btn-group btn-group-xs"> <div class="btn-group btn-group-xs">
<button type="button" class="btn btn-primary" style="padding: 5px;" onclick="showMessageDialog('<%=ios.getAccount() %>')">发送消息</button> <button type="button" class="btn btn-primary" style="padding: 5px;"
<button type="button" class="btn btn-danger" style="padding: 5px;" onclick="doOffLine('<%=ios.getAccount() %>')">强制下线</button> onclick="showMessageDialog('<%=ios.getAccount() %>')">发送消息</button>
</div> </div>
</td> </td>
</tr> </tr>
<%} %> <%}} %>
</tbody> </tbody>
<tfoot>
</tfoot>
</table> </table>
</form> </form>
@ -153,23 +157,30 @@
<form role="form"> <form role="form">
<div class="form-groupBuy"> <div class="form-groupBuy">
<label for="Amobile"> <label for="Amobile">
接收账号: 接收账号:
</label> </label>
<input type="text" class="form-control" id="account" name="account" <input type="text" class="form-control" id="Saccount" name="account"
style=" width: 100%;font-size: 20px;font-weight: bold;" disabled="disabled" /> style=" width: 100%;font-size: 20px;font-weight: bold;" disabled="disabled" />
</div> </div>
<div class="form-groupBuy" style="margin-top: 20px;"> <div class="form-groupBuy" style="margin-top: 20px;">
<label for="exampleInputFile" style="padding-left: 7px;">消 容:</label> <label for="exampleInputFile">消息内容:</label>
<textarea rows="10" style="width: 100%;height: 120px;" id="message" name="message" class="form-control"></textarea> <textarea rows="10" style="width: 100%;height: 120px;" id="message" name="message" class="form-control"></textarea>
</div> </div>
<div class="form-groupBuy" style="margin-top: 20px;">
<center>
<button type="button" style="width: 150px;" class="btn btn-success btn-lg" onclick="doSendMessage()">发 送</button>
</center>
</div>
</form> </form>
</div> </div>
<div class="panel-footer" style="padding:5px 10px;text-align: center;">
<a type="button" class="btn btn-success btn-lg" onclick="doSendMessage()" style="width: 200px;"> 发送</a>
</div>
</div>
<div class="panel panel-primary gdialog" id="scanDownloadDialog" style="display: none;width: 300px;position: absolute;z-index: 1001;">
<div class="panel-heading">二维码下载
<a class="close" onclick="doHideDialog('scanDownloadDialog'),$('#scanDownloadDialog').css('z-index',1000);">&times;</a>
</div>
<div class="panel-body">
<img src = "<%=basePath%>/resource/img/scan_download.png"/>
</div>
</div> </div>
<script> <script>
@ -177,4 +188,4 @@
</script> </script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="0" height="0"
backgroundColor="#FEFEFE"
creationComplete="init(event)"
xmlns:mx="library://ns.adobe.com/flex/mx"
>
<fx:Script>
<![CDATA[
import com.farsunset.webcim.bean.Message;
import com.farsunset.webcim.bean.ReplyBody;
import mx.events.FlexEvent;
private var CIM_HOST:String = "127.0.0.1";
private var CIM_PORT:String = "23456";
private var socket:Socket;
private var heartbeat_timer:Timer=new Timer(180 * 1000);;
var froceOffline :Boolean = false;
protected function init(event:FlexEvent):void
{
ExternalInterface.call("bridgeCreationComplete");
ExternalInterface.addCallback("connect",connect);
ExternalInterface.addCallback("setAccount",setAccount);
ExternalInterface.addCallback("getOfflineMessage",getOfflineMessage);
ExternalInterface.addCallback("logout",logout);
heartbeat_timer.addEventListener(TimerEvent.TIMER,doSendHeartbeat);
}
public function connect(host:String):void
{
CIM_HOST = host;
var policyfile:String="xmlsocket://"+CIM_HOST+":"+CIM_PORT;
Security.loadPolicyFile(policyfile);
socket=new Socket();
socket.addEventListener(Event.CONNECT,sessionCreated);//监听是否连接上服务器
socket.addEventListener(Event.CLOSE,sessionClosed);//监听套接字连接是否关闭
socket.addEventListener(IOErrorEvent.IO_ERROR,exceptionCaught);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorFun);
//监听服务器新信息
socket.addEventListener(ProgressEvent.SOCKET_DATA,messageReceived);
socket.connect(CIM_HOST,parseInt(CIM_PORT));//连接服务器
}
public function setAccount(account:String,deviceId:String):void
{
var xml:String="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<sent>";
xml+="<key>client_bind</key>";
xml+="<data>";
xml+="<account>"+account+"</account>";
xml+="<deviceId>"+deviceId+"</deviceId>";
xml+="<channel>web</channel>";
xml+="<device>browser</device>";
xml+="</data>";
xml+="</sent>";
send(xml);
}
public function getOfflineMessage(account:String):void
{
var xml:String="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<sent>";
xml+="<key>client_get_offline_message</key>";
xml+="<data>";
xml+="<account>"+account+"</account>";
xml+="</data>";
xml+="</sent>";
send(xml);
}
public function logout():void
{
socket.close();
}
private function sessionCreated(event:Event):void
{
ExternalInterface.call("sessionCreated");
heartbeat_timer.start();
froceOffline = false;
}
private function doSendHeartbeat(e:TimerEvent):void
{
var xml:String="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<sent>";
xml+="<key>client_heartbeat</key>";
xml+="</sent>";
send(xml);
}
private function sessionClosed(event:Event):void
{
ExternalInterface.call("sessionClosed");
if(!froceOffline)
{
connect(CIM_HOST);
}
//heartbeat_timer.stop();
}
private function exceptionCaught(event:Event):void{
//Alert.show("exceptionCaught","提示");
}
private function securityErrorFun(event:Event):void{
//Alert.show("securityErrorFun"+event.toString(),"提示");
}
/**接受服务器信息*/
internal function messageReceived(event:ProgressEvent):void
{
var msg:String="";
//循环读取数据
while(socket.bytesAvailable)
{
msg+=socket.readUTFBytes(socket.bytesAvailable);
}
var index:int = msg.indexOf("\b");
if(msg.indexOf("\b")>=0)
{
msg = msg.substring(0,index);
}
var xml:XML=XML(msg);
var data:Object = xml as Object;
if(xml.name()=="reply"){
ExternalInterface.call("onReplyReceived",ReplyBody.mappingToJSON(xml));
}
if(xml.name()=="message"){
if(xml["type"]=="999")
{
froceOffline = true;
}
ExternalInterface.call("onMessageReceived",Message.mappingToJSON(xml),xml["content"].toString());
}
}
/**发送数据到服务器*/
internal function send(msg:String):void
{
//新建一个ByteArray来存放数据
socket.writeUTFBytes(msg+"\b");
//调用flush方法发送信息
socket.flush();
}
]]>
</fx:Script>
</s:Application>

View File

@ -0,0 +1,39 @@
<%@ page language="java" pageEncoding="utf-8"%>
<script type="text/javascript">
function doLogin()
{
ACCOUNT = $('#account').val();
if($.trim(ACCOUNT)=='' )
{
return;
}
showProcess('正在接入请稍后......');
document.getElementById("CIMBridge").connect(CIM_HOST);
}
</script>
<div class="panel panel-primary gdialog" id="LoginDialog"
style="display: none; width: 300px; position: absolute;">
<div class="panel-heading">
登录
</div>
<div style="text-align: center;background: #5FA0D3;height: 150px;">
<img src="<%=basePath%>/resource/img/icon.png" style="margin-top: 35px;height: 80px;height: 80px;"/>
</div>
<div class="panel-body">
<div class="alert alert-info">
登录之前请在 cim.js里面设置当前服务器的IP地址
</div>
<div class="form-group" style="margin-top: 20px;">
<label style="width: 50px;">
<font color="red">*</font>账号:
</label>
<input type="text" class="form-control" id="account"
maxlength="15" style="display: inline; width: 200px;height: 50px;" />
</div>
</div>
<div class="panel-footer" style="text-align: center;">
<a type="button" class="btn btn-success btn-lg" onclick="doLogin()" style="width: 200px;"> 登录</a>
</div>
</div>

View File

@ -0,0 +1,77 @@
package com.farsunset.webcim.bean
{
import com.adobe.serialization.json.JSON;
public class Message
{
/**
*
*/
public var mid:String;
/**
*
*/
public var type:String;
/**
*
*/
public var title:String;
/**
* type content format text,json ,xml数据格式
*/
public var content:String = "";
/**
*
*/
public var sender:String;
/**
*
*/
public var receiver:String;
/**
* url
*/
public var file:String;
/**
*
*/
public var fileType:String;
/**
* content
*/
public var format:String = "txt";
public var timestamp:Number;
public static function mappingToJSON(xml:XML):Object
{
var message:Message = new Message();
message.mid = xml["mid"];
message.type = xml["type"];
message.title = xml["title"];
message.sender = xml["sender"];
message.receiver = xml["receiver"];
message.file = xml["file"];
message.fileType = xml["fileType"];
message.timestamp = xml["timestamp"];
message.content = "";
return com.adobe.serialization.json.JSON.encode(message).toString();
}
}
}

View File

@ -0,0 +1,18 @@
<%@ page language="java" pageEncoding="utf-8"%>
<div class="panel panel-primary" id="MessageDialog"
style="display: none; width: 700px; position: absolute;min-height: 500px;box-shadow: 0 0 10px -2px #0B203A;">
<div class="panel-heading" style="height: 80px;background: #428bca;line-height: 80px;padding: 0 10px;">
消息列表
<span id="current_account" style="color: white;float: right;font-weight: bold;"></span>
</div>
<div class="panel-body" id="messageList">
</div>
</div>

View File

@ -0,0 +1,28 @@
package com.farsunset.webcim.bean
{
import com.adobe.serialization.json.JSON;
public class ReplyBody
{
public var key:String;
public var code:String;
public var message:String;
public var data:Object;
public var timestamp:Number;
public static function mappingToJSON(xml:XML):Object
{
var body:ReplyBody = new ReplyBody();
body.key = xml["key"];
body.code = xml["code"];
body.timestamp = xml["timestamp"];
return com.adobe.serialization.json.JSON.encode(body);
}
}
}

View File

@ -0,0 +1,3 @@
var CIM_HOST="127.0.0.1";//修改为服务器的真实IP
var ACCOUNT;

View File

@ -0,0 +1,138 @@
<%@ page language="java" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path;
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta charset="utf-8"/>
<title>ICHAT for web(beta) </title>
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/bootstrap/css/bootstrap.min.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/dialog.css" />
<script type="text/javascript" src="<%=basePath%>/resource/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script>
<script type="text/javascript" src="cim.js"></script>
</head>
<script type="text/javascript">
/**CIMBridge.swf提供的接口,源码是CIMBridge.mxml , ReplyBody.as ,Message.as 用flahs builder 工具 导入开发。
connect(host);连接服务端 host:服务器IP
setAccount(account) 绑定客户端账号到服务端 account账号
logout() 退出连接
getOfflineMessage(account) 拉取离线消息,需要服务端实现 请求key client_get_offline_message
**/
/** 当socket连接成功回调 **/
function sessionCreated()
{
document.getElementById("CIMBridge").setAccount(ACCOUNT,ACCOUNT);
}
/** 当socket断开是回调 **/
function sessionClosed()
{
}
/** 当收到请求回复时候回调 **/
function onReplyReceived(data)
{
var json = JSON.parse(data)
if(json.key=='client_bind' && json.code==200)
{
hideProcess();
doHideDialog('LoginDialog');
doShowDialog('MessageDialog');
$("#current_account").text("当前账号:"+ACCOUNT);
}
}
/** 当收到消息时候回调 **/
function onMessageReceived(data,content)
{
var message = JSON.parse(data);
if(message.type=='2')
{
message.content = content;
$("#messageList").append("<div class='alert alert-info' >"+content+"</div>");
}
}
/** 当flex socket 组件(CIMBridge.swf) 加载完成是回调 **/
function bridgeCreationComplete(){
hideProcess();
}
$(document).ready(function(){
showProcess("加载中......");
doShowDialog('LoginDialog');
});
</script>
<script language="Javascript">
document.oncontextmenu = function (){
return false;
}
window.onload=function()
{
window.onkeydown=function(e)
{
if(e.which)
{
if(e.which==116)
{
return false;
}
}
else if(event.keyCode)
{
if(event.keyCode==116)
{
return false;
}
}
}
}
</script>
<body style="background-color: rgb(190, 209, 216);">
<object type="application/x-shockwave-flash" data="CIMBridge.swf" id="CIMBridge" width="0" height="0">
<param name="quality" value="low"/>
<param name="allowScriptAccess" value="always"/>
<param name="wmode" value="transparent"/>
<param name="movie" value="CIMBridge.swf"/>
</object>
<div id="global_mask" style="display: none; position: absolute; top: 0px; left: 0px; z-index: 998; background-color: rgb(190, 209, 216); opacity: 0.5; width: 100%; height: 100%; overflow: hidden; background-position: initial initial; background-repeat: initial initial;"></div>
<%@include file="LoginDialog.jsp"%>
<%@include file="MessageDialog.jsp"%>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@

/* golabe */ /* golabe */
@ -234,10 +234,10 @@
.icon_success{ .icon_success{
background: url(../img/icon_success.png) no-repeat; background: url(../img/icon_success.png) no-repeat;
width: 32px; width: 38px;
height: 32px; height: 38px;
left:10px; left:10px;
top:9px; top:6px;
position: absolute; position: absolute;
} }
.icon_hint{ .icon_hint{
@ -273,4 +273,28 @@
top:15px; top:15px;
position: absolute; position: absolute;
} }
.form-group label {
width: 60px;
text-align: right;
}
.lay-main-toolbar {
height: 60px;
border-radius: 0px;
background-color: #f5f6f9;
border-bottom: 1px solid #B5BBBF;
border-right: 1px solid #B5BBBF;
position: relative;
width: 100%;
padding: 7px;
}
.btn i {
font-size: 24px;
margin-right: 4px;
font-style: normal;
vertical-align: text-top;
line-height: 18px;
}

View File

@ -26,4 +26,47 @@
.gdialog .close:hover, .gdialog .close:focus{ .gdialog .close:hover, .gdialog .close:focus{
opacity: .93; opacity: .93;
filter: alpha(opacity=93); filter: alpha(opacity=93);
} }
.gdialog .panel-heading{
cursor: move;
}
.tip_process {
zoom: 1;
color:#394A5E;
text-align: center;
line-height: 50px;
height: 50px;
-webkit-box-shadow: 0 0 20px -2px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 0 20px -2px rgba(0,0,0,0.5);
-ms-box-shadow: 0 0 20px -2px rgba(0,0,0,0.5);
box-shadow: 0 0 20px -2px rgba(0, 0, 0, 0.5);
border: 1px solid #6D7A89;
z-index: 9999;
background-color: white;
min-width: 300px;
position: absolute;
z-index:9999;;
font-size: 16px;
font-weight: bold;
}
.icon_loading_mid{
background: url(../img/icon_loading_mid.gif) no-repeat;
width: 31px;
height: 31px;
left:10px;
top:10px;
position: absolute;
}
.icon_loading_small{
background: url(../img/icon_loading_small.gif) no-repeat;
width: 22px;
height: 22px;
left:10px;
top:15px;
position: absolute;
}

View File

@ -3,13 +3,14 @@
/* left nav */ /* left nav */
.ui-vnav { .ui-vnav {
position: fixed; position: fixed;
top: 50px; top: 100px;
left: 0; left: 0;
width: 170px; width: 180px;
min-height: 560px; min-height: 560px;
height: 960px; height: 960px;
background: #d8dce5; background: #eaedf4;
_overflow: hidden; _overflow: hidden;
border-right: 1px solid #d8dce5;
} }
@ -29,41 +30,41 @@ border-bottom: 1px solid #eaeaea;
} }
.ui-vnav .ui-item { .ui-vnav .ui-item {
height: 36px; height: 45px;
margin-bottom: 3px; line-height: 45px;
line-height: 36px;
padding: 0 10px; padding: 0 10px;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
border-bottom: 1px #eaedf4 solid;
border-top: 1px #eaedf4 solid;
} }
.ui-vnav .ui-item:hover { .ui-vnav .ui-item:hover {
background-color: #C8CCD5;
color: white; color: white;
background-color: #e0e4ed;
border-bottom: 1px #d8dce5 solid;
border-top: 1px #d8dce5 solid;
} }
.ui-vnav .current,.ui-vnav .current:hover { .ui-vnav .current,.ui-vnav .current:hover {
/*border-left: solid 3px #14A7D4; background-color: #ced4e0;
background-color: #7b7b7b;*/ border-bottom: 1px #c8ccd5 solid;
background:url(../img/nav_selected_bg.png) no-repeat ; border-top: 1px #c8ccd5 solid;
color: white; border-left: 5px #5FA0D3 solid;
} }
.ui-vnav .ui-item a { .ui-vnav .ui-item a {
position: relative; position: relative;
display: block; display: block;
height: 36px; height: 45px;
line-height: 36px; line-height: 45px;
font-family: "\5FAE\8F6F\96C5\9ED1","\534E\6587\7EC6\9ED1"; font-family: "\5FAE\8F6F\96C5\9ED1","\534E\6587\7EC6\9ED1";
font-size: 18px; font-size: 18px;
color: #666; color: #666;
text-decoration:none; text-decoration:none;
} }
.ui-vnav .ui-bg, .ui-vnav .current a, .ui-vnav a:active {
background-position: -999px -999px;
background-repeat: no-repeat;
color: white;
}
.ui-vnav .ui-shd { .ui-vnav .ui-shd {
position: absolute; position: absolute;
right: 0; right: 0;

View File

@ -6,8 +6,6 @@
.utable { .utable {
border-collapse: collapse; border-collapse: collapse;
border-spacing: 0; border-spacing: 0;
border-top: solid 1px #D4D4D4;
border-left: solid 1px #D4D4D4;
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
background: #ffffff; background: #ffffff;
@ -15,8 +13,10 @@
margin-right: 10px; margin-right: 10px;
} }
.utable tr th { .utable tr th {
background-color: #d8dce5; background-color: #F3F3F3;
border: solid 1px #D4D4D4; border-right: solid 1px #D4D4D4;
border-left: solid 1px #D4D4D4;
border-bottom: solid 1px #D4D4D4;
color: #463E5E; color: #463E5E;
line-height: 40px; line-height: 40px;
font-size: 14px; font-size: 14px;
@ -26,7 +26,7 @@
.utable tr:hover { .utable tr:hover {
background-color: #F1F1F1; background-color: #f5f6f9;
} }
@ -40,7 +40,6 @@ height:35px;
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
overflow: hidden; overflow: hidden;
white-space: nowrap;
} }

View File

@ -23,7 +23,7 @@ body .hide,.app-web .hide,.app-qplus .hide,.app-appbox .hide{display:none}
body .ellipsis{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;_width:100%;word-wrap:normal} body .ellipsis{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;_width:100%;word-wrap:normal}
body{color:#666;background:#F1F1F1} body{color:#666;background:#F1F1F1}
a{color:#1D719E} a{color:#1D719E}
#mainWrapper{ width: auto; margin-left: 170px; min-height: 600px;padding-top: 65px;padding-left: 10px;;padding-bottom: 50px; padding-right: 10px;} #mainWrapper{ width: auto; margin-left: 180px; min-height: 600px;padding-top:100px; 10px;;padding-bottom: 50px; }
.mb{margin-bottom:15px} .mb{margin-bottom:15px}
.float_right{float:right} .float_right{float:right}
.text_right{text-align:right} .text_right{text-align:right}
@ -65,10 +65,12 @@ a:focus {
/* header */ /* header */
.header{ .header{
position: relative; position: relative;
height:50px; height:100px;
margin:0 auto; margin:0 auto;
background:url(../img/top-bg.png) repeat-x left top; width:100%;
box-shadow: 0 1px 5px #ccc; -webkit-box-shadow: 0 0 10px -2px #0B203A;
box-shadow: 0 0 10px -2px #0B203A;
background: #0B203A;
z-index: 10; z-index: 10;
} }
.app-appbox .header{ .app-appbox .header{
@ -551,14 +553,13 @@ a:focus {
background:#d8d638; background:#d8d638;
} }
/* ui-pop */ /* ui-pop */
.ui-pop{ .ui-pop {
position:absolute; position: absolute;
border:1px solid #CEC754; border: 1px solid #CEC754;
border-radius:3px; background: #FFFAAB;
background:#FFFAAB; box-shadow: 0px 1px 2px #CCC;
box-shadow:1px 1px 2px #CCC; color: #9D9A69;
color:#9D9A69; font-size: 12px;
font-size:12px;
} }
.ui-pop-text{ .ui-pop-text{
padding:13px 15px 13px; padding:13px 15px 13px;
@ -1296,16 +1297,15 @@ a:focus {
background:#fff url(../img/avatar-hover-bg.png?t=1) no-repeat left top; background:#fff url(../img/avatar-hover-bg.png?t=1) no-repeat left top;
} }
/* 用户浮层 */ /* 用户浮层 */
.ui-pop-user{ .ui-pop-user {
width:168px; width: 168px;
right:0; right: 10px;
top:50px; top: 45px;
background:#FFF; background: #FFF;
border-color:#abb0bb; border-color: #c8ccd5;
border-top:none; border-radius: 0;
border-radius:0; color: #666;
color:#666; z-index: 10;
z-index:10;
} }
.ui-pop-user .ui-pop-head{ .ui-pop-user .ui-pop-head{
padding:0 15px; padding:0 15px;
@ -1465,4 +1465,5 @@ a:focus {
.app-photo .wrapper{margin-top:-1px;} .app-photo .wrapper{margin-top:-1px;}
/* photo */ /* photo */
/* vnav *//* |xGv00|ca7570ffdcf2d601f22a688ce458168d */ /* vnav *//* |xGv00|ca7570ffdcf2d601f22a688ce458168d */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -117,9 +117,49 @@ function prepareShowDialog(dialog)
var w = $(document).width(); var w = $(document).width();
var mheight = dialog.height(); var mheight = dialog.height();
var mwidth = dialog.width(); var mwidth = dialog.width();
dialog.css({top:(h-mheight)/3,left:(w-mwidth)/2}); dialog.css({top:150,left:(w-mwidth)/2});
$('#global_mask').css('height',h); $('#global_mask').css('height',h);
$('#global_mask').fadeIn(); $('#global_mask').fadeIn();
$("body").attr("unselectable","no");
$("body").attr("onselectstart","return false;");
dialog.find(".panel-heading").mousedown(function(e)
{
var offset = $(this).offset();
var x = e.pageX - offset.left;
var y = e.pageY - offset.top;
$(document).bind("mousemove",function(ev)
{
var _x = ev.pageX - x;
var _y = ev.pageY - y;
if(_x<=0)
{
_x=0;
}
if(_y <=0 )
{
_y=0;
}
if(_x >= (w - mwidth))
{
_x=(w - mwidth);
}
if( _y >= (h - mheight))
{
_y = (h - mheight);
}
dialog.css({left:_x+"px",top:_y+"px"});
});
});
$(document).mouseup(function()
{
dialog.css("cursor","default");
$(this).unbind("mousemove");
})
} }
@ -128,7 +168,6 @@ function doShowDialog(dialogId,animate){
var dialog = $('#'+dialogId); var dialog = $('#'+dialogId);
prepareShowDialog(dialog); prepareShowDialog(dialog);
if(animate==undefined) if(animate==undefined)
{ {
/*$('#'+dialogId).fadeIn(); /*$('#'+dialogId).fadeIn();
@ -261,6 +300,6 @@ function gotoPage(number)
function getDateTime(t) { function getDateTime(t) {
//return new Date(parseInt(t)).toLocaleString().substr(0,17) //return new Date(parseInt(t)).toLocaleString().substr(0,17)
var tt=new Date(parseInt(t)).toLocaleString().replace(/年|月/g, "-").replace(/日/g, " ") //return new Date(parseInt(t)).pattern("yyyy-MM-dd HH:mm:ss");
return tt; return new Date(parseInt(t)).toLocaleString().replace(/年|月/g, "-").replace(/日/g, " ");
} }

View File

@ -7,7 +7,7 @@ import java.util.UUID;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.farsunset.cim.nio.constant.CIMConstant; import com.farsunset.cim.nio.constant.CIMConstant;
import com.farsunset.cim.nio.handle.CIMRequestHandler; import com.farsunset.cim.nio.handler.CIMRequestHandler;
import com.farsunset.cim.nio.mutual.Message; import com.farsunset.cim.nio.mutual.Message;
import com.farsunset.cim.nio.mutual.ReplyBody; import com.farsunset.cim.nio.mutual.ReplyBody;
import com.farsunset.cim.nio.mutual.SentBody; import com.farsunset.cim.nio.mutual.SentBody;

View File

@ -2,7 +2,7 @@
package com.farsunset.ichat.cim.handler; package com.farsunset.ichat.cim.handler;
import com.farsunset.cim.nio.constant.CIMConstant; import com.farsunset.cim.nio.constant.CIMConstant;
import com.farsunset.cim.nio.handle.CIMRequestHandler; import com.farsunset.cim.nio.handler.CIMRequestHandler;
import com.farsunset.cim.nio.mutual.ReplyBody; import com.farsunset.cim.nio.mutual.ReplyBody;
import com.farsunset.cim.nio.mutual.SentBody; import com.farsunset.cim.nio.mutual.SentBody;
import com.farsunset.cim.nio.session.CIMSession; import com.farsunset.cim.nio.session.CIMSession;

View File

@ -4,7 +4,7 @@ package com.farsunset.ichat.cim.handler;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.farsunset.cim.nio.constant.CIMConstant; import com.farsunset.cim.nio.constant.CIMConstant;
import com.farsunset.cim.nio.handle.CIMRequestHandler; import com.farsunset.cim.nio.handler.CIMRequestHandler;
import com.farsunset.cim.nio.mutual.ReplyBody; import com.farsunset.cim.nio.mutual.ReplyBody;
import com.farsunset.cim.nio.mutual.SentBody; import com.farsunset.cim.nio.mutual.SentBody;
import com.farsunset.cim.nio.session.CIMSession; import com.farsunset.cim.nio.session.CIMSession;

View File

@ -26,7 +26,7 @@
</map> </map>
</property> </property>
</bean> </bean>
<bean id="mainIoHandler" class="com.farsunset.cim.nio.handle.MainIOHandler" > <bean id="mainIoHandler" class="com.farsunset.cim.nio.handler.MainIOHandler" >
<property name="handlers"> <property name="handlers">
<map> <map>
@ -37,7 +37,7 @@
<bean class="com.farsunset.ichat.cim.handler.LogoutHandler" /> <bean class="com.farsunset.ichat.cim.handler.LogoutHandler" />
</entry> </entry>
<entry key="client_heartbeat"> <entry key="client_heartbeat">
<bean class="com.farsunset.cim.nio.handle.HeartbeatHandler"/> <bean class="com.farsunset.cim.nio.handler.HeartbeatHandler"/>
</entry> </entry>
<entry key="sessionClosedHander"> <entry key="sessionClosedHander">
<bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/> <bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/>

View File

@ -32,6 +32,7 @@ public interface CIMConstant {
public static byte MESSAGE_SEPARATE='\b'; public static byte MESSAGE_SEPARATE='\b';
public static byte FLEX_DATA_SEPARATE='\0';
public static int CIM_DEFAULT_MESSAGE_ORDER=1; public static int CIM_DEFAULT_MESSAGE_ORDER=1;
@ -41,6 +42,17 @@ public interface CIMConstant {
public static final String HEARTBEAT_KEY ="heartbeat"; public static final String HEARTBEAT_KEY ="heartbeat";
/**
* FLEX 客户端socket请求发的安全策略请求需要特殊处理返回安全验证报文
*/
public static final String FLEX_POLICY_REQUEST ="<policy-file-request/>";
public static final String FLEX_POLICY_RESPONSE ="<?xml version=\"1.0\"?><cross-domain-policy><site-control permitted-cross-domain-policies=\"all\"/><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>\0";
/** /**
* 对应ichat spring-cim.xml > bean:mainIoHandler >handlers * 对应ichat spring-cim.xml > bean:mainIoHandler >handlers
* 服务端处理对应的handlers应该继承与com.farsunset.cim.nio.handle.AbstractHandler * 服务端处理对应的handlers应该继承与com.farsunset.cim.nio.handle.AbstractHandler

View File

@ -36,14 +36,14 @@ public class ServerMessageDecoder extends FrameDecoder {
byte[] data = new byte[length-1]; byte[] data = new byte[length-1];
buffer.readBytes(data); buffer.readBytes(data);
String messsage = new String(new String(data,CIMConstant.ENCODE_UTF8)); String message = new String(new String(data,CIMConstant.ENCODE_UTF8));
System.out.println("[ServerMessageDecoder]:"+message);
buffer.readByte(); buffer.readByte();
SentBody body = new SentBody(); SentBody body = new SentBody();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder(); DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(messsage.toString().getBytes())); Document doc = builder.parse(new ByteArrayInputStream(message.toString().getBytes()));
body.setKey(doc.getElementsByTagName("key").item(0).getTextContent()); body.setKey(doc.getElementsByTagName("key").item(0).getTextContent());
NodeList items = doc.getElementsByTagName("data").item(0).getChildNodes(); NodeList items = doc.getElementsByTagName("data").item(0).getChildNodes();
for (int i = 0; i < items.getLength(); i++) { for (int i = 0; i < items.getLength(); i++) {
@ -52,11 +52,28 @@ public class ServerMessageDecoder extends FrameDecoder {
} }
data = null; data = null;
messsage = null; message = null;
return body; return body;
} }
/**
* CIMConstant.FLEX_DATA_SEPARATE 为FLEX客户端socket验证消息界限
*
*/
if (buffer.readable()&& length > 0 && CIMConstant.FLEX_DATA_SEPARATE == buffer.getByte(length-1)) {
byte[] data = new byte[length-1];
buffer.readBytes(data);
String message = new String(new String(data,CIMConstant.ENCODE_UTF8));
System.out.println("[ServerMessageDecoder]:"+message);
//将末尾的消息分隔符读取掉
buffer.readByte();
data = null;
return message;
}
return null; return null;
} }

View File

@ -26,6 +26,7 @@ public class ServerMessageEncoder extends OneToOneEncoder {
ChannelBuffer buf = ChannelBuffers.dynamicBuffer();//(2) ChannelBuffer buf = ChannelBuffers.dynamicBuffer();//(2)
buf.writeBytes(message.toString().getBytes(CIMConstant.ENCODE_UTF8)); buf.writeBytes(message.toString().getBytes(CIMConstant.ENCODE_UTF8));
buf.writeByte(CIMConstant.MESSAGE_SEPARATE); buf.writeByte(CIMConstant.MESSAGE_SEPARATE);
System.out.println("[ServerMessageEncoder]:"+message);
return buf; return buf;
} }

View File

@ -1,5 +1,5 @@
package com.farsunset.cim.nio.handle; package com.farsunset.cim.nio.handler;
/** /**
* 请求处理接口,所有的请求实现必须实现此接口 * 请求处理接口,所有的请求实现必须实现此接口

View File

@ -1,5 +1,5 @@
package com.farsunset.cim.nio.handle; package com.farsunset.cim.nio.handler;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;

View File

@ -1,5 +1,5 @@
package com.farsunset.cim.nio.handle; package com.farsunset.cim.nio.handler;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.HashMap; import java.util.HashMap;
@ -76,6 +76,16 @@ public class MainIOHandler extends SimpleChannelUpstreamHandler {
throws Exception { throws Exception {
logger.debug("message: " + e.getMessage().toString()); logger.debug("message: " + e.getMessage().toString());
/**
* flex 客户端安全策略请求需要返回特定报文
*/
if(CIMConstant.FLEX_POLICY_REQUEST.equals(e.getMessage()))
{
ctx.getChannel().write(CIMConstant.FLEX_POLICY_RESPONSE);
return ;
}
CIMSession cimSession =new CIMSession(ctx.getChannel()); CIMSession cimSession =new CIMSession(ctx.getChannel());
ReplyBody reply = new ReplyBody(); ReplyBody reply = new ReplyBody();
SentBody body = (SentBody) e.getMessage(); SentBody body = (SentBody) e.getMessage();

View File

@ -1,3 +1,4 @@
#Mon Jun 23 09:53:56 CST 2014 #Mon Sep 15 18:21:03 CST 2014
eclipse.preferences.version=1 eclipse.preferences.version=1
encoding//WebRoot/console/webclient/cim.js=UTF-8
encoding/<project>=UTF-8 encoding/<project>=UTF-8

View File

@ -14,7 +14,7 @@
> >
<bean id="mainIoHandler" class="com.farsunset.cim.nio.handle.MainIOHandler" init-method="init" > <bean id="mainIoHandler" class="com.farsunset.cim.nio.handler.MainIOHandler" init-method="init" >
<property name="port" value="23456" /> <property name="port" value="23456" />
<property name="handlers"> <property name="handlers">
<map> <map>
@ -25,7 +25,7 @@
<bean class="com.farsunset.ichat.cim.handler.LogoutHandler" /> <bean class="com.farsunset.ichat.cim.handler.LogoutHandler" />
</entry> </entry>
<entry key="client_heartbeat"> <entry key="client_heartbeat">
<bean class="com.farsunset.cim.nio.handle.HeartbeatHandler"/> <bean class="com.farsunset.cim.nio.handler.HeartbeatHandler"/>
</entry> </entry>
<entry key="sessionClosedHander"> <entry key="sessionClosedHander">
<bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/> <bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/>

View File

@ -1,8 +1,10 @@
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page language="java" pageEncoding="UTF-8"%>
<% <%
String headerBasePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ request.getContextPath(); String headerBasePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
Object admin = session.getAttribute("admin");
%> %>
<script type="text/javascript"> <script type="text/javascript">
function showUserMenu() function showUserMenu()
@ -33,6 +35,31 @@
}); });
function doLogin()
{
var account = $('#account').val();
var password = $('#password').val();
if($.trim(account)=='' || $.trim(password)=='')
{
return;
}
showProcess('正在登录请稍后......');
$.post("<%=headerBasePath%>/system/system_login.action", {account:account,password:password},
function(data){
hideProcess();
if(data == 403)
{
showETip("账号或者密码错误");
return ;
}
doHideDialog('LoginDialog');
$("#loginButton").text("系统管理员");
$("#loginButton").removeAttr("onclick");
});
}
</script> </script>
@ -41,53 +68,76 @@
<!-- 头部 --> <!-- 头部 -->
<div id="_main_header_banner" class="header"> <div id="_main_header_banner" class="header">
<div id="_main_header_cnt" class="header-cnt"> <div id="_main_header_cnt" class="header-cnt">
<div class="logo" style="left: -200px;"> </div> <div class="logo" style="left: -200px;">
<!-- 头像 -->
<div id="_main_face" data-no-selection="" class="header-right" style="cursor: pointer;" onclick="showUserMenu();">
<span class="user-info"> <span
class="user-avatar" style="width: 80px;"> <img
src="<%=headerBasePath %>/resource/img/icon.png"><i
class="ui-arr"></i> </span> </span>
</div> </div>
<!-- 头像下方的菜单 -->
<div id="_main_face_menu" style="display:none;" class="ui-pop ui-pop-user" >
<div class="ui-pop-head">
<span id="_main_nick_name" class="user-nick" style="text-align: center;font-weight: bold;color: #555168;font-size: 18px;">管理员</span>
<span class="user-nick" style="line-height: 10px;text-align: center;font-weight: bold;color: #3B20BB;font-size: 12px;">admin</span>
</div>
<ul class="ui-menu"> <div class="btn-group" style="float: right; margin-top: 50px;">
<a type="button" class="btn btn-primary"
onclick="doShowDialog('aboutDialog')">关于</a>
<li>
<a id="_main_logout" href="javascript:doShowDialog('aboutDialog')"><i class="icon-fedbk"></i>关于</a>
</li>
</ul>
<i class="ui-arr"></i>
<i class="ui-arr ui-tarr"></i>
</div> </div>
</div> </div>
</div> </div>
<!--web的导航在左侧--> <!--web的导航在左侧-->
</div> </div>
<div class="panel panel-primary gdialog" id="aboutDialog" style="display: none;width: 400px;position: absolute;">
<div class="panel-heading">关于 <div class="panel panel-primary gdialog" id="aboutDialog"
<a class="close" onclick="doHideDialog('aboutDialog')">&times;</a> style="display: none; width: 400px; position: absolute;">
</div> <div class="panel-heading">
<div class="panel-body"> 关于
<ul class="list-group"> <a class="close" onclick="doHideDialog('aboutDialog')">&times;</a>
<li class="list-group-item">CIM即时通讯后台管理系统</li> </div>
<li class="list-group-item">Email:3979434@qq.com</li> <div class="panel-body" style="padding: 0px;">
<li class="list-group-item">QQ:3979434</li> <div style="text-align: center;background: #5FA0D3;height: 150px;">
</ul> <img src="<%=headerBasePath%>/resource/img/icon.png" style="margin-top: 35px;height: 80px;height: 80px;"/>
</div> </div>
<ul class="list-group">
<li class="list-group-item">
CIM即时通讯后台管理系统
</li>
<li class="list-group-item">
Email:3979434@qq.com
</li>
<li class="list-group-item">
QQ:3979434
</li>
</ul>
</div>
</div>
<div class="panel panel-primary gdialog" id="LoginDialog"
style="display: none; width: 300px; position: absolute; height: 395px;">
<div class="panel-heading">
系统管理员登录
<a class="close" onclick="doHideDialog('LoginDialog')">&times;</a>
</div>
<div style="text-align: center; background: #5FA0D3; height: 100px;">
</div>
<div class="panel-body">
<div class="form-group" style="margin-top: 20px;">
<label style="width: 50px;">
<font color="red">*</font>账号:
</label>
<input type="text" class="form-control" id="account" maxlength="15"
style="display: inline; width: 200px; height: 50px;" />
</div>
<div class="form-group" style="margin-top: 20px;">
<label style="width: 50px;">
<font color="red">*</font>密码:
</label>
<input type="password" class="form-control" id="password"
maxlength="32" style="display: inline; width: 200px; height: 50px;" />
</div>
</div>
<div class="panel-footer" style="text-align: center;">
<a type="button" class="btn btn-success btn-lg" onclick="doLogin()"
style="width: 200px;"> 登录</a>
</div>
</div> </div>
<div id="global_mask"
<div id="global_mask" style="display: none; position: absolute; top: 0px; left: 0px; z-index: 998; background-color: rgb(190, 209, 216); opacity: 0.5; width: 100%; height: 100%; overflow: hidden; background-position: initial initial; background-repeat: initial initial;"></div> style="display: none; position: absolute; top: 0px; left: 0px; z-index: 998; background-color: rgb(190, 209, 216); opacity: 0.5; width: 100%; height: 100%; overflow: hidden; background-position: initial initial; background-repeat: initial initial;"></div>

View File

@ -1,39 +1,5 @@
<%@ page language="java" pageEncoding="utf-8"%> <%@ page language="java" pageEncoding="utf-8"%>
<% <%
String path = request.getContextPath(); response.sendRedirect("admin/session_list.action");
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%> %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>CIM管理系统</title>
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/webbase.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/main-layout.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/base-ui.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/bootstrap/css/bootstrap.min.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/dialog.css" />
<script type="text/javascript" src="<%=basePath%>/resource/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script>
</head>
<body class="web-app ui-selectable">
<br />&lt;<br /><%@include file="header.jsp"%>
<%@include file="nav.jsp"%>
<div id="mainWrapper" style="padding-top: 25px;" >
</div>
<script>
$('#indexMenu').addClass('current');
</script>
</body>
</html>

View File

@ -1,20 +1,27 @@
<% <%
String navBasePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ request.getContextPath(); String navBasePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
%> %>
<%@ page language="java" pageEncoding="UTF-8"%> <%@ page language="java" pageEncoding="UTF-8"%>
<div id="_main_nav" class="ui-vnav"> <div id="_main_nav" class="ui-vnav">
<ul class="ui-nav-inner"> <ul class="ui-nav-inner">
<li class="ui-bar"> <li style="height: 50px; text-align: center; margin-top: 10px;">
<b class="ui-bd"></b> <div class="btn-group" style="margin-top: 5px;">
<a type="button" class="btn btn-danger" target="_blank"
href="javascript:openWebclient();">CIM for
Web(测试版)</a>
</div>
</li> </li>
<li class="ui-item" id="sessionMenu"> <li style="border-bottom: 1px solid #D1D6DA;"></li>
<a href="<%=navBasePath %>/admin/session_list.action"> <li class="ui-item" id="sessionMenu">
<span class="ui-text">在线用户</span> <i class="ui-bg nav-recycle"></i> </a> <a href="<%=navBasePath%>/admin/session_list.action"> <span
</li> class="ui-text">在线用户</span> <i class="ui-bg nav-recycle"></i> </a>
</li>
</ul> </ul>
<!-- 阴影 -->
<b class="ui-shd"></b>
</div> </div>

View File

@ -1,6 +1,5 @@
<%@ page language="java" pageEncoding="utf-8"%> <%@ page language="java" pageEncoding="utf-8"%>
<%@ page import="java.util.Collection"%> <%@ page import="java.util.Collection"%>
<%@ page import="com.farsunset.ichat.common.util.StringUtil"%>
<%@ page import="com.farsunset.cim.nio.session.CIMSession"%> <%@ page import="com.farsunset.cim.nio.session.CIMSession"%>
<% <%
String path = request.getContextPath(); String path = request.getContextPath();
@ -27,33 +26,18 @@
<script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script> <script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script>
<script> <script>
function doOffLine(account)
{
var setting = {hint:"确定让这个用户强制下线吗?",
onConfirm:function(){
$.post("<%=basePath%>/admin/session_offline.action", {account:account},
function(data){
showSTip("下线成功");
$('#'+account).fadeOut().fadeIn().fadeOut();
doHideConfirm();
});
}};
doShowConfirm(setting);
}
function showMessageDialog(account) function showMessageDialog(account)
{ {
doShowDialog("messageDialog"); doShowDialog("messageDialog");
$('#account').val(account); $('#Saccount').val(account);
} }
function doSendMessage() function doSendMessage()
{ {
var message = $('#message').val(); var message = $('#message').val();
var account = $('#account').val(); var account = $('#Saccount').val();
if($.trim(message)=='') if($.trim(message)=='')
{ {
return; return;
@ -69,6 +53,20 @@
}); });
} }
function onImageError(obj)
{
obj.src="<%=basePath%>/webclient/images/icon_head_default.png";
}
function openWebclient(){
var height = $(document).height();
var width = $(document).width();
window.open ("<%=basePath%>/console/webclient/main.jsp", "","height="+height+", width="+width+", top=0, left=0, toolbar=no,menubar=no, scrollbars=no, resizable=no,location=no, status=no");
}
</script> </script>
</head> </head>
<body class="web-app ui-selectable"> <body class="web-app ui-selectable">
@ -79,24 +77,28 @@
<%@include file="../nav.jsp"%> <%@include file="../nav.jsp"%>
<div id="mainWrapper"> <div id="mainWrapper">
<div class="panel panel-default">
<div class="panel-heading"> <div class="lay-main-toolbar">
在线用户
</div> </div>
<div class="panel-body" style="padding: 5px;">
<div>
<form action="<%=basePath%>/admin/user_manage.action" method="post" <form action="<%=basePath%>/admin/user_manage.action" method="post"
id="searchForm" style="padding: 0px;"> id="searchForm" style="padding: 0px;">
<input type="hidden" name="currentPage" id="currentPage" /> <input type="hidden" name="currentPage" id="currentPage" />
<table style="margin: 5px;width: 100%" class="utable"> <table style="width: 100%" class="utable">
<thead> <thead>
<tr class="tableHeader"> <tr class="tableHeader">
<th width="4%">头像</th>
<th width="15%">账号</th> <th width="15%">账号</th>
<th width="15%">终端来源</th> <th width="10%">终端</th>
<th width="15%">终端ID</th> <th width="10%">设备型号</th>
<th width="15%">终端型号</th> <th width="10%">在线时长</th>
<th width="15%">在线时长</th> <th width="28%">位置</th>
<th width="10%">操作</th> <th width="12%">操作</th>
</tr> </tr>
</thead> </thead>
@ -105,39 +107,41 @@
<% <%
for(CIMSession ios:sessionList) for(CIMSession ios:sessionList)
{ {
if(ios.getAccount()!=null)
{
%> %>
<tr id="<%=ios.getAccount()%>"> <tr id="<%=ios.getAccount() %>" style=" height: 50px;">
<td>
<img width="40px" height="40px" onerror='onImageError(this)' src="http://cim.oss-cn-hangzhou.aliyuncs.com/UI_<%=ios.getAccount() %>"/>
</td>
<td> <td>
<%=ios.getAccount() %> <%=ios.getAccount() %>
</td> </td>
<td> <td>
<%=ios.getChannel() %> <%=ios.getChannel()%>
</td> </td>
<td> <td>
<%=ios.getDeviceId() %> <%=ios.getDeviceModel()==null?"":ios.getDeviceModel()%>
</td>
<td>
<%=ios.getDeviceModel() %>
</td> </td>
<td> <td>
<%=(System.currentTimeMillis()-ios.getBindTime())/1000 %>秒 <%=(System.currentTimeMillis()-ios.getBindTime())/1000 %>秒
</td> </td>
<td>
<%=ios.getAttribute("location")==null?"":ios.getAttribute("location") %>
</td>
<td> <td>
<div class="btn-group btn-group-xs"> <div class="btn-group btn-group-xs">
<button type="button" class="btn btn-primary" style="padding: 5px;" onclick="showMessageDialog('<%=ios.getAccount() %>')">发送消息</button> <button type="button" class="btn btn-primary" style="padding: 5px;"
<button type="button" class="btn btn-danger" style="padding: 5px;" onclick="doOffLine('<%=ios.getAccount() %>')">强制下线</button> onclick="showMessageDialog('<%=ios.getAccount() %>')">发送消息</button>
</div> </div>
</td> </td>
</tr> </tr>
<%} %> <%}} %>
</tbody> </tbody>
<tfoot>
</tfoot>
</table> </table>
</form> </form>
@ -153,23 +157,30 @@
<form role="form"> <form role="form">
<div class="form-groupBuy"> <div class="form-groupBuy">
<label for="Amobile"> <label for="Amobile">
接收账号: 接收账号:
</label> </label>
<input type="text" class="form-control" id="account" name="account" <input type="text" class="form-control" id="Saccount" name="account"
style=" width: 100%;font-size: 20px;font-weight: bold;" disabled="disabled" /> style=" width: 100%;font-size: 20px;font-weight: bold;" disabled="disabled" />
</div> </div>
<div class="form-groupBuy" style="margin-top: 20px;"> <div class="form-groupBuy" style="margin-top: 20px;">
<label for="exampleInputFile" style="padding-left: 7px;">消 容:</label> <label for="exampleInputFile">消息内容:</label>
<textarea rows="10" style="width: 100%;height: 120px;" id="message" name="message" class="form-control"></textarea> <textarea rows="10" style="width: 100%;height: 120px;" id="message" name="message" class="form-control"></textarea>
</div> </div>
<div class="form-groupBuy" style="margin-top: 20px;">
<center>
<button type="button" style="width: 150px;" class="btn btn-success btn-lg" onclick="doSendMessage()">发 送</button>
</center>
</div>
</form> </form>
</div> </div>
<div class="panel-footer" style="padding:5px 10px;text-align: center;">
<a type="button" class="btn btn-success btn-lg" onclick="doSendMessage()" style="width: 200px;"> 发送</a>
</div>
</div>
<div class="panel panel-primary gdialog" id="scanDownloadDialog" style="display: none;width: 300px;position: absolute;z-index: 1001;">
<div class="panel-heading">二维码下载
<a class="close" onclick="doHideDialog('scanDownloadDialog'),$('#scanDownloadDialog').css('z-index',1000);">&times;</a>
</div>
<div class="panel-body">
<img src = "<%=basePath%>/resource/img/scan_download.png"/>
</div>
</div> </div>
<script> <script>
@ -177,4 +188,4 @@
</script> </script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="0" height="0"
backgroundColor="#FEFEFE"
creationComplete="init(event)"
xmlns:mx="library://ns.adobe.com/flex/mx"
>
<fx:Script>
<![CDATA[
import com.farsunset.webcim.bean.Message;
import com.farsunset.webcim.bean.ReplyBody;
import mx.events.FlexEvent;
private var CIM_HOST:String = "127.0.0.1";
private var CIM_PORT:String = "23456";
private var socket:Socket;
private var heartbeat_timer:Timer=new Timer(180 * 1000);;
var froceOffline :Boolean = false;
protected function init(event:FlexEvent):void
{
ExternalInterface.call("bridgeCreationComplete");
ExternalInterface.addCallback("connect",connect);
ExternalInterface.addCallback("setAccount",setAccount);
ExternalInterface.addCallback("getOfflineMessage",getOfflineMessage);
ExternalInterface.addCallback("logout",logout);
heartbeat_timer.addEventListener(TimerEvent.TIMER,doSendHeartbeat);
}
public function connect(host:String):void
{
CIM_HOST = host;
var policyfile:String="xmlsocket://"+CIM_HOST+":"+CIM_PORT;
Security.loadPolicyFile(policyfile);
socket=new Socket();
socket.addEventListener(Event.CONNECT,sessionCreated);//监听是否连接上服务器
socket.addEventListener(Event.CLOSE,sessionClosed);//监听套接字连接是否关闭
socket.addEventListener(IOErrorEvent.IO_ERROR,exceptionCaught);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorFun);
//监听服务器新信息
socket.addEventListener(ProgressEvent.SOCKET_DATA,messageReceived);
socket.connect(CIM_HOST,parseInt(CIM_PORT));//连接服务器
}
public function setAccount(account:String,deviceId:String):void
{
var xml:String="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<sent>";
xml+="<key>client_bind</key>";
xml+="<data>";
xml+="<account>"+account+"</account>";
xml+="<deviceId>"+deviceId+"</deviceId>";
xml+="<channel>web</channel>";
xml+="<device>browser</device>";
xml+="</data>";
xml+="</sent>";
send(xml);
}
public function getOfflineMessage(account:String):void
{
var xml:String="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<sent>";
xml+="<key>client_get_offline_message</key>";
xml+="<data>";
xml+="<account>"+account+"</account>";
xml+="</data>";
xml+="</sent>";
send(xml);
}
public function logout():void
{
socket.close();
}
private function sessionCreated(event:Event):void
{
ExternalInterface.call("sessionCreated");
heartbeat_timer.start();
froceOffline = false;
}
private function doSendHeartbeat(e:TimerEvent):void
{
var xml:String="<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
xml+="<sent>";
xml+="<key>client_heartbeat</key>";
xml+="</sent>";
send(xml);
}
private function sessionClosed(event:Event):void
{
ExternalInterface.call("sessionClosed");
if(!froceOffline)
{
connect(CIM_HOST);
}
//heartbeat_timer.stop();
}
private function exceptionCaught(event:Event):void{
//Alert.show("exceptionCaught","提示");
}
private function securityErrorFun(event:Event):void{
//Alert.show("securityErrorFun"+event.toString(),"提示");
}
/**接受服务器信息*/
internal function messageReceived(event:ProgressEvent):void
{
var msg:String="";
//循环读取数据
while(socket.bytesAvailable)
{
msg+=socket.readUTFBytes(socket.bytesAvailable);
}
var index:int = msg.indexOf("\b");
if(msg.indexOf("\b")>=0)
{
msg = msg.substring(0,index);
}
var xml:XML=XML(msg);
var data:Object = xml as Object;
if(xml.name()=="reply"){
ExternalInterface.call("onReplyReceived",ReplyBody.mappingToJSON(xml));
}
if(xml.name()=="message"){
if(xml["type"]=="999")
{
froceOffline = true;
}
ExternalInterface.call("onMessageReceived",Message.mappingToJSON(xml),xml["content"].toString());
}
}
/**发送数据到服务器*/
internal function send(msg:String):void
{
//新建一个ByteArray来存放数据
socket.writeUTFBytes(msg+"\b");
//调用flush方法发送信息
socket.flush();
}
]]>
</fx:Script>
</s:Application>

View File

@ -0,0 +1,39 @@
<%@ page language="java" pageEncoding="utf-8"%>
<script type="text/javascript">
function doLogin()
{
ACCOUNT = $('#account').val();
if($.trim(ACCOUNT)=='' )
{
return;
}
showProcess('正在接入请稍后......');
document.getElementById("CIMBridge").connect(CIM_HOST);
}
</script>
<div class="panel panel-primary gdialog" id="LoginDialog"
style="display: none; width: 300px; position: absolute;">
<div class="panel-heading">
登录
</div>
<div style="text-align: center;background: #5FA0D3;height: 150px;">
<img src="<%=basePath%>/resource/img/icon.png" style="margin-top: 35px;height: 80px;height: 80px;"/>
</div>
<div class="panel-body">
<div class="alert alert-info">
登录之前请在 cim.js里面设置当前服务器的IP地址
</div>
<div class="form-group" style="margin-top: 20px;">
<label style="width: 50px;">
<font color="red">*</font>账号:
</label>
<input type="text" class="form-control" id="account"
maxlength="15" style="display: inline; width: 200px;height: 50px;" />
</div>
</div>
<div class="panel-footer" style="text-align: center;">
<a type="button" class="btn btn-success btn-lg" onclick="doLogin()" style="width: 200px;"> 登录</a>
</div>
</div>

View File

@ -0,0 +1,77 @@
package com.farsunset.webcim.bean
{
import com.adobe.serialization.json.JSON;
public class Message
{
/**
*
*/
public var mid:String;
/**
*
*/
public var type:String;
/**
*
*/
public var title:String;
/**
* type content format text,json ,xml数据格式
*/
public var content:String = "";
/**
*
*/
public var sender:String;
/**
*
*/
public var receiver:String;
/**
* url
*/
public var file:String;
/**
*
*/
public var fileType:String;
/**
* content
*/
public var format:String = "txt";
public var timestamp:Number;
public static function mappingToJSON(xml:XML):Object
{
var message:Message = new Message();
message.mid = xml["mid"];
message.type = xml["type"];
message.title = xml["title"];
message.sender = xml["sender"];
message.receiver = xml["receiver"];
message.file = xml["file"];
message.fileType = xml["fileType"];
message.timestamp = xml["timestamp"];
message.content = "";
return com.adobe.serialization.json.JSON.encode(message).toString();
}
}
}

View File

@ -0,0 +1,18 @@
<%@ page language="java" pageEncoding="utf-8"%>
<div class="panel panel-primary" id="MessageDialog"
style="display: none; width: 700px; position: absolute;min-height: 500px;box-shadow: 0 0 10px -2px #0B203A;">
<div class="panel-heading" style="height: 80px;background: #428bca;line-height: 80px;padding: 0 10px;">
消息列表
<span id="current_account" style="color: white;float: right;font-weight: bold;"></span>
</div>
<div class="panel-body" id="messageList">
</div>
</div>

View File

@ -0,0 +1,28 @@
package com.farsunset.webcim.bean
{
import com.adobe.serialization.json.JSON;
public class ReplyBody
{
public var key:String;
public var code:String;
public var message:String;
public var data:Object;
public var timestamp:Number;
public static function mappingToJSON(xml:XML):Object
{
var body:ReplyBody = new ReplyBody();
body.key = xml["key"];
body.code = xml["code"];
body.timestamp = xml["timestamp"];
return com.adobe.serialization.json.JSON.encode(body);
}
}
}

View File

@ -0,0 +1,3 @@
var CIM_HOST="127.0.0.1";//修改为服务器的真实IP
var ACCOUNT;

View File

@ -0,0 +1,138 @@
<%@ page language="java" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path;
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta charset="utf-8"/>
<title>ICHAT for web(beta) </title>
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/bootstrap/css/bootstrap.min.css" />
<link charset="utf-8" rel="stylesheet" href="<%=basePath%>/resource/css/dialog.css" />
<script type="text/javascript" src="<%=basePath%>/resource/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/resource/js/framework.js"></script>
<script type="text/javascript" src="cim.js"></script>
</head>
<script type="text/javascript">
/**CIMBridge.swf提供的接口,源码是CIMBridge.mxml , ReplyBody.as ,Message.as 用flahs builder 工具 导入开发。
connect(host);连接服务端 host:服务器IP
setAccount(account) 绑定客户端账号到服务端 account账号
logout() 退出连接
getOfflineMessage(account) 拉取离线消息,需要服务端实现 请求key client_get_offline_message
**/
/** 当socket连接成功回调 **/
function sessionCreated()
{
document.getElementById("CIMBridge").setAccount(ACCOUNT,ACCOUNT);
}
/** 当socket断开是回调 **/
function sessionClosed()
{
}
/** 当收到请求回复时候回调 **/
function onReplyReceived(data)
{
var json = JSON.parse(data)
if(json.key=='client_bind' && json.code==200)
{
hideProcess();
doHideDialog('LoginDialog');
doShowDialog('MessageDialog');
$("#current_account").text("当前账号:"+ACCOUNT);
}
}
/** 当收到消息时候回调 **/
function onMessageReceived(data,content)
{
var message = JSON.parse(data);
if(message.type=='2')
{
message.content = content;
$("#messageList").append("<div class='alert alert-info' >"+content+"</div>");
}
}
/** 当flex socket 组件(CIMBridge.swf) 加载完成是回调 **/
function bridgeCreationComplete(){
hideProcess();
}
$(document).ready(function(){
showProcess("加载中......");
doShowDialog('LoginDialog');
});
</script>
<script language="Javascript">
document.oncontextmenu = function (){
return false;
}
window.onload=function()
{
window.onkeydown=function(e)
{
if(e.which)
{
if(e.which==116)
{
return false;
}
}
else if(event.keyCode)
{
if(event.keyCode==116)
{
return false;
}
}
}
}
</script>
<body style="background-color: rgb(190, 209, 216);">
<object type="application/x-shockwave-flash" data="CIMBridge.swf" id="CIMBridge" width="0" height="0">
<param name="quality" value="low"/>
<param name="allowScriptAccess" value="always"/>
<param name="wmode" value="transparent"/>
<param name="movie" value="CIMBridge.swf"/>
</object>
<div id="global_mask" style="display: none; position: absolute; top: 0px; left: 0px; z-index: 998; background-color: rgb(190, 209, 216); opacity: 0.5; width: 100%; height: 100%; overflow: hidden; background-position: initial initial; background-repeat: initial initial;"></div>
<%@include file="LoginDialog.jsp"%>
<%@include file="MessageDialog.jsp"%>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@

/* golabe */ /* golabe */
@ -234,10 +234,10 @@
.icon_success{ .icon_success{
background: url(../img/icon_success.png) no-repeat; background: url(../img/icon_success.png) no-repeat;
width: 32px; width: 38px;
height: 32px; height: 38px;
left:10px; left:10px;
top:9px; top:6px;
position: absolute; position: absolute;
} }
.icon_hint{ .icon_hint{
@ -273,4 +273,28 @@
top:15px; top:15px;
position: absolute; position: absolute;
} }
.form-group label {
width: 60px;
text-align: right;
}
.lay-main-toolbar {
height: 60px;
border-radius: 0px;
background-color: #f5f6f9;
border-bottom: 1px solid #B5BBBF;
border-right: 1px solid #B5BBBF;
position: relative;
width: 100%;
padding: 7px;
}
.btn i {
font-size: 24px;
margin-right: 4px;
font-style: normal;
vertical-align: text-top;
line-height: 18px;
}

View File

@ -26,4 +26,47 @@
.gdialog .close:hover, .gdialog .close:focus{ .gdialog .close:hover, .gdialog .close:focus{
opacity: .93; opacity: .93;
filter: alpha(opacity=93); filter: alpha(opacity=93);
} }
.gdialog .panel-heading{
cursor: move;
}
.tip_process {
zoom: 1;
color:#394A5E;
text-align: center;
line-height: 50px;
height: 50px;
-webkit-box-shadow: 0 0 20px -2px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 0 20px -2px rgba(0,0,0,0.5);
-ms-box-shadow: 0 0 20px -2px rgba(0,0,0,0.5);
box-shadow: 0 0 20px -2px rgba(0, 0, 0, 0.5);
border: 1px solid #6D7A89;
z-index: 9999;
background-color: white;
min-width: 300px;
position: absolute;
z-index:9999;;
font-size: 16px;
font-weight: bold;
}
.icon_loading_mid{
background: url(../img/icon_loading_mid.gif) no-repeat;
width: 31px;
height: 31px;
left:10px;
top:10px;
position: absolute;
}
.icon_loading_small{
background: url(../img/icon_loading_small.gif) no-repeat;
width: 22px;
height: 22px;
left:10px;
top:15px;
position: absolute;
}

View File

@ -3,13 +3,14 @@
/* left nav */ /* left nav */
.ui-vnav { .ui-vnav {
position: fixed; position: fixed;
top: 50px; top: 100px;
left: 0; left: 0;
width: 170px; width: 180px;
min-height: 560px; min-height: 560px;
height: 960px; height: 960px;
background: #d8dce5; background: #eaedf4;
_overflow: hidden; _overflow: hidden;
border-right: 1px solid #d8dce5;
} }
@ -29,41 +30,41 @@ border-bottom: 1px solid #eaeaea;
} }
.ui-vnav .ui-item { .ui-vnav .ui-item {
height: 36px; height: 45px;
margin-bottom: 3px; line-height: 45px;
line-height: 36px;
padding: 0 10px; padding: 0 10px;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
border-bottom: 1px #eaedf4 solid;
border-top: 1px #eaedf4 solid;
} }
.ui-vnav .ui-item:hover { .ui-vnav .ui-item:hover {
background-color: #C8CCD5;
color: white; color: white;
background-color: #e0e4ed;
border-bottom: 1px #d8dce5 solid;
border-top: 1px #d8dce5 solid;
} }
.ui-vnav .current,.ui-vnav .current:hover { .ui-vnav .current,.ui-vnav .current:hover {
/*border-left: solid 3px #14A7D4; background-color: #ced4e0;
background-color: #7b7b7b;*/ border-bottom: 1px #c8ccd5 solid;
background:url(../img/nav_selected_bg.png) no-repeat ; border-top: 1px #c8ccd5 solid;
color: white; border-left: 5px #5FA0D3 solid;
} }
.ui-vnav .ui-item a { .ui-vnav .ui-item a {
position: relative; position: relative;
display: block; display: block;
height: 36px; height: 45px;
line-height: 36px; line-height: 45px;
font-family: "\5FAE\8F6F\96C5\9ED1","\534E\6587\7EC6\9ED1"; font-family: "\5FAE\8F6F\96C5\9ED1","\534E\6587\7EC6\9ED1";
font-size: 18px; font-size: 18px;
color: #666; color: #666;
text-decoration:none; text-decoration:none;
} }
.ui-vnav .ui-bg, .ui-vnav .current a, .ui-vnav a:active {
background-position: -999px -999px;
background-repeat: no-repeat;
color: white;
}
.ui-vnav .ui-shd { .ui-vnav .ui-shd {
position: absolute; position: absolute;
right: 0; right: 0;

View File

@ -6,8 +6,6 @@
.utable { .utable {
border-collapse: collapse; border-collapse: collapse;
border-spacing: 0; border-spacing: 0;
border-top: solid 1px #D4D4D4;
border-left: solid 1px #D4D4D4;
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
background: #ffffff; background: #ffffff;
@ -15,8 +13,10 @@
margin-right: 10px; margin-right: 10px;
} }
.utable tr th { .utable tr th {
background-color: #d8dce5; background-color: #F3F3F3;
border: solid 1px #D4D4D4; border-right: solid 1px #D4D4D4;
border-left: solid 1px #D4D4D4;
border-bottom: solid 1px #D4D4D4;
color: #463E5E; color: #463E5E;
line-height: 40px; line-height: 40px;
font-size: 14px; font-size: 14px;
@ -26,7 +26,7 @@
.utable tr:hover { .utable tr:hover {
background-color: #F1F1F1; background-color: #f5f6f9;
} }
@ -40,7 +40,6 @@ height:35px;
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
overflow: hidden; overflow: hidden;
white-space: nowrap;
} }

View File

@ -23,7 +23,7 @@ body .hide,.app-web .hide,.app-qplus .hide,.app-appbox .hide{display:none}
body .ellipsis{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;_width:100%;word-wrap:normal} body .ellipsis{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;_width:100%;word-wrap:normal}
body{color:#666;background:#F1F1F1} body{color:#666;background:#F1F1F1}
a{color:#1D719E} a{color:#1D719E}
#mainWrapper{ width: auto; margin-left: 170px; min-height: 600px;padding-top: 65px;padding-left: 10px;;padding-bottom: 50px; padding-right: 10px;} #mainWrapper{ width: auto; margin-left: 180px; min-height: 600px;padding-top:100px; 10px;;padding-bottom: 50px; }
.mb{margin-bottom:15px} .mb{margin-bottom:15px}
.float_right{float:right} .float_right{float:right}
.text_right{text-align:right} .text_right{text-align:right}
@ -65,10 +65,12 @@ a:focus {
/* header */ /* header */
.header{ .header{
position: relative; position: relative;
height:50px; height:100px;
margin:0 auto; margin:0 auto;
background:url(../img/top-bg.png) repeat-x left top; width:100%;
box-shadow: 0 1px 5px #ccc; -webkit-box-shadow: 0 0 10px -2px #0B203A;
box-shadow: 0 0 10px -2px #0B203A;
background: #0B203A;
z-index: 10; z-index: 10;
} }
.app-appbox .header{ .app-appbox .header{
@ -551,14 +553,13 @@ a:focus {
background:#d8d638; background:#d8d638;
} }
/* ui-pop */ /* ui-pop */
.ui-pop{ .ui-pop {
position:absolute; position: absolute;
border:1px solid #CEC754; border: 1px solid #CEC754;
border-radius:3px; background: #FFFAAB;
background:#FFFAAB; box-shadow: 0px 1px 2px #CCC;
box-shadow:1px 1px 2px #CCC; color: #9D9A69;
color:#9D9A69; font-size: 12px;
font-size:12px;
} }
.ui-pop-text{ .ui-pop-text{
padding:13px 15px 13px; padding:13px 15px 13px;
@ -1296,16 +1297,15 @@ a:focus {
background:#fff url(../img/avatar-hover-bg.png?t=1) no-repeat left top; background:#fff url(../img/avatar-hover-bg.png?t=1) no-repeat left top;
} }
/* 用户浮层 */ /* 用户浮层 */
.ui-pop-user{ .ui-pop-user {
width:168px; width: 168px;
right:0; right: 10px;
top:50px; top: 45px;
background:#FFF; background: #FFF;
border-color:#abb0bb; border-color: #c8ccd5;
border-top:none; border-radius: 0;
border-radius:0; color: #666;
color:#666; z-index: 10;
z-index:10;
} }
.ui-pop-user .ui-pop-head{ .ui-pop-user .ui-pop-head{
padding:0 15px; padding:0 15px;
@ -1465,4 +1465,5 @@ a:focus {
.app-photo .wrapper{margin-top:-1px;} .app-photo .wrapper{margin-top:-1px;}
/* photo */ /* photo */
/* vnav *//* |xGv00|ca7570ffdcf2d601f22a688ce458168d */ /* vnav *//* |xGv00|ca7570ffdcf2d601f22a688ce458168d */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -117,9 +117,49 @@ function prepareShowDialog(dialog)
var w = $(document).width(); var w = $(document).width();
var mheight = dialog.height(); var mheight = dialog.height();
var mwidth = dialog.width(); var mwidth = dialog.width();
dialog.css({top:(h-mheight)/3,left:(w-mwidth)/2}); dialog.css({top:150,left:(w-mwidth)/2});
$('#global_mask').css('height',h); $('#global_mask').css('height',h);
$('#global_mask').fadeIn(); $('#global_mask').fadeIn();
$("body").attr("unselectable","no");
$("body").attr("onselectstart","return false;");
dialog.find(".panel-heading").mousedown(function(e)
{
var offset = $(this).offset();
var x = e.pageX - offset.left;
var y = e.pageY - offset.top;
$(document).bind("mousemove",function(ev)
{
var _x = ev.pageX - x;
var _y = ev.pageY - y;
if(_x<=0)
{
_x=0;
}
if(_y <=0 )
{
_y=0;
}
if(_x >= (w - mwidth))
{
_x=(w - mwidth);
}
if( _y >= (h - mheight))
{
_y = (h - mheight);
}
dialog.css({left:_x+"px",top:_y+"px"});
});
});
$(document).mouseup(function()
{
dialog.css("cursor","default");
$(this).unbind("mousemove");
})
} }
@ -128,7 +168,6 @@ function doShowDialog(dialogId,animate){
var dialog = $('#'+dialogId); var dialog = $('#'+dialogId);
prepareShowDialog(dialog); prepareShowDialog(dialog);
if(animate==undefined) if(animate==undefined)
{ {
/*$('#'+dialogId).fadeIn(); /*$('#'+dialogId).fadeIn();
@ -261,6 +300,6 @@ function gotoPage(number)
function getDateTime(t) { function getDateTime(t) {
//return new Date(parseInt(t)).toLocaleString().substr(0,17) //return new Date(parseInt(t)).toLocaleString().substr(0,17)
var tt=new Date(parseInt(t)).toLocaleString().replace(/年|月/g, "-").replace(/日/g, " ") //return new Date(parseInt(t)).pattern("yyyy-MM-dd HH:mm:ss");
return tt; return new Date(parseInt(t)).toLocaleString().replace(/年|月/g, "-").replace(/日/g, " ");
} }

View File

@ -7,7 +7,7 @@ import java.util.UUID;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.farsunset.cim.nio.constant.CIMConstant; import com.farsunset.cim.nio.constant.CIMConstant;
import com.farsunset.cim.nio.handle.CIMRequestHandler; import com.farsunset.cim.nio.handler.CIMRequestHandler;
import com.farsunset.cim.nio.mutual.Message; import com.farsunset.cim.nio.mutual.Message;
import com.farsunset.cim.nio.mutual.ReplyBody; import com.farsunset.cim.nio.mutual.ReplyBody;
import com.farsunset.cim.nio.mutual.SentBody; import com.farsunset.cim.nio.mutual.SentBody;

View File

@ -2,7 +2,7 @@
package com.farsunset.ichat.cim.handler; package com.farsunset.ichat.cim.handler;
import com.farsunset.cim.nio.constant.CIMConstant; import com.farsunset.cim.nio.constant.CIMConstant;
import com.farsunset.cim.nio.handle.CIMRequestHandler; import com.farsunset.cim.nio.handler.CIMRequestHandler;
import com.farsunset.cim.nio.mutual.ReplyBody; import com.farsunset.cim.nio.mutual.ReplyBody;
import com.farsunset.cim.nio.mutual.SentBody; import com.farsunset.cim.nio.mutual.SentBody;
import com.farsunset.cim.nio.session.CIMSession; import com.farsunset.cim.nio.session.CIMSession;

View File

@ -4,7 +4,7 @@ package com.farsunset.ichat.cim.handler;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.farsunset.cim.nio.constant.CIMConstant; import com.farsunset.cim.nio.constant.CIMConstant;
import com.farsunset.cim.nio.handle.CIMRequestHandler; import com.farsunset.cim.nio.handler.CIMRequestHandler;
import com.farsunset.cim.nio.mutual.ReplyBody; import com.farsunset.cim.nio.mutual.ReplyBody;
import com.farsunset.cim.nio.mutual.SentBody; import com.farsunset.cim.nio.mutual.SentBody;
import com.farsunset.cim.nio.session.CIMSession; import com.farsunset.cim.nio.session.CIMSession;

View File

@ -14,7 +14,7 @@
> >
<bean id="mainIoHandler" class="com.farsunset.cim.nio.handle.MainIOHandler" init-method="init" > <bean id="mainIoHandler" class="com.farsunset.cim.nio.handler.MainIOHandler" init-method="init" >
<property name="port" value="23456" /> <property name="port" value="23456" />
<property name="handlers"> <property name="handlers">
<map> <map>
@ -25,7 +25,7 @@
<bean class="com.farsunset.ichat.cim.handler.LogoutHandler" /> <bean class="com.farsunset.ichat.cim.handler.LogoutHandler" />
</entry> </entry>
<entry key="client_heartbeat"> <entry key="client_heartbeat">
<bean class="com.farsunset.cim.nio.handle.HeartbeatHandler"/> <bean class="com.farsunset.cim.nio.handler.HeartbeatHandler"/>
</entry> </entry>
<entry key="sessionClosedHander"> <entry key="sessionClosedHander">
<bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/> <bean class="com.farsunset.ichat.cim.handler.SessionClosedHandler"/>