JRT菜单

news2024/9/9 4:41:56

上一章搭建了登录界面的雏形和抽取了登录接口。给多组使用登录和菜单功能提供预留,做到不强行入侵别人业务。任何产品只需要按自己表实现登录接口后配置到容器即可共用登录界面和菜单部分。最后自己的用户关联到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 字符串
     */
    @Trans
    public 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
     */
    @Trans
    public 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());
        //显示的服务器IP
        String 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);
        //会话ID
        String 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");
            //按日期倒序取top1
            List<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计划的最终目标将以此开发质控系统、鉴定过程、检验系统。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

迭代器模式(统一对集合的访问方式)

目录 前言 UML plantuml 类图 实战代码 Iterator ArrayList Client 自定义迭代器 TreeNode TreeUtils Client 前言 在实际开发过程中&#xff0c;常用各种集合来存储业务数据并处理&#xff0c;比如使用 List&#xff0c;Map&#xff0c;Set 等等集合来存储业务数…

MyBatis是纸老虎吗?(七)

在上篇文章中&#xff0c;我们对照手动编写jdbc的开发流程&#xff0c;对MyBatis进行了梳理。通过这次梳理我们发现了一些之前文章中从未见过的新知识&#xff0c;譬如BoundSql等。本节我想继续MyBatis这个主题&#xff0c;并探索一下MyBatis中的缓存机制。在正式开始梳理前&am…

Python自动化测试环境搭建

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 请事先自行安装好​​Pycharm​​​软件哦&#xff0c;我…

【Python系列】获取字符串的长度

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Clip Converter - 视频在线下载方法

Clip Converter - 视频在线下载方法 1. Video URL to Download2. Continue3. StartReferences YT to MP4 & MP3 Converter! https://www.clipconverter.cc/ Clip Converter is a free online media conversion application, which allows you to reocord, convert and do…

基于冠豪猪优化器(CPO)的无人机路径规划

该优化算法是2024年新发表的一篇SCI一区top论文具有良好的实际应用和改进意义。一键运行main函数代码自动保存高质量图片 1、冠豪猪优化器 摘要&#xff1a;受冠豪猪(crest Porcupine, CP)的各种防御行为启发&#xff0c;提出了一种新的基于自然启发的元启发式算法——冠豪猪…

#Linux系统编程(ps和kill命令)

&#xff08;一&#xff09;发行版&#xff1a;Ubuntu16.04.7 &#xff08;二&#xff09;记录&#xff1a; &#xff08;1&#xff09;ps命令 可以列出系统中当前运行的那些进程。 命令格式&#xff1a;ps 参数(常用-aux) 命令功能&#xff1a;用来显示当前进程的状态 常…

应急响应实战笔记04Windows实战篇(2)

第2篇&#xff1a;蠕虫病毒 0x00 前言 ​ 蠕虫病毒是一种十分古老的计算机病毒&#xff0c;它是一种自包含的程序&#xff08;或是一套程序&#xff09;&#xff0c;通常通过网络途径传播&#xff0c;每入侵到一台新的计算机&#xff0c;它就在这台计算机上复制自己&#xff…

Star 5.3k!纯Python开发的高效SQL 解析器!

目前从事大数据相关的开发&#xff0c;都离不开SQL&#xff0c;不管是关系型数据库还是非关系型数据&#xff0c;在做不同数据库间迁移或者转换的时候都会用到SQL转换。今天来为大家分享一个有趣的开源项目&#xff0c;SQLGlot&#xff0c;一个纯Python开发的SQL转换器&#xf…

VMware扩容硬盘

最近研究Oracle的备份导入导出功能&#xff0c;但是因为磁盘容量不够导致表空间的扩容没办法&#xff0c;从而没办法导入数据库的dmp文件。得想办法先扩容磁盘容量。话不多说上截图操作。 操作环境&#xff1a;VMware10 , Centos 6.9 VMware扩容硬盘步骤 一、关闭虚拟机&…

sizeof和strlen的使用及差异

sizeof 1.sizeof是操作符 2.sizeof计算操作数所占内存的大小&#xff0c;单位是字节&#xff08;byte&#xff09; 3.sizeof不关注内存中存放什么数据 4.sizeof比较通用不挑类型 strlen 1.strlen是库函数&#xff0c;使用需包含头文件string.h 2.strlen是求字符串长度的&#x…

L1-2 倒数第N个字符串

本题链接&#xff1a;PTA | 程序设计类实验辅助教学平台 题目&#xff1a; 样例&#xff1a; 输入 3 7417 输出 pat 思路&#xff1a; 根据题意&#xff0c;这道题是一道思维模拟题。 给出 n 位的小写字母字符串&#xff0c;其中进制位为 26 &#xff0c;求进位1 到 倒数第 …

天工AI搜索引擎

相信正在看autosar架构相关内容的人来说&#xff0c;对于autosar相关知识或者配置项的生涩知识点可谓是苦之久矣&#xff0c;这个时候一个好的搜索引擎能带来的帮助太大了&#xff0c;不管是平时百度还是看文档都需要大量的时间去检索自己真正想知道的信息&#xff0c;偶然间发…

酒店管理系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/89036287 更多系统资源库…

Windows 频繁失去焦点分析

原文&#xff1a;https://blog.iyatt.com/?p14383 1 前言 刚才在打字的时候发现会随机失去焦点&#xff0c;然后又要用鼠标点一下正在输入的位置才能继续输入&#xff0c;特别烦。开始我怀疑是手碰到触摸板导致失去焦点&#xff0c;但是我用了差不多十年带触摸板的笔记本电脑…

Python框架篇(7):FastApi-依赖项

有时选择太多也会让人陷入焦虑&#xff0c;比如突然有一段自由时间&#xff0c;却因为想做的事情太多&#xff0c;最后把时间都浪费在了摇摆不定上&#xff0c;静不下心做最重要的事&#xff0c;或者说根本不知道最重要的事情是什么。---------- 《认知觉醒:开启自我改变的原动…

【干货】无源滤波器设计讲解,工作原理+设计步骤

今天给大家分享的是&#xff1a;无源模拟滤波器针对很多入门小白不懂滤波器设计&#xff0c;一些老工程师上班很多年有的也不懂得总结知识点&#xff0c;以及想学习不知道怎么系统学习的这一类人群&#xff0c;前方知识点来袭&#xff0c;请君放心食用~ 在信号处理领域&#x…

AXI-Stream——草稿版

参考自哔站&#xff1a;FPGA IP之AXI4-Lite AXI4-Stream_哔哩哔哩_bilibili 信号 传输层级从小到大 TKEEP和TSTRB共同决定了是哪种数据流

红外循迹,避障模块介绍

本节将介绍标题中三种模块的应用以及工作原理 上图中&#xff0c;黑色的是红外接收管&#xff0c;绿色的是红外发射管&#xff0c;他俩与发光二级管都非常像&#xff0c;但功能上却有所不同。 发光二级管&#xff1a;亮度在一定的时间内随电流的增大而增大。 红外发射管&…

Python遥感开发之解决TIF数据之间行列不一致的问题

Python遥感开发之解决TIF数据之间行列不一致的问题 1.问题如图所示2.完整代码如下所示 前言&#xff1a;主要解决在同一分辨率的情况下&#xff0c;遥感数据之间行和列数据不一致的问题。 1.问题如图所示 我们发现这两个TIF的分辨率是一样的&#xff0c;都是0.01x0.01&#xff…