平台默认提供的在线用户列表中没有记录用户登录的终端,因此要分别控制pc和mobile一个用户只能登录一次,需要自己记录用户登录的终端等信息
第一步:可以定义一个全局的map,在登录后把登录的用户名和终端作为key,登录产生的session做为value存储到map中
第二步:在登录前获取到当前登录的用户名和终端,判断map中是否有,如果有说明已经登录过了,可以抛出异常不让登录
第三步:当注销和session超时应该删除map中的信息,可以监听session失效实现

定义全局的map和监听session失效,可以在BusinessServer下创建servlet和listener实现,具体实现如下:
在\runtime\BusinessServer\WEB-INF下创建src
在src下创建servlet:/com/justep/user/OnLineMap.java,注意有包名目录/com/justep/user

package com.justep.user;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServlet;


public class OnLineMap extends HttpServlet {
	//定义一个mapping存在登录者的相关信息
	public static  Map<String, Object> OnLineMaps = new HashMap<String, Object>();
}

创建listener:/com/justep/user/SessionListener.java,注意有包名目录/com/justep/user

package com.justep.user;

import java.util.Map.Entry;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;


public class SessionListener implements HttpSessionListener {  
	public void sessionDestroyed(HttpSessionEvent event) {  
       //session失效时获取map中value为此session的信息,并且map中删除
		HttpSession session = event.getSession();  
        String user = "";
        for (Entry<String, Object> entry : OnLineMap.OnLineMaps.entrySet()) {       	
        	HttpSession userSession = (HttpSession) entry.getValue();      	
        	if(session.equals(userSession)){        		
        		user = entry.getKey();
        	}
          }
        
        OnLineMap.OnLineMaps.remove(user);
    }

	public void sessionCreated(HttpSessionEvent arg0) {
		// TODO 自动生成的方法存根		
	}
}


最终运行是执行的java编译的class文件,可以在studio中切换到java视图,然后把\runtime\BusinessServer导入
直接复制上面的java代码在WEB-INF/src上粘贴就可以生产对应的java类和对应的class文件

在\runtime\BusinessServer\WEB-INF\web.xml中配置servlet和listener
注意:servlet和listener的配置要放到平台默认配置的前面
如下,com.justep.x.loader.NativeLoaderListener这个配置就是平台默认的:

  <listener>
    <listener-class>com.justep.user.SessionListener</listener-class>
  </listener>
  <servlet>  
    <servlet-name>getOnLine</servlet-name>  
    <servlet-class>com.justep.user.OnLineMap</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>  
  <servlet-mapping>  
    <servlet-name>getOnLine</servlet-name>  
    <url-pattern>/getOnLine</url-pattern>  
  </servlet-mapping>
   
  <listener>
    <listener-class>com.justep.x.loader.NativeLoaderListener</listener-class>
  </listener>
  <listener>

登录后和登录前的操作可以在loginAction的执行前后事件中操作,通过扩展空间在/BIZ/SA_X/OPM/system/system.process.m的loginAction上添加事件
注意:事件默认生成的java的名字是System,需要自己修改一下名字,对应的procedure中配置的java的名字也需要修改,本案例用的是SystemTest

import java.util.Map;
import javax.servlet.http.HttpSession;
import com.justep.system.context.*;

import com.justep.user.*;

public class SystemTest {

	public static void systemProcessBeforeLoginAction() throws Exception {
		String user = ((String) ContextHelper.getActionContext().getParameter("name"));
		Map<Object, Object> options = (Map<Object, Object>) ContextHelper.getActionContext().getParameter("options");
		String deviceType = (String) options.get("DeviceType");
		String userDeviceType = user+":"+deviceType;
		//获取登录输入的name和设备类型,判断map中是否存在
		if (OnLineMap.OnLineMaps.containsKey(userDeviceType)) {
				throw new Exception("此用户已经在当前终端类型登录,请切换其他用户登录");

		}

	}

	public static void systemProcessAfterLoginAction() {
		String user = ((String) ContextHelper.getActionContext().getParameter("name"));// 获取登录输入的name
		// 获取设备类型
		Map<Object, Object> options = (Map<Object, Object>) ContextHelper.getActionContext().getParameter("options");
		String deviceType = (String) options.get("DeviceType");
		HttpSession session = ContextHelper.getSessionContext().getSession();//获取登录产生的session
		String userDeviceType = user+":"+deviceType;
		// 把name和设备类型拼接做为key,session做为value放到Map中
		OnLineMap.OnLineMaps.put(userDeviceType, session);
	}
}

用map存储的这个方案可用于非集群的环境,如果集群的环境要控制,把map修改为数据库表,把登录人员的信息存储的数据库表中操作