工作之RF功能开发入门

公司现阶段使用的各个系统中有很多都是使用RF扫码枪进行业务操作,因此学会利用现有系统框架开发能在RF扫码枪上使用的业务功能非常有必要。

1 打开Telnet服务

使用Win+R快捷键打开命令窗口,输入以下内容(这里以jac_parts_wms系统中的RF为例,不同的系统输入的网址和端口号是不一样的)。
工作之RF功能开发入门_第1张图片
其中,telnet是协议名 “192.168.10.92”是IP地址,6666是服务端口(配置端口的文件是standardListener.properties)。点击“确定”按钮,进入到telnet登录界面:
工作之RF功能开发入门_第2张图片
输入用户名和密码,按键盘上的“↑”键或者“↓”键切换仓库,
就进入到了模拟RF扫码枪操作的主界面。
工作之RF功能开发入门_第3张图片
工作之RF功能开发入门_第4张图片
主界面上的各种功能就是我们要开发的功能。接着我们来讲解公司现有系统的RF功能的开发步骤:

2 RF功能开发步骤

2.1配置功能菜单

首先要在kangarooMenu.xml中的Menu标签中配置在telnet主界面上显示的功能菜单。
举例说明:


上述配置了一个器具签收的功能菜单,配置好之后,就会在telnet主界面上显示如下内容:
工作之RF功能开发入门_第5张图片

配置bean

我们编写的每一个shell文件都是java文件,由于使用了Spring框架对所有的java对象进行管理,因此要配置bean。公司现有系统都是在shellContext.xml中对RF操作的java类进行配置。
这里还是以器具签收为例:


    	
            
        
    	
            
        
    

上述代码中还使用构造函数的方式进行了bean的依赖注入操作,这里不再详述,需要依赖注入可以按上述代码的注入方式进行注入即可。

2.3 编写shell

要在对应的项目文件夹下编写一个名为XXXShell类的java文件。按照继承的父类的不同,目前遇到的shell文件有这么三种:

shell父类 作用
YzBaseShell 一般用于用户输入的code或者ID等
JacPageableBaseShell 用于批量展示业务数据,可以选择某条数据
Thorn4BaseShell 展示每一条业务数据,并可以输入数量等字段

2.3.1 XXXshell继承YzBaseShell

这里以jac_parts_wms系统中RF操作的器具签收功能为例:
签收界面:
工作之RF功能开发入门_第6张图片
代码如下:

package com.vtradex.wms.server.telnet.shell.view;

import java.io.IOException;
import java.util.Map;

import net.wimpi.telnetd.net.Connection;

import org.apache.commons.lang.StringUtils;

import com.vtradex.kangaroo.shell.BreakException;
import com.vtradex.kangaroo.shell.ContinueException;
import com.vtradex.kangaroo.shell.ShellFactory;
import com.vtradex.wms.server.model.base.BaseStatus;
import com.vtradex.wms.server.telnet.pick.WmsPickRFManager;
import com.vtradex.wms.server.telnet.shell.ShellExceptions;
import com.vtradex.wms.server.telnet.shell.YzBaseShell;
import com.yc.utils.common.MyUtils;
/**器具签收*/
public class SignScanPickContainerShell extends YzBaseShell{
	public static final String PAGE_ID = "signScanPickContainerShell";
	public static final String BOX_TAG = "BOX_TAG";
	public static final String ERROR = "";
	
