jbase虚拟M层的设计

对于只是自己产品内部使用的打印程序来说(比如打印收费单,打印结算单等),打印逻辑写在js,获取其他层都是没毛病的。但是对于类型检验报告这种打印来说,打印格式控制逻辑写在js层是百分百不行的。因为检验报告的打印不光检验内部用,还要给his、自助机、病案、支付宝、微信等用,你不可能要求第三方都有js执行环境。所以逻辑写在js的方案可以直接pass。

同时由于报告格式多样性和经常调整,把打印格式控制逻辑直接写在dll也是不合适的,你总不能改个格式就要求his、自助机等更新你的dll。

所以最完美的方案就是给第三方提供文件或者提供不包含业务逻辑的dll,对外dll只负责按元素绘制执行打印,内部不包含任何业务逻辑,dll通过数据库连接串调用服务器的脚步得到绘制数据绘制,这样改格式不影响第三方使用,在自己服务器内部就能完成打印格式控制。

设计参照打印设计

这种设计方案虽然很完美,但是也得有类似M的服务器脚本支撑,用Cache数据库完全没问题,换到关系库由于没有M的存在,所以这个方案就不行了,为此设计虚拟M层。

虚拟M层旨在提供一个类型M的脚步层,在虚拟M层,开发人员可以写和M的Query一样的逻辑,同时提供脚本化的效果,这样就可以借助虚拟M层完成很多事情,比如:控制输出打印元素、查询excel导出数据、启动TCP连接设备等,虚拟M的前提是框架实现脚本化。

首先实现虚拟M的主入口,到时候使用的地方就配置该ashx的路径来调用虚拟M

