JRT菜单
上一章搭建了登录界面的雏形和抽取了登录接口。给多组使用登录和菜单功能提供预留,做到不强行入侵别人业务。任何产品只需要按自己表实现登录接口后配置到容器即可共用登录界面和菜单部分。最后自己的用户关联到JRT角色表即可。
登录效果
这次构建菜单体系
首先用dbo.JRTForm描述页面路径资源
用dbo.JRTFormFunction描述页面的控制点
然后用菜单dbo.JRTMenu表描述菜单树
最后用角色和角色菜单把菜单数据通过角色暴露给业务模块
这样业务模块就很自由了,可以自由的用自己的用户表,自己的用户角色关系。最终只需要有关系对应上JRTRole表就行了,在登录接口实现执行角色就能共用整套登录和菜单体系了。比如检验的用户登录的工作组。
登录接口实现类按具体表和菜单暴露的角色表对接,JRT开头的表是给大家共用的
效果
JRT提供执行SQL语句的api,不到万不得已的时候JRT不鼓励用SQL语句写业务,因为一旦用SQL之后,跨数据库就成为无稽之谈,目前没有发现使用SQL语句的必要性。
系统页面维护后台代码
import JRT.Core.CustomAttributes.Trans;
import JRT.Core.Dto.OutValue;
import JRT.Core.Util.TxtUtil;
import JRTBLLBase.BaseHttpHandlerNoSession;
import JRTBLLBase.Helper;
import JRT.Core.Dto.HashParam;
import JRT.Core.Dto.ParamDto;
import JRT.Core.Dto.OutParam;
import JRT.Model.Entity.*;
import JRT.Core.Util.Convert;
import JRT.Core.MultiPlatform.JRTContext;import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;/*** 界面资源维护的后台代码*/
public class ashJRTForm extends BaseHttpHandlerNoSession {/*** 保存数据,前台按表的属性名提交** @return 字符串*/public String SaveJRTForm() throws Exception {JRTForm dto = new JRTForm();//主键dto.RowID = Helper.ValidParam(JRTContext.GetRequest(Request, "RowID"), dto.RowID);//名称dto.CName = Helper.ValidParam(JRTContext.GetRequest(Request, "CName"), dto.CName);//序号dto.Sequence = Helper.ValidParam(JRTContext.GetRequest(Request, "Sequence"), dto.Sequence);//激活 {1:true,0:false}dto.Active = Helper.ValidParam(JRTContext.GetRequest(Request, "Active"), dto.Active);//相对路径dto.Path = Helper.ValidParam(JRTContext.GetRequest(Request, "Path"), dto.Path);//说明dto.Remark = Helper.ValidParam(JRTContext.GetRequest(Request, "Remark"), dto.Remark);//帮助信息dto.FormHelp = Helper.ValidParam(JRTContext.GetRequest(Request, "FormHelp"), dto.FormHelp);//宽度dto.HelpWidth = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpWidth"), dto.HelpWidth);//高度dto.HelpHeight = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpHeight"), dto.HelpHeight);//帮助文档路径dto.HelpDoc = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpDoc"), dto.HelpDoc);OutParam out = new OutParam();int ret = 0;//更新if (dto.RowID > 0) {ret = EntityManager().Update(dto, null, out, null, null, null);}//插入数据else {ret = EntityManager().Save(dto, out);}if (ret == 1) {return Helper.Success();} else {return Helper.Error(out);}}/*** 删除数据,多个RowID以上尖号分割** @return 字符串*/@Transpublic String DeleteJRTForm() throws Exception {String RowIDS = Helper.ValidParam(JRTContext.GetRequest(Request, "RowIDS"), "");if (RowIDS.isEmpty()) {return Helper.Error("请传入要删除数据的RowID,多个以^分割!");}//分割主键String[] arr = RowIDS.split("^");//循环删除数据for (int i = 0; i < arr.length; i++) {int formDR = Convert.ToInt32(arr[i]);//删除页面功能点List<JRTFormFunction> formFunList = EntityManager().FindByColVal(JRTFormFunction.class, "FormDR", formDR);if (formFunList != null && formFunList.size() > 0) {for (JRTFormFunction f : formFunList) {int ret = EntityManager().Remove(f, ErrRet());if (ret != 1) {throw new Exception(Err.GetString());}}}//删除页面数据int ret = EntityManager().RemoveById(JRTForm.class, formDR, ErrRet());if (ret != 1) {throw new Exception(Err.GetString());}}return Helper.Success();}/*** 查询数据,前台按表的属性名提交** @return 字符串*/public String QryJRTForm() throws Exception {//预留的取前台参数代码//参数List<ParamDto> para = new ArrayList<>();//sql连接符号List<String> joiner = new ArrayList<>();//sql比较符号List<String> operators = new ArrayList<>();//模糊查询String Filter = Helper.ValidParam(JRTContext.GetRequest(Request, "Filter"), "");//预留参数//主键String RowID = Helper.ValidParam(JRTContext.GetRequest(Request, "RowID"), "");//名称String CName = Helper.ValidParam(JRTContext.GetRequest(Request, "CName"), "");//序号String Sequence = Helper.ValidParam(JRTContext.GetRequest(Request, "Sequence"), "");//激活 {1:true,0:false}String Active = Helper.ValidParam(JRTContext.GetRequest(Request, "Active"), "");//相对路径String Path = Helper.ValidParam(JRTContext.GetRequest(Request, "Path"), "");//说明String Remark = Helper.ValidParam(JRTContext.GetRequest(Request, "Remark"), "");//帮助信息String FormHelp = Helper.ValidParam(JRTContext.GetRequest(Request, "FormHelp"), "");//宽度String HelpWidth = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpWidth"), "");//高度String HelpHeight = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpHeight"), "");//帮助文档路径String HelpDoc = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpDoc"), "");//模糊查询if (!Filter.isEmpty()) {ParamDto p = null;//名称p = new ParamDto();p.Key = "CName";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//相对路径p = new ParamDto();p.Key = "Path";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//说明p = new ParamDto();p.Key = "Remark";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//帮助信息p = new ParamDto();p.Key = "FormHelp";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//帮助文档路径p = new ParamDto();p.Key = "HelpDoc";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");}//调用查询String json = EntityManager().QueryAllWithFK(JRTForm.class, para, "", true, -1, -1, "", joiner, operators);return json;}/*** 得到页面的功能点** @return*/public String GetFormFunction() throws Exception {int FormDR = Helper.ValidParam(JRTContext.GetRequest(Request, "FormDR"), 0);List<FormFunctionDto> retList = GetFunctionList(FormDR);if (retList == null || retList.size() == 0) {return "[{\"RowID\":\"-2\",\"Name\":\"" + "\"无功能点控制\"" + "\"}]";} else {//取功能点名称for (FormFunctionDto one : retList) {if (one.FunctionDR != null) {JRTFunction fun = EntityManager().DolerGet(JRTFunction.class, one.FunctionDR);one.FunctionName = fun.CName;}}}return Helper.Object2Json(retList);}/*** 得到页面功能点列表** @param formDR 页面主键* @return 页面功能点* @throws Exception*/private List<FormFunctionDto> GetFunctionList(int formDR) throws Exception {List<FormFunctionDto> retList = new ArrayList<>();HashParam hs = new HashParam();hs.Add("FormDR", formDR);//页面功能点List<FormFunctionDto> formFunctions = EntityManager().FindAll(FormFunctionDto.class, hs, "", -1, -1, "", null, null);//读取指定文件中的功能点//基地址String basePath = JRTContext.MapPath("");//得到页面数据JRTForm form = EntityManager().GetById(JRTForm.class, formDR);if (form != null) {String codeStr = GetFormCode(form, basePath);//调用方法读取代码中功能点集合List<String> functionCodes = GetFunctionCode(codeStr);//功能点JRTFunction functionOne = null;//实际页面功能点List<JRTFunction> realFunctions = new ArrayList<>();if (functionCodes != null) {for (String functionCode : functionCodes) {functionOne = EntityManager().GetByColVal(JRTFunction.class, "Code", functionCode);if (functionOne != null) {realFunctions.add(functionOne);} else {JRTFunction funcDto = new JRTFunction();funcDto.Active = true;funcDto.CName = functionCode;funcDto.Code = functionCode;funcDto.Sequence = 1;OutValue key = new OutValue();int ret = EntityManager().Save(funcDto, key, ErrRet());if (ret == 1) {funcDto.RowID = key.GetInerger();realFunctions.add(funcDto);}}}}//遍历页面功能点检测页面不提供的功能点,数据库有页面没有的功能点for (FormFunctionDto f : formFunctions) {boolean isHas = false;for (JRTFunction rf : realFunctions) {if (rf.RowID == f.FunctionDR) {isHas = true;break;}}if (isHas == false) {//应该删除的数据f.FormDR = -1;}retList.add(f);}//页面有数据库没有的功能点功能点for (JRTFunction rf1 : realFunctions) {boolean isHas = false;for (FormFunctionDto f1 : formFunctions) {if (rf1.RowID == f1.FunctionDR) {isHas = true;break;}}if (isHas == false) {FormFunctionDto dto = new FormFunctionDto();//该添加的数据dto.RowID = -1;dto.FormDR = formDR;dto.FunctionDR = rf1.RowID;retList.add(dto);}}return retList;} else {return retList;}}/*** 得到页面的代码** @param form 页面* @param basePath 根地址* @return 页面代码* @throws Exception*/private String GetFormCode(JRTForm form, String basePath) throws Exception {String formPath = form.Path;formPath = formPath.split("\\?")[0];//路径存在if (formPath != null && formPath.length() > 1) {formPath = formPath.replace("../../", "").replace("../", "").replace("/", (char) 0 + "");String[] arr = formPath.split((char) 0 + "");String pathR = arr[0];for (int i = 1; i < arr.length; i++) {pathR = Paths.get(pathR, arr[i]).toString();}formPath = Paths.get(basePath, pathR).toString();if (formPath.toLowerCase().contains(".pdf")) {return "";}int index = formPath.indexOf(".aspx");formPath = formPath.substring(0, index + 5);File fi = new File(formPath);//如果文件存在,读取文件信息if (fi.exists()) {//读取所有代码String codeStr = TxtUtil.ReadTextStr(formPath);return codeStr;}}return "";}/*** 处理功能点的特色字符** @param data 数据* @return 剔除特殊字符的数据*/public String DealSpChar(String data) {for (int i = 0; i <= 31; i++) {data = data.replace((char) i + "", "");}data = data.replace((char) 127 + "", "");data = data.replace("\r\n", "");data = data.replace(";", "");return data;}/*** 得到页面功能点代码** @param codeStr 页面代码串* @return*/private List<String> GetFunctionCode(String codeStr) {List<String> codes = new ArrayList<>();int curIndex = 0;int startIndex = 0;while (curIndex == 0) {String funStrFlag1 = "SYSPageCommonInfo.GetFunction(";curIndex = codeStr.indexOf(funStrFlag1, startIndex);if (curIndex > 0) {//得到功能点后下标int endIndex = codeStr.indexOf(")", curIndex + funStrFlag1.length() + 1);//得到功能点串String funStr = codeStr.substring(curIndex + funStrFlag1.length() + 1, endIndex - 1);funStr = DealSpChar(funStr);//没有就添加到集合,有就不要if (!codes.contains(funStr)) {codes.add(funStr);}curIndex = 0;startIndex = endIndex;continue;}}return codes;}/*** 同步功能点** @return* @throws Exception*/public String RsyncFun() throws Exception {int formDR = Helper.ValidParam(JRTContext.GetRequest(Request, "FormDR"), 0);List<FormFunctionDto> list = GetFunctionList(formDR);if (list != null && list.size() > 0) {for (FormFunctionDto v : list) {//删除if (v.FormDR == -1) {int ret = EntityManager().RemoveById(JRTFormFunction.class, v.RowID, ErrRet());}//添加if (v.RowID == -1) {int ret = EntityManager().Save(v);}}}return Helper.Success();}/*** 页面功能点返回实体*/public static class FormFunctionDto extends JRTFormFunction {/*** 功能点名称*/public String FunctionName;}
}
菜单维护的后台代码
import JRT.Core.CustomAttributes.Trans;
import JRT.Core.Dto.OutValue;
import JRT.Core.Util.TxtUtil;
import JRTBLLBase.BaseHttpHandlerNoSession;
import JRTBLLBase.Helper;
import JRT.Core.Dto.HashParam;
import JRT.Core.Dto.ParamDto;
import JRT.Core.Dto.OutParam;
import JRT.Model.Entity.*;
import JRT.Core.Util.Convert;
import JRT.Core.MultiPlatform.JRTContext;import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;/*** 菜单资源维护的后台代码*/
public class ashJRTMenu extends BaseHttpHandlerNoSession {/*** 查询所有页面数据** @return* @throws Exception*/public String QueryAllForm() throws Exception {//预留的取前台参数代码//参数List<ParamDto> para = new ArrayList<>();//sql连接符号List<String> joiner = new ArrayList<>();//sql比较符号List<String> operators = new ArrayList<>();//模糊查询String Filter = Helper.ValidParam(JRTContext.GetRequest(Request, "Filter"), "");//预留参数//主键String RowID = Helper.ValidParam(JRTContext.GetRequest(Request, "RowID"), "");//名称String CName = Helper.ValidParam(JRTContext.GetRequest(Request, "CName"), "");//序号String Sequence = Helper.ValidParam(JRTContext.GetRequest(Request, "Sequence"), "");//激活 {1:true,0:false}String Active = Helper.ValidParam(JRTContext.GetRequest(Request, "Active"), "");//相对路径String Path = Helper.ValidParam(JRTContext.GetRequest(Request, "Path"), "");//说明String Remark = Helper.ValidParam(JRTContext.GetRequest(Request, "Remark"), "");//帮助信息String FormHelp = Helper.ValidParam(JRTContext.GetRequest(Request, "FormHelp"), "");//宽度String HelpWidth = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpWidth"), "");//高度String HelpHeight = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpHeight"), "");//帮助文档路径String HelpDoc = Helper.ValidParam(JRTContext.GetRequest(Request, "HelpDoc"), "");//模糊查询if (!Filter.isEmpty()) {ParamDto p = null;//名称p = new ParamDto();p.Key = "CName";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//相对路径p = new ParamDto();p.Key = "Path";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//说明p = new ParamDto();p.Key = "Remark";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//帮助信息p = new ParamDto();p.Key = "FormHelp";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");//帮助文档路径p = new ParamDto();p.Key = "HelpDoc";p.Value = "%" + Filter + "%";para.add(p);joiner.add("or");operators.add("like");}//调用查询String json = EntityManager().QueryAllWithFK(JRTForm.class, para, "", false, -1, -1, "", joiner, operators);return json;}/*** 查询所有菜单** @return* @throws Exception*/public String GetAllMenu() throws Exception {String SystemDR = Helper.ValidParam(JRTContext.GetRequest(Request, "SystemDR"), "");MenuTreeDto retMenu = new MenuTreeDto();retMenu.isFolder = "1";retMenu.id = "0";retMenu.RowID = 0;retMenu.Level = 0;HashParam hs = new HashParam();if (!SystemDR.isEmpty()) {retMenu.SystemDR = Convert.ToInt32(SystemDR);hs.Add("SystemDR", Convert.ToInt32(SystemDR));JRTSystem sysDto = EntityManager().DolerGet(JRTSystem.class, Convert.ToInt32(SystemDR));retMenu.text = sysDto.SysName;retMenu.CName = sysDto.SysName;}//查询角色系统的全部菜单数据List<JRTMenu> allMenu = EntityManager().FindAll(JRTMenu.class, hs, "Sequence asc", "", null, null);int seqIndex = 0;List<String> upCol = new ArrayList<>();upCol.add("Sequence");for (JRTMenu m : allMenu) {//一级菜单if (m.ParentDR == null) {seqIndex++;//更新序号if (m.Sequence != seqIndex * 5) {m.Sequence = seqIndex * 5;int ret = EntityManager().Update(m, ErrRet(), upCol);}MenuTreeDto one = MenuToMenuDto(m);one.isFolder = "1";one.state = "closed";one.Level = retMenu.Level + 1;retMenu.children.add(one);AddChildMenu(one, allMenu);}}return "[" + Helper.Object2Json(retMenu) + "]";}/*** 更新菜单序号** @return* @throws Exception*/public String UpdateSequence() throws Exception {int RowID = Helper.ValidParam(JRTContext.GetRequest(Request, "RowID"), -1);int Sequence = Helper.ValidParam(JRTContext.GetRequest(Request, "Sequence"), -1);JRTMenu curMenu = EntityManager().GetById(JRTMenu.class, RowID);if (curMenu == null) {return Helper.Error("没有找到菜单数据!");}curMenu.Sequence = Sequence;List<String> upCol = new ArrayList<>();upCol.add("Sequence");int ret = EntityManager().Update(curMenu, ErrRet(), upCol);if (ret == -1) {return Helper.Error(this.Err);}return Helper.Success();}/*** 粘贴菜单,复制的才能只能粘贴到复制级别的上级,或者整个菜单树** @return*/@Transpublic String PasteMenu() throws Exception {//老节点int OldDR = Helper.ValidParam(JRTContext.GetRequest(Request, "OldDR"), 0);//新节点int NewDR = Helper.ValidParam(JRTContext.GetRequest(Request, "NewDR"), 0);//目标系统int SystemDR = Helper.ValidParam(JRTContext.GetRequest(Request, "SystemDR"), 0);//源头系统int OldSystemDR = Helper.ValidParam(JRTContext.GetRequest(Request, "OldSystemDR"), 0);//复制整个菜单树if (OldDR == 0) {HashParam hs = new HashParam();hs.Add("SystemDR", OldSystemDR);//查询角色系统的全部菜单数据List<JRTMenu> allMenu = EntityManager().FindAllSimple(JRTMenu.class, hs);for (JRTMenu one : allMenu) {if (one.ParentDR == null) {int oneOldID = one.RowID;one.SystemDR = SystemDR;OutValue key = new OutValue();int ret = EntityManager().Save(one, key, ErrRet());if (ret == 1) {for (JRTMenu tow : allMenu) {if (tow.ParentDR != null && tow.ParentDR == oneOldID) {tow.ParentDR = one.RowID;tow.SystemDR = SystemDR;int ret1 = EntityManager().Save(tow, key, ErrRet());if (ret1 != 1) {throw new Exception("复制2级菜单异常:" + ErrRet().GetString());}}}} else {throw new Exception("复制1级菜单异常:" + ErrRet().GetString());}}}} else {JRTMenu menuOld = EntityManager().GetById(JRTMenu.class, OldDR);//复制目录到根节点if (NewDR == 0) {HashParam hs = new HashParam();hs.Add("ParentDR", OldDR);//查询角色系统的全部菜单数据List<JRTMenu> allChildMenu = EntityManager().FindAllSimple(JRTMenu.class, hs);menuOld.SystemDR = SystemDR;OutValue key = new OutValue();int ret = EntityManager().Save(menuOld, key, ErrRet());if (ret == 1) {for (JRTMenu tow : allChildMenu) {tow.ParentDR = menuOld.RowID;tow.SystemDR = SystemDR;int ret1 = EntityManager().Save(tow, key, ErrRet());if (ret1 != 1) {throw new Exception("复制2级菜单异常:" + ErrRet().GetString());}}} else {throw new Exception("复制1级菜单异常:" + ErrRet().GetString());}}//复制子菜单到目录else {OutValue key = new OutValue();menuOld.ParentDR = NewDR;menuOld.SystemDR = SystemDR;int ret = EntityManager().Save(menuOld, key, ErrRet());if (ret != 1) {throw new Exception("复制1级菜单异常:" + ErrRet().GetString());}}}return Helper.Success();}/*** 保存数据,前台按表的属性名提交** @return 字符串*/public String SaveJRTMenu() throws Exception {JRTMenu dto = new JRTMenu();//主键dto.RowID = Helper.ValidParam(JRTContext.GetRequest(Request, "RowID"), dto.RowID);//名称dto.CName = Helper.ValidParam(JRTContext.GetRequest(Request, "CName"), dto.CName);//上级dto.ParentDR = Helper.ValidParam(JRTContext.GetRequest(Request, "ParentDR"), dto.ParentDR);//页面路径dto.FormDR = Helper.ValidParam(JRTContext.GetRequest(Request, "FormDR"), dto.FormDR);//功能描述dto.Description = Helper.ValidParam(JRTContext.GetRequest(Request, "Description"), dto.Description);//图标dto.Icon = Helper.ValidParam(JRTContext.GetRequest(Request, "Icon"), dto.Icon);//序号dto.Sequence = Helper.ValidParam(JRTContext.GetRequest(Request, "Sequence"), dto.Sequence);//激活 {1:true,0:false}dto.Active = Helper.ValidParam(JRTContext.GetRequest(Request, "Active"), dto.Active);//是否置顶显示 {1:true,0:false}dto.IsTop = Helper.ValidParam(JRTContext.GetRequest(Request, "IsTop"), dto.IsTop);//子系统dto.SystemSubDR = Helper.ValidParam(JRTContext.GetRequest(Request, "SystemSubDR"), dto.SystemSubDR);//系统模块dto.SystemDR = Helper.ValidParam(JRTContext.GetRequest(Request, "SystemDR"), dto.SystemDR);//空:在Tab页打印,0:弹窗打开,1:独立打开dto.OpenModel = Helper.ValidParam(JRTContext.GetRequest(Request, "OpenModel"), dto.OpenModel);//打开宽度dto.OpenWidth = Helper.ValidParam(JRTContext.GetRequest(Request, "OpenWidth"), dto.OpenWidth);//打开高度dto.OpenHeight = Helper.ValidParam(JRTContext.GetRequest(Request, "OpenHeight"), dto.OpenHeight);//根节点if(dto.ParentDR==0){dto.ParentDR=null;}OutParam out = new OutParam();int ret = 0;//更新if (dto.RowID > 0) {ret = EntityManager().Update(dto, null, out, null, null, null);}//插入数据else {ret = EntityManager().Save(dto, out);}if (ret == 1) {return Helper.Success();} else {return Helper.Error(out);}}/*** 删除数据,多个RowID以上尖号分割** @return 字符串*/public String DeleteJRTMenu() throws Exception {String RowIDS = Helper.ValidParam(JRTContext.GetRequest(Request, "RowIDS"), "");if (RowIDS.isEmpty()) {return Helper.Error("请传入要删除数据的RowID,多个以^分割!");}//分割主键String[] arr = RowIDS.split("^");//out参数OutParam out = new OutParam();//循环删除数据for (int i = 0; i < arr.length; i++) {//是否有子菜单List<JRTMenu> child=EntityManager().FindByColVal(JRTMenu.class,"ParentDR",Convert.ToInt32(arr[i]));if(child!=null&&child.size()>0){return Helper.Error("当前菜单已经有子菜单数据,请先删除子项!");}int ret = EntityManager().RemoveById(JRTMenu.class, Convert.ToInt32(arr[i]), out);if (ret != 1) {return Helper.Error(out);}}return Helper.Success();}/*** 添加子菜单** @param one 一级菜单* @param allMenu 所有菜单*/private void AddChildMenu(MenuTreeDto one, List<JRTMenu> allMenu) throws Exception {int seqIndex = 0;List<String> upCol = new ArrayList<>();upCol.add("Sequence");for (JRTMenu m : allMenu) {if (m.ParentDR != null && one.RowID == m.ParentDR) {seqIndex++;//更新序号if (m.Sequence != seqIndex * 5) {m.Sequence = seqIndex * 5;int ret = EntityManager().Update(m, ErrRet(), upCol);}MenuTreeDto child = MenuToMenuDto(m);child.Level = one.Level + 1;one.children.add(child);AddChildMenu(child, allMenu);}}}/*** 菜单表是实体得到菜单数据的实体** @param menu 菜单表数据* @return 菜单树数据* @throws Exception*/private MenuTreeDto MenuToMenuDto(JRTMenu menu) throws Exception {MenuTreeDto oneMenu = new MenuTreeDto();oneMenu.RowID = menu.RowID;oneMenu.id = String.valueOf(menu.RowID);oneMenu.CName = menu.CName;oneMenu.text = menu.CName;oneMenu.isFolder = "0";oneMenu.FormDR = menu.FormDR;//页面路径if(menu.FormDR!=null){JRTForm form=EntityManager().DolerGet(JRTForm.class,menu.FormDR);oneMenu.FormPath=form.Path;}if (menu.ParentDR == null) {oneMenu.ParentDR = 0;} else {oneMenu.ParentDR = menu.ParentDR;}oneMenu.Description = menu.Description;oneMenu.Icon = menu.Icon;oneMenu.iconCls = "icon iconfont " + menu.Icon;oneMenu.Sequence = menu.Sequence;oneMenu.Active = menu.Active;oneMenu.IsTop = menu.IsTop;oneMenu.OpenModel = menu.OpenModel;if (menu.OpenWidth == null) {oneMenu.OpenWidth = "";} else {oneMenu.OpenWidth = String.valueOf(menu.OpenWidth);}if (menu.OpenHeight == null) {oneMenu.OpenHeight = "";} else {oneMenu.OpenHeight = String.valueOf(menu.OpenHeight);}oneMenu.SystemDR = menu.SystemDR;return oneMenu;}/*** 菜单树实体*/public static class MenuTreeDto {/*** 构造函数*/public MenuTreeDto() {id = "";text = "";iconCls = "";isFolder = "";state = "";checked = "";RowID = 0;Level = 0;CName = "";FormDR = null;ParentDR = 0;Description = "";Icon = "";Sequence = 0;Active = true;IsTop = false;OpenModel = "";OpenWidth = "";OpenHeight = "";children = new ArrayList<>();SystemDR = 0;FormPath="";}/*** 树id*/public String id;/*** 树文本*/public String text;/*** 树图标*/public String iconCls;/*** 是否是文件夹*/public String isFolder;/*** 树的状态*/public String state;/*** 是否选择*/public String checked;/*** 层级*/public int Level;/*** 菜单主键*/public int RowID;/*** 菜单名称*/public String CName;/*** 菜单路径*/public Integer FormDR;/*** 菜单父级*/public int ParentDR;/*** 菜单描述*/public String Description;/*** 菜单图标*/public String Icon;/*** 菜单序号*/public int Sequence;/*** 是否激活*/public Boolean Active;/*** 是否在顶部*/public Boolean IsTop;/*** 打开模式*/public String OpenModel;/*** 打开宽度*/public String OpenWidth;/*** 打开高度*/public String OpenHeight;/*** 子菜单*/public List<MenuTreeDto> children;/*** 系统*/public int SystemDR;/*** 页面路径*/public String FormPath;}}
登录界面的后台
import JRT.Core.Dto.HashParam;
import JRT.Core.MultiPlatform.JRTConfigurtaion;
import JRT.Core.MultiPlatform.JRTContext;
import JRT.Core.Util.IPMacUtil;
import JRT.Core.Util.Md5Util;
import JRT.Core.Util.PassWordUtil;
import JRT.Core.Util.TimeParser;
import JRT.DAL.ORM.EntityManager.EntityManagerImpl;
import JRT.Login.ILogin;
import JRT.Login.SelectRoleDto;
import JRT.Model.Bussiness.Sessions;
import JRT.Model.Entity.JRTUserLog;
import JRT.Model.Entity.SYSParameter;
import JRTBLLBase.BaseHttpHandlerNoSession;
import JRTBLLBase.Helper;import java.util.HashMap;
import java.util.List;/*** 作为登录界面的后台实现类,实现用户验证和修改密码登,为登录构造会话*/
public class ashLogin extends BaseHttpHandlerNoSession {/*** 登录接口*/private ILogin login=null;/*** 得到登录的实现类* @return* @throws Exception*/private ILogin Login() throws Exception{//登录类型String LoginType=Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "LoginType"), "LIS");if(login==null) {login = (ILogin) JRT.Core.Context.ObjectContainer.GetObject(LoginType);}return login;}/*** 得到登录信息* @return 常用信息的键值对*/public String GetLoginInfo() throws Exception{HashMap map=new HashMap();//系统标题map.put("SystemTitle",Login().GetSystemTitle());//系统名称map.put("SystemName",Login().GetSystemName());//模块名称map.put("UrlTitle",Login().GetUrlTitle());//选择的角色名称map.put("RoleTypeName",Login().GetRoleTypeName());//密码级别map.put("SYSPasswordLevel",Login().GetSYSPasswordLevel());//密码长度map.put("SYSPasswordLength",Login().GetSYSPasswordLength());//显示的服务器IPString ServiceShowIP= JRTConfigurtaion.Configuration("ServiceShowIP");//密码长度map.put("ServiceShowIP",ServiceShowIP);//密码长度map.put("ClientIP",JRTContext.GetClientIP(Request));return Helper.Object2Json(map);}/*** 校验用户* @return*/public String CheckUser() throws Exception{//用户名String UserCode = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "UserCode"), "");//密码String Password = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "Password"), "");//解密密码Password=JRT.Core.Util.RsaUtil.RsaDecrypt(Password);//验证密码boolean ret=Login().CheckUser(UserCode,Password);if(ret==false){return Helper.Error("用户名或密码错误!");}else{//用户名加上时间构成时间戳String timeSpan=JRT.Core.Util.RsaUtil.RsaEncrypt(JRT.Core.Util.TimeParser.GetNowTime()+"^"+UserCode);//得到选择的角色数据List<SelectRoleDto> roleList=Login().GetSelectRole(UserCode);HashMap map=new HashMap();//系统标题map.put("TimeSpan",timeSpan);map.put("RoleList",roleList);return Helper.Success(Helper.Object2Json(map));}}/*** 登录并且构造会话* @return*/public String LoginSys() throws Exception{//用户名String UserCode = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "UserCode"), "");//密码String Password = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "Password"), "");//角色String RoleJson = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "RoleJson"), "");//登录类型String LoginType=Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "LoginType"), "LIS");//解密密码Password=JRT.Core.Util.RsaUtil.RsaDecrypt(Password);//验证密码boolean ret=Login().CheckUser(UserCode,Password);if(ret==false){return Helper.Error("用户名或密码错误!");}//角色对象SelectRoleDto role=(SelectRoleDto)Helper.Json2Object(RoleJson,SelectRoleDto.class);//会话IDString SYSSessionID="";String SessionKey="JRTUserSession";//取会话对象Sessions session=JRTContext.GetSession(Session,SessionKey);if(session!=null){SYSSessionID=LoginType+"-"+role.UserID+"-"+role.GroupID+"-"+role.RoleDR;SYSSessionID= Md5Util.GetMd5Hash(SYSSessionID);SessionKey="JRTUserSession-"+SYSSessionID;}Sessions sessionNew=new Sessions();sessionNew.IpAddress= JRTContext.GetClientIP(Request);sessionNew.UserCode=role.UserCode;sessionNew.UserID=role.UserID;sessionNew.UserName=role.UserName;sessionNew.SessionStr=role.SessionStr;sessionNew.GroupID=role.GroupID;sessionNew.RoleDR=role.RoleDR;sessionNew.RoleName=role.RoleName;sessionNew.SYSSessionID=SYSSessionID;sessionNew.LoginDate=Helper.GetNowDate();sessionNew.LoginTime=Helper.GetNowTime();sessionNew.LoginType=LoginType;JRTContext.SetSession(Session,SessionKey,sessionNew);return Helper.Success(SYSSessionID);}/*** 修改密码* @return*/public String ChangePassword() throws Exception{//用户名String UserCode = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "UserCode"), "");//密码String Password = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "Password"), "");//解密密码Password=JRT.Core.Util.RsaUtil.RsaDecrypt(Password);//新密码String PasswordNew = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "PasswordNew"), "");//解密密码PasswordNew=JRT.Core.Util.RsaUtil.RsaDecrypt(PasswordNew);String ret=Login().ChangePassword(UserCode,Password,PasswordNew);if(ret.isEmpty()){//修改密码日志SaveUserLog(UserCode,"UP","修改密码");return Helper.Success();}else{return Helper.Error(ret);}}/*** 保存用户日志* @param UserCode* @param LogType* @param Remark* @throws Exception*/private void SaveUserLog(String UserCode,String LogType,String Remark) throws Exception{//登录类型String LoginType=Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "LoginType"), "LIS");JRTUserLog log=new JRTUserLog();log.AddDate= Helper.GetNowDate();log.AddTime=Helper.GetNowTime();log.IPAddress=Helper.GetClientIP(Request);log.LogType=LogType;log.Remark=Remark;log.Site=IPMacUtil.GetLocalIPv4Address();log.SysCode=LoginType;log.UserCode=UserCode;EntityManager().Save(log);}/*** 得到修改密码信息* @return*/public String GetChangePassInfo() throws Exception{//用户名String UserCode = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "UserCode"), "");int changePassDay=-1;//查询系统参数SYSParameter dto = EntityManager().GetByColVal(SYSParameter.class, "Code", "SYSChangePassDay");if (dto != null) {if (dto.ParaValue != null && !dto.ParaValue.isEmpty()) {changePassDay=Integer.valueOf(dto.ParaValue);}}//要求定期换密码if(changePassDay>0){HashParam hs=new HashParam();hs.Add("UserCode",UserCode);hs.Add("LogType","UP");//按日期倒序取top1List<JRTUserLog> logLast=EntityManager().FindAllTop(JRTUserLog.class,1,hs,"AddDate desc","",null,null);//没日志插入一个if(logLast==null||logLast.size()==0){//修改密码日志SaveUserLog(UserCode,"UP","修改密码");return "";}//超期没改密码if(TimeParser.DaysBetween(Helper.GetNowDate(),logLast.get(0).AddDate)>changePassDay){return "系统已开启密码天数检测:系统检测到您的密码已经超过"+changePassDay+"天未修改";}}return "";}}
为了提高效率会用M方法把所有表的实体、后台、前端代码统一生成到Copy目录供开发拷贝表操作和界面的基础逻辑
这些功能在PostGreSql和人大金仓跑起来是一样的,因为没使用SQL,都是基于ORM的api实现的功能。之所以用IRIS开发是因为表结构来回调整直接k表数据方便,效率还是很重要的,jrtlis计划的最终目标将以此开发质控系统、鉴定过程、检验系统。
相关文章:

JRT菜单
上一章搭建了登录界面的雏形和抽取了登录接口。给多组使用登录和菜单功能提供预留,做到不强行入侵别人业务。任何产品只需要按自己表实现登录接口后配置到容器即可共用登录界面和菜单部分。最后自己的用户关联到JRT角色表即可。 登录效果 这次构建菜单体系 首先用…...

《海王2》观后感
前言 我原本计划电影上映之后,去电影院观看的,但时间过得飞快,一眨眼这都快4月份了,查了一下,电影院早就没有排片了,所以只能在B站看了,这里不得不吐槽一下,原来花了4块钱购买观看还…...

[蓝桥杯 2023 省 A] 颜色平衡树:从零开始理解树上莫队 一颗颜色平衡树引发的惨案
十四是一名生物工程的学生,他已经7年没碰过信息学竞赛了,有一天他走在蓝桥上看见了一颗漂亮的颜色平衡树: [蓝桥杯 2023 省 A] 颜色平衡树 - 洛谷 十四想用暴力解决问题,他想枚举每个节点,每个节点代表…...

maya打开bvh脚本
目录 maya打开脚本编辑器 运行打开bvh脚本 maya导出bvh脚本 maya打开脚本编辑器 打开Maya软件,点击右下角 “脚本编辑器” 运行打开bvh脚本 https://github.com/jhoolmans/mayaImporterBVH/blob/master/bvh_importer.py import os import re from typing impo…...

【JavaSE】数据类型和运算符
前言 从这一篇我们开始Java的学习~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 Java第一个程序 字面常量 字面常量的分类 结合代码理解 类型转换 类型提升 byte与byte的运算 正确写法 字符串类型St…...

Docker 哲学 - ip 的组成规则 与 网关介绍
在 IP 地址中,我们通常将 IP 地址分为两部分:网络部分和主机部分。网络部分用于标识网络,主机部分用于标识该网络中的特定主机。 IP 地址的每个部分(也被称为一个八位组或一个字节)可以是从0到255的任何值。 一个 IPv4…...

数学建模竞赛真的是模型解题一般,但是论文出彩而获奖的吗?
最近,数乐君发现有同学会有这样的问题:在数学建模国赛中,会因为参赛团队的模型解题一般,但论文写得非常精彩而获奖吗? 是的,确实会存在这样的情况。 我们都知道数学建模竞赛最终都是以提交成品论文的形式…...

深度学习常见的三种模型
深度学习模型实际上是一个包含多个隐藏层的神经网络,目前主要有卷积神经网络(CNN)、深度置信网络(DBN)、循环神经网络(RNN)。 1) 卷积神经网络 在机器学习领域,卷积神经网络属于前…...

接口自动化测试分层设计与实践总结
🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号:互联网杂货铺,回复1 ,免费获取软件测试全套资料,资料在手,涨薪更快 接口测试三要素: 参数构造 发起请求&#x…...

集合(下)Map集合的使用
文章目录 前言一、Map接口二、Map接口的实现类 1.HashMap类2.TreeMap类总结 前言 Map集合没有继承Collection接口,不能像List集合和Set集合那样直接使用Collection接口的方法。Map集合其自身通过以key到value的映射关系实现的集合,也有相应的许多方法。类…...

AAPT: error: resource android:attr/dialogCornerRadius not found.
ERROR:D:\android.gradle\caches\transforms-3\b3b98118f65da38d0ad9da84cfc70a72\transformed\appcompat-1.0.0\res\values-v28\values-v28.xml:5:5-8:13: AAPT: error: resource android:attr/dialogCornerRadius not found. 请帮我看看这个错误是什么意思。我改如何做。 这个…...

数字功放VS模拟功放,选择适合你的音频解决方案
数字功放和模拟功放是音频系统中常用的两种功放技术,适用于不同的音频应用,都具有各自的优势和特点。本文将为您详细介绍数字功放和模拟功放的差异,并帮助您找到适合自己的音频解决方案。 1、数字功放是一种利用数字信号处理技术的功放。它将…...

5.88 BCC工具之tcpsynbl.py解读
一,工具简介 tcpsynbl工具以直方图的形式显示SYN到达时的TCP SYN积压大小。这可以让我们了解应用程序距离达到积压限制并丢弃SYN(导致SYN重传产生性能问题)还有多远。 TCP SYN 数据包则通常用于启动 TCP 三次握手过程的第一次握手。 二,代码示例 #!/usr/bin/env python…...

GVRP实现vlan的自动创建和注册
拓扑图 资源已上传 流程 第一、每台交换机的全局及端口下使能GVRP功能 第二、配置交换机的二层连通性,交换机某些端口配置Trunk端口,并允许相应的vlan通过 第三、在交换机4和5配置静态vlan100,然后查看1和3交换机是否有vlan100的定义&…...

Oracle VM VirtualBox修改磁盘大小
一、 修改虚拟机磁盘大小 先把虚拟机停掉。再增加磁盘大小。 路径中有空格的用""包起来。 D:\Program Files\Oracle\VirtualBox>VBoxManage.exe modifyhd "D:\Program Files\VirtualBox VMs\mycentos\mycentos.vdi" --resize 30000 0%...10%...20%...3…...

【嵌入式硬件】步进电机
1.步进电机简介 1.1步进电机基本原理 步进电机的英文是stepping motor。step的中文意思是行走、迈步。所以仅从字面上我们就可以得知,步进电机就是一步一步移动的电动机。说的官方一点儿,步进电机是一种将电脉冲信号转换成相应角位移或者线位移的电动机(直线电机)。下图为…...

FlyControls 是 THREE.js 中用于实现飞行控制的类,它用于控制摄像机在三维空间中的飞行。
demo演示地址 FlyControls 是 THREE.js 中用于实现飞行控制的类,它用于控制摄像机在三维空间中的飞行。 入参: object:摄像机对象,即要控制的摄像机。domElement:用于接收用户输入事件的 HTML 元素,通常…...

【Java程序设计】【C00366】基于(JavaWeb)Springboot的纹理生产图片系统(有论文)
TOC 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,博客中有上百套程序可供参考,欢迎共同交流学习。 项目简介 项目获取 🍅文末点击卡片…...

编译原理Lab. 1 初代编译器实验说明和要求
目录 Lab. 1 初代编译器实验说明和要求一、初代编译器功能描述二、初代编译器文法要求三、初代编译器测试样例四、初代编译器提交要求五、初代编译器实验测试框架说明 代码与思路 Lab. 1 初代编译器实验说明和要求 一、初代编译器功能描述 初代编译器将 C 语言顺序语句序列翻…...

python判断工作日,节假日
一、概述 需要判断一个日期是否为工作日,节假日。 找到一个现成的插件,蛮好用的。 插件介绍 https://pypi.org/project/chinesecalendar/ 判断某年某月某一天是不是工作日/节假日。 支持 2004年 至 2020年,包括 2020年 的春节延长。 兼容…...

练习4-权重衰减(李沐函数简要解析)
环境:练习1的环境 代码详解 0.导入库 import torch from torch import nn from d2l import torch as d2l1.初始化数据 这里初始化出train_iter test_iter 可以查一下之前的获取Fashion数据集后的数据格式与此对应 n_train, n_test, num_inputs, batch_size 20, 100, 200, …...

websocket 中 request-line 中的URI编码问题
首先,request-line组成如下: Request-Line Method SP Request-URI SP HTTP-Version CRLF 在 rfc6455 规范的 5.1.2 Request-URI 中,有这样的描述: The Request-URI is transmitted in the format specified in section 3.2.1. …...

为何ChatGPT日耗电超50万度?
看新闻说,ChatGPT每天的耗电量是50万度,国内每个家庭日均的耗电量不到10度,ChatGPT耗电相当于国内5万个家庭用量。 网上流传,英伟达创始人黄仁勋说:“AI的尽头是光伏和储能”,大佬的眼光就是毒辣ÿ…...

__init__.py 的作用
在 Python 中,包含一个名为 __ init __.py 的文件的目录被称为一个包(package)。 __ init __.py 文件的作用有以下几点: 指示包含该文件的目录是一个 Python 包:当 Python 导入一个包时,会查找该包所在目录…...

Redis到底是多线程还是单线程?
Redis6.0之前:是单线程模式。 Redis6.0之后:Redis的IO线程是多线程,worker线程是单线程。 Redis6.0之前:单线程 Redis6.0之后:Redis的IO线程是多线程,worker线程是单线程。...

JAVA 100道题(18)
18.实现一个除法运算的方法,能够处理被除数为零的情况,并抛出异常。 在Java中,你可以创建一个除法运算的方法,该方法接受两个整数作为参数,分别代表被除数和除数。如果被除数为零,你可以抛出一个自定义的异…...

【C++】每日一题 137 只出现一次的数字
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 #include <vector>int singleNumber(std::vecto…...

RAG进阶笔记:RAG进阶
1 查询/索引部分 1.1 层次索引 创建两个索引——一个由摘要组成,另一个由文档块组成分两步进行搜索:首先通过摘要过滤出相关文档,接着只在这个相关群体内进行搜索 1.2 假设性问题 让LLM为每个块生成一个假设性问题,并将这些问…...

《论文阅读》带边界调整的联合约束学习用于情感原因对提取 ACL 2023
《论文阅读》带边界调整的联合约束学习用于情感原因对提取 前言简介Clause EncoderJoint Constrained LearningBoundary Adjusting损失函数前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《Joint Cons…...

【微服务】接口幂等性常用解决方案
一、前言 在微服务开发中,接口幂等性问题是一个常见却容易被忽视的问题,同时对于微服务架构设计来讲,好的幂等性设计方案可以让程序更好的应对一些高并发场景下的数据一致性问题。 二、幂等性介绍 2.1 什么是幂等性 通常我们说的幂等性&…...