	private final WmsPickRFManager pickRFManager;
	public SignScanPickContainerShell(WmsPickRFManager pickRFManager) {
		this.pickRFManager = pickRFManager;
	}
	@Override
	protected void mainProcess(Connection connection) throws BreakException,
			ContinueException, IOException, Exception {
		
		String messge = "成功";
		String boxTag = (String) this.getParentValue(BOX_TAG);
		if(boxTag==null){
			boxTag = this.getTextField("scan.boxTag");
			if (StringUtils.isEmpty (boxTag) || BaseStatus.NULLVALUE.equals(boxTag)) {
				this.setStatusMessage(ShellExceptions.ERROR_OVER);
			}
			boxTag = boxTag.trim();
			if(MyUtils.OVER.equals(boxTag)){
				forward(ShellFactory.getMainShell());
			}
			Map<String,String> result = pickRFManager.checkBoxTag(boxTag);
			if(!result.get(ERROR).isEmpty()){
				messge = result.get(ERROR);
				this.forward(SignScanPickContainerShell.PAGE_ID, messge);
			}else{
				messge = "选择序号";
				this.put(BOX_TAG, boxTag);
				this.forward(ViewScanPickContainerDetailShell.PAGE_ID, messge);
			}
		}
	}

}

代码讲解如下图:
工作之RF功能开发入门_第7张图片
对上图补充一点:boxTag = this.getTextField("scan.boxTag");代码中那个的scan.boxTag是自定义的,并且要对其国际化。国际化如下:
新建一个和XXXShell_zh.properties的文件,在该文件中编写需要国际化的字段。
RF功能开发中的国际化

2.3.2 XXXshell继承JacPageableBaseShell

该界面主要用于展示,有点类似于表格的概念。话不多说,直接上图:
工作之RF功能开发入门_第8张图片
代码如下:

package com.vtradex.wms.server.telnet.shell.view;

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

import com.vtradex.wms.server.telnet.shell.JacPageableBaseShell;

public class ViewScanPickContainerDetailShell extends JacPageableBaseShell{
	public static final String PAGE_ID = "viewScanPickContainerDetailShell";
	public static final String TASK_ID = "TASK_ID";
	public static final String ITEM_CODE = "ITEM_CODE";
	public static final String ITEM_NAME = "ITEM_NAME";
	public static final String MOVED_QUANTITY = "MOVED_QUANTITY";
	public static final String PRODUCT_LINE = "PRODUCT_LINE";

	@Override
	public String[] getTableHeader() {
		return new String[]{"序号","物料编码","物料名称","数量","产线"};
	}

	@Override
	public String getHql() {
		String hql = " SELECT task.id" +
				",task.moveDocDetail.item.code" +
				",task.moveDocDetail.item.name" +
				",task.movedQuantityBU" +
				",task.moveDocDetail.productionLine" +
				" FROM WmsTask task" +
				" WHERE task.signTime is null" +
				" /~BOXTAG: AND task.boxTag = {BOXTAG}~/";	
		return hql;
	}

	@Override
	public String getNextShell() {
		Object[] rowData = (Object[])get(ROW_DATA_KEY);
		String boxTag = (String) this.getParentValue(SignScanPickContainerShell.BOX_TAG);
		this.put(TASK_ID, rowData[0]);
		this.put(ITEM_CODE, rowData[1]);
		this.put(ITEM_NAME, rowData[2]);
		this.put(MOVED_QUANTITY, rowData[3]);
		this.put(PRODUCT_LINE, rowData[4]);
		this.put(SignScanPickContainerShell.BOX_TAG, boxTag);
		return SignScanPickContainerDetailShell.PAGE_ID;
	}

	@Override
	public String getUpShell() {
		return SignScanPickContainerShell.PAGE_ID;
	}

	@Override
	public Map<String, Object> getParams() {
		Map<String, Object> params = new HashMap<String, Object>();
		String boxTag = (String) this.getParentValue(SignScanPickContainerShell.BOX_TAG);
		params.put("BOXTAG", boxTag);
		return params;
	}

}

代码讲解如下:
工作之RF功能开发入门_第9张图片
工作之RF功能开发入门_第10张图片

2.3.3 XXXshell继承Thorn4BaseShell

工作之RF功能开发入门_第11张图片
代码如下:

package com.vtradex.wms.server.telnet.shell.view;

import java.io.IOException;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import net.wimpi.telnetd.net.Connection;