import LIS.Core.Dto.OutParam;
import LIS.Core.MultiPlatform.LISContext;
import LIS.Model.Bussiness.Parameters;
import appcode.BaseHttpHandlerNoSession;
import appcode.Helper;import java.io.File;
import java.io.PrintWriter;
import java.lang.reflect.Method;/*** 虚拟M层的调用入口实现类,由该类对外提供http的虚拟M服务。通过java业务脚本实现和M方法或者Query一样的输入输出约定,来供业务调用,进而基于* 此基础上实现打印和导出Excel等功能,vm概念很重要,打印、导出、连仪器都离不开*/
public class VMService extends BaseHttpHandlerNoSession {/*** 供外部http调用的请求入口** @return*/public String GetData() {//类名String ClassName = Helper.ValidParam(LISContext.GetRequest(Request, "ClassName"), "");//方法名String FuncName = Helper.ValidParam(LISContext.GetRequest(Request, "FuncName"), "");//参数String Param = Helper.ValidParam(LISContext.GetRequest(Request, "Param"), "");//会话串String Session = Helper.ValidParam(LISContext.GetRequest(Request, "Session"), "");//调用虚拟M代码return GetVMData(ClassName, FuncName, Param, Session);}/*** 得到数据,调用者和Web在一个程序预时候直接通过接口调用,避免post的性能损失** @param ClassName 类名 vm.his.printbarcode* @param FuncName  方法名 GetData* @param Param     P0-P14的参数json串* @param Session   会话串* @return*/public String GetVMData(String ClassName, String FuncName, String Param, String Session) {StringBuilder objStream = new StringBuilder();try {PrintWriter writer = Response.getWriter();String[] funArr = FuncName.split("^");String[] sessArr = Session.split("^");String FunModul = "";if (funArr.length > 1) {FunModul = funArr[1];}String RowCount = "";FuncName = funArr[0];String OutPutType = "";if (sessArr.length > 6) {OutPutType = sessArr[6];}Parameters ParamObj = (Parameters) Helper.Json2Object(Param, Parameters.class);//转换M的类名为java的类名称ClassName = LISContext.WebBasePath + File.separator + ClassName.replace(".", File.separator);//反射得到类型Object objDeal = GetBllObjService.GetObjectByConfString(ClassName, writer, "", "");//没有实现类if (objDeal == null) {String errStr = "类" + ClassName + "不存在";//编译报错信息if (GetBllObjService.BuildingResHash.containsKey(ClassName)) {errStr = GetBllObjService.BuildingResHash.get(ClassName).toString();}objStream.append("<Response>");objStream.append("<SQLResult><SQL><FunRet></FunRet></SQL></SQLResult><RetVal>-1</RetVal><Error>" + errStr + "</Error><Node>" + ClassName + "</Node><RowCount>0</RowCount>");objStream.append("</Response>");return objStream.toString();}//获得类型Class type = objDeal.getClass();//得到方法Method method = type.getMethod(FuncName);//没有实现方法if (method == null) {objStream.append("<Response>");objStream.append("<SQLResult><SQL><FunRet></FunRet></SQL></SQLResult><RetVal>-1</RetVal><Error>" + ClassName + "里面不存在:" + FuncName + "方法</Error><Node>" + ClassName + "</Node><RowCount>0</RowCount>");objStream.append("</Response>");return objStream.toString();}//会话对象,可能带出数据OutParam SessionOut=new OutParam();SessionOut.Message=Session;//返回行数对象,可能带出数据OutParam RowCountOut=new OutParam();RowCountOut.Message=RowCount;Object[] paraObj = new Object[16];paraObj[0] = ParamObj.P0;paraObj[1] = ParamObj.P1;paraObj[2] = ParamObj.P2;paraObj[3] = ParamObj.P3;paraObj[4] = ParamObj.P4;paraObj[5] = ParamObj.P5;paraObj[6] = ParamObj.P6;paraObj[7] = ParamObj.P7;paraObj[8] = ParamObj.P8;paraObj[9] = ParamObj.P9;paraObj[10] = ParamObj.P10;paraObj[11] = ParamObj.P11;paraObj[12] = ParamObj.P12;paraObj[13] = ParamObj.P13;paraObj[14] = SessionOut;paraObj[15] = RowCountOut;objStream.append("<Response>");int ResType = 0;String retJson = "";String Err = "";//调用方法直接返回串if (FuncName.substring(FuncName.length() - 4) == "MTHD" || FunModul == "MTHD") {//执行返回数据Object retObj = method.invoke(objDeal, paraObj);Session = SessionOut.GetString();RowCount = RowCountOut.GetString();retJson = retObj.toString();ResType = 1;}//方法直接输出Json串else if (FuncName.length() > 10 && FuncName.substring(FuncName.length() - 10) == "JSONStream" || FunModul == "JSONStream") {//执行返回数据Object retObj = method.invoke(objDeal, paraObj);Session = SessionOut.GetString();RowCount = RowCountOut.GetString();ResType = 1;retJson = retObj.toString();objStream.append("<" + FuncName + "Result>");objStream.append(DealXml(retJson));objStream.append("</" + FuncName + "Result>");objStream.append("<RetVal>0</RetVal><Error></Error><Node>" + FuncName + "</Node><RowCount>" + RowCount + "</RowCount><ResType>" + ResType + "</ResType>" + "<RetSession>" + Session + "</RetSession>");objStream.append("</Response>");return objStream.toString();}//方法输出List顶替Queryelse {//执行返回数据Object retObj = method.invoke(objDeal, paraObj);Session = SessionOut.GetString();RowCount = RowCountOut.GetString();retJson = retObj.toString();if (FuncName.substring(FuncName.length() - 4) == "JSON") {ResType = 1;} else {ResType = 2;}}objStream.append("<" + FuncName + "Result>" + DealXml(retJson) + "</" + FuncName + "Result>");objStream.append("<RetVal>0</RetVal><Error>" + Err + "</Error><Node>" + FuncName + "</Node><RowCount>" + RowCount + "</RowCount><ResType>" + ResType + "</ResType>" + "<RetSession>" + Session + "</RetSession>");objStream.append("</Response>");return objStream.toString();} catch (Exception ex) {objStream.append("<Response>");objStream.append("<SQLResult><SQL><FunRet></FunRet></SQL></SQLResult><RetVal>-1</RetVal><Error>调用:" + DealXml(ClassName + ",方法:" + FuncName + ",参数:" + Param + ",会话:" + Session + "发生异常!" + Helper.Object2Json(ex)) + "</Error><Node>" + ClassName + "</Node><RowCount>0</RowCount>");objStream.append("</Response>");return objStream.toString();}}/*** 替换xml干扰串** @param str* @return*/private String DealXml(String str) {return str.replace("&", "&amp;").replace("'", "&apos;").replace("\"", "&quot;").replace(">", "&gt;").replace("<", "&lt;");}}

然后实现两个虚拟M的示例
打印初步结构

import LIS.Core.Dto.OutParam;
import appcode.BaseHttpHandlerNoSession;/*** 输出符合打印元素绘制协议的打印元素数据,来供打印执行层打印*/
public class PrintBarCodeTest extends BaseHttpHandlerNoSession {/*** 按传入的RowID输出符合打印元素绘制协议的数据来实现打印控制* @param RowID 业务主键* @param P1* @param P2* @param P3* @param P4* @param P5* @param P6* @param P7* @param P8* @param P9* @param P10* @param P11* @param P12* @param P13* @param Session* @param Output* @return*/public String GetData(String RowID, String P1, String P2, String P3, String P4, String P5, String P6, String P7, String P8, String P9, String P10, String P11, String P12, String P13, OutParam Session, OutParam Output) {//先包一个打印元素绘制协议数据生成的工具类来解决元素约束问题,工具类实现了调用工具类得到标签,条码,文本等return "[]";}
}

导出的示例

import LIS.Core.Dto.OutParam;
import LIS.Model.Entity.BTTestCode;
import appcode.BaseHttpHandlerNoSession;
import appcode.Helper;import java.util.List;/*** 输出符合Query约定的数据供导出Excel用,所有的虚拟M方法参数约定就是这个样子*/
public class ExportExcelTest extends BaseHttpHandlerNoSession {/*** 查询所有项目数据导出到Excel* @param P0* @param P1* @param P2* @param P3* @param P4* @param P5* @param P6* @param P7* @param P8* @param P9* @param P10* @param P11* @param P12* @param P13* @param Session* @param Output* @return*/public String QryTestCode(String P0, String P1, String P2, String P3, String P4, String P5, String P6, String P7, String P8, String P9, String P10, String P11, String P12, String P13, OutParam Session, OutParam Output) throws Exception{BTTestCode dto=new BTTestCode();//返回的参数,供Excel模板使用Session.Message="项目数据导出^"+LIS.Core.Util.TimeParser.GetNowDate()+"^zhanglianzhu";//查询项目数据List<BTTestCode> retList=EntityManager().FindAll(dto,null,"",-1,-1);//数组转json就是等价Query的return Helper.Object2Json(retList);}
}

这样客户端执行层再对接虚拟M调用后就可以完成以前在M层实现的效果了,为了支持虚拟M层,把业务脚本化的实现下沉到jar包层,虚拟M和Web调用共用业务脚本化基础

在这里插入图片描述

虚拟M存放的目录
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/188412.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenAI GPT5计划泄露

OpenAI的首席执行官萨姆奥特曼在最近接受《金融时报》的专访时&#xff0c;分享了OpenAI未来发展的一些新动向。此外&#xff0c;他还透露了关于即将到来的GPT-5模型以及公司对AGI的长期目标的一些细节。 奥特曼指出&#xff1a; 1.OpenAI正在开发GPT-5&#xff0c;一种更先进的…

FullCalendar日历插件说明文档

一般标准配置 属性描述默认值header设置日历头部信息。 如果设置为false&#xff0c;则不显示头部信息。包括left&#xff0c;center,right左中右三个位置&#xff0c;每个位置都可以对应以下不同的配置&#xff1a; title: 显示当前月份/周/日信息 prev: 用于切换到上一月/周…

Postman:API测试之Postman使用完全指南

Postman是一个可扩展的API开发和测试协同平台工具&#xff0c;可以快速集成到CI/CD管道中。旨在简化测试和开发中的API工作流。 Postman工具有Chrome扩展和独立客户端&#xff0c;推荐安装独立客户端。 Postman有个workspace的概念&#xff0c;workspace分personal和team类型…

jetson nano的tensorrt加速部署

实验平台参数 jetack在线OTA升级指令 $ sudo vi /etc/apt/sources.list.d/nvidia-l4t-apt-source.list修改其apt源文件即可,即可可以参考上一篇文章 一,查看相应的包版本 1,jetpack版本查看 🔔sudo apt-cache show nvidia-jetpack 后面我进行了OTA在线升级,升级到4.…

LangGPT作者教你编写高质量提示词

CoT和ToT能够提升表现&#xff0c;但是会使得模型的使用变复杂。在对话的场景下容易消耗人的耐心&#xff1b;实际应用的场景下&#xff0c;比较消耗人的token。 还有一点需要说明的是&#xff0c;我们在写自己的prompt的时候&#xff0c;不应该盲目地追求和堆砌提示词技巧&am…

提前占领高地!2024年值得期待的UI设计原型图软件推荐

UI设计原型图软件对于产品经理、设计师来说是效率神器。一款专业的UI设计原型图软件能够帮助产品经理、设计师高效且快速地创建精美且实用的UI用户界面&#xff0c;从而提升UI用户界面的产品价值。本篇文章将推荐10款2024年好用的UI设计原型图软件&#xff0c;以帮助你更好地选…

面试其他注意事项

面试其他注意事项 一、面试反问 这个岗位的日常工作和主要职责是什么&#xff1f;咱们这边主要负责什么业务&#xff0c;用到了哪些技术呢&#xff1f;对于我们校招生有没有培养体系呢&#xff1f;脱产培训&#xff0c;还是边工作边熟悉&#xff1f;会有导师带嘛&#xff1f;…

YOLOv5项目实战(4)— 简单三步,教你按比例划分数据集

前言:Hello大家好,我是小哥谈。本节课就教大家如何去按照比例去划分数据集,希望大家学习之后可以有所收获!~🌈 前期回顾: YOLOv5项目实战(1)— 如何去训练模型 YOLOv5项目

ssrf学习笔记总结

SSRF概述 ​ 服务器会根据用户提交的URL 发送一个HTTP 请求。使用用户指定的URL&#xff0c;Web 应用可以获取图片或者文件资源等。典型的例子是百度识图功能。 ​ 如果没有对用户提交URL 和远端服务器所返回的信息做合适的验证或过滤&#xff0c;就有可能存在“请求伪造”的…

【备忘】在Nginx服务器安装SSL证书

您可以在Nginx或Tengine服务器上安装SSL证书&#xff0c;实现通过HTTPS安全访问Web服务器。本文介绍如何为Nginx或Tengine服务器安装SSL证书。 重要 本文以CentOS 8.0 64位操作系统、Nginx 1.14.2为例介绍。不同版本的操作系统或Web服务器&#xff0c;部署操作可能有所差异&a…

零代码编程:用ChatGPT批量转换多个视频文件夹到音频并自动移动文件夹

有很多个视频文件夹&#xff1a; 要全部转成音频&#xff0c;然后复制到另一个文件夹。 在ChatGPT中输入如下提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个批量将Mp4视频转为Mp3音频的任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;…

2.项目疑问

Day01 1.前后端分离项目的全局异常处理怎么做 使用ControllerAdviceExceptionHandler&#xff08;类.class&#xff09;来实现异常处理 ControllerAdvice: Controller增强器。将异常处理器应用到所有的控制器 ExceptionHandler&#xff1a;异常处理器&#xff0c;只要发生异…