import com.vtradex.kangaroo.shell.BreakException;
import com.vtradex.kangaroo.shell.ContinueException;
import com.vtradex.kangaroo.shell.Thorn4BaseShell;
import com.vtradex.wms.server.telnet.pick.WmsPickRFManager;
import com.vtradex.wms.server.telnet.shell.ShellExceptions;
import com.yc.utils.common.JavaTools;
import com.yc.utils.common.MyUtils;

public class SignScanPickContainerDetailShell extends Thorn4BaseShell{
	public static final String PAGE_ID = "signScanPickContainerDetailShell";
	private final WmsPickRFManager pickRFManager;

	public static final String ERROR = "ERROR";
	
	public SignScanPickContainerDetailShell(WmsPickRFManager pickRFManager) {
		this.pickRFManager = pickRFManager;
	}

	@Override
	protected void mainProcess(Connection connection) throws BreakException,
			ContinueException, IOException, Exception {

		String messge = "";
		Long taskId = (Long)this.getParentValue(ViewScanPickContainerDetailShell.TASK_ID);
		String boxTag = (String) this.getParentValue(SignScanPickContainerShell.BOX_TAG);
		String itemCode = (String) this.getParentValue(ViewScanPickContainerDetailShell.ITEM_CODE);
		String itemName = (String) this.getParentValue(ViewScanPickContainerDetailShell.ITEM_NAME);
		String productLine = (String) this.getParentValue(ViewScanPickContainerDetailShell.PRODUCT_LINE);
		double quantity = (Double) this.getParentValue(ViewScanPickContainerDetailShell.MOVED_QUANTITY);
		
		output("物料编码",itemCode);
		output("物料名称",itemName);
		output("产线",productLine);
		output("数量",String.valueOf(quantity));
		
		String value = this.getTextField("task.signQty");
		Double signQuantityBU = 0D;
		if(StringUtils.isEmpty(value)){
			signQuantityBU = quantity;
		}else{
			if(MyUtils.OVER.equals(value)){
				messge = "选择序号";
				this.put(SignScanPickContainerShell.BOX_TAG, messge);
				this.forward(ViewScanPickContainerDetailShell.PAGE_ID,messge);
			}
			
			if(!JavaTools.isNumber(value)){
				messge = "失败!签收数量不合法!00返回上一级";
				this.setStatusMessage(messge);
			}
			signQuantityBU = JavaTools.stringToDouble(value);
			if(signQuantityBU<0 || signQuantityBU>quantity){
				messge = "失败!签收数量不合法!00返回上一级";
				this.setStatusMessage(messge);
			}
		}
		try {
			Map<String,String> results = pickRFManager.signScanPickContainerDetail(taskId,signQuantityBU);
			if(!StringUtils.isEmpty(results.get(ERROR))){
				messge = results.get(ERROR);
				this.put(SignScanPickContainerShell.BOX_TAG, messge);
				this.forward(ViewScanPickContainerDetailShell.PAGE_ID,messge);
			}
		} catch (Exception e) {
			e.printStackTrace();
			this.reset(e.getMessage());
		}
		
		//验证器具单明细是否全部签收 
		Map<String,String> results = pickRFManager.checkBoxTag(boxTag);
		if(!StringUtils.isEmpty(results.get(ERROR))){
			messge = "签收完成,继续扫码";
			this.forward(SignScanPickContainerShell.PAGE_ID,messge);
		}
		messge = "选择序号";
		this.put(SignScanPickContainerShell.BOX_TAG, boxTag);
		this.forward(ViewScanPickContainerDetailShell.PAGE_ID,messge);

	}
		
}

代码讲解如下:
工作之RF功能开发入门_第12张图片
工作之RF功能开发入门_第13张图片
RF功能开发的大致流程就是以上这些,关于RF开发的内容还有很多没有讲到,可自行查看源码分析学习。如有不正确的地方,请各位批评指正,不胜感激!!!

你可能感兴趣的:(我的工作)