精华内容
下载资源
问答
  • 若依环境使用手册;若依环境使用手册;若依环境使用手册;若依环境使用手册;若依环境使用手册;若依环境使用手册若依环境使用手册若依环境使用手册
  • 若依开发手册前端Validate相关时间格式化相关修改回显Table展示Bootstarp相关BootStarpTable设置默认排序列Table增加减少功能选项单页面全局Table根据字典匹配相应的值创建新的标签页调用方法input select锁定add...

    这篇布局太乱看着太累了 重新把为文档布局调整了一下 之后的更新内容会在新地址发布:
    [https://blog.csdn.net/weixin_42059737/article/details/98873972]
    更新频率为3天/7天

    2019-12-24
    这是最后在这个帖子更新 后续只会在新地址更新了
    这边文章目的是可以让你会复制粘贴代码就能用 即便有需要要阅读的 也会把阅读的关键点指出 方便理解 需要代码的地方也是能把无用代码能缩减就缩减 一般不会贴臃肿难读的代码上来 推荐小伙伴进入新地址食用

    首页

    作者

    💘 :青衫

    ✉️ :2940500@qq.com

    🚀 : 点击进入文档实时更新地址-码云

    前言:

    💥接触若依也很长时间了从1.0到现在的4.0 期间一直想写个手册 但一直没有很好地切入点 最近在开发新系统 正好根据开发中遇到或者使用到的内容作为切入点来进行写文档 可能会有些混乱 一开始先写上准备后续再排版精修 推荐Git拉取,方便文档实时更新

    CSDN过来的同学注意 文档已经停止在CSDN的维护 (继续维护到CSDN吧 看CSDN有很多小伙伴在看)

    这篇文章一开始是为了若依框架而写 写着写着发现有很多地方超纲了 有些开发中遇到的小技巧什么的也会在这里补充下 可能你不用若依框架 也能用到该文章 比如回显浏览器选中图片 鼠标悬浮自动放大缩略图等等(后续看情况提取成独立文章)

    目录结构:

    大致分为前端、后端,前端根据使用的页面add、edit、list来进行详细划分,后端根据三层加上其他特殊内容点划分

    前端

    add.html

    下拉列

    // 1 其中t_vip_user_details_vip_type 为字典表的字典类型 可前往-系统管理-->字段管理 --> 添加新的字典
    <div class="form-group">
                <label class="col-sm-3 control-label">VIP用户类别:</label>
                <div class="col-sm-8">
                    <select id="xxxxx" name="xxxxx" class="form-control m-b"
                            th:with="type=${@dict.getType('t_vip_user_details_vip_type')}">
                        <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
                    </select>
                </div>
            </div>
    
    
    // 2 取非字典的数据(model)
            <div class="form-group">
                <label class="col-sm-3 control-label">司机:</label>
                <div class="col-sm-8">
    		<select id="xxxx" name="xxxx" class="form-control m-b">
                  <option value="">--请选择(非必选)--</option>
                  <option th:each="xxxx : ${xxxxList}" th:text="${xxxx.name}" th:value="${xxxx.id}"></option>
            </select>
                </div>
            </div>
    
    //3 使下拉列带有搜索功能:引入该JS即可
    https://www.cnblogs.com/tianxinyu/p/9988763.html
    
    select的class样式为
    <div th:include="include::footer"></div>
    // 该JS需要在include下方
    <script th:src="@{/ajax/libs/select/select2.js}"></script>
    

    时间框

    <div class="form-group">
        <label class="col-sm-3 control-label">设备到期时间:</label>
        <div class="col-sm-8">
            <div class="input-group date">
               <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
               <input name="xxxxx" class="time-input" placeholder="yyyy-MM-dd" type="text">
            </div>
        </div>
    </div>
    

    大文本框

    <textarea name="content" style="width: 762px ;margin: 0px; height: 295px;"></textarea>
    
    

    Ajax校验

     $("#form-motorman-add").validate({
            rules: {
                name: {
                    required: true,
                },
                identityCard: {
                    required: true,
                    isIdentity: true,
                    remote: {
                        url: ctx + "iot/motorman/checkIdentityCard",
                        type: "post",
                        dataType: "json",
                        data: {
                            name: function () {
                                return $.common.trim($("#identityCard").val());
                            },
                            id: ''
                        },
                        dataFilter: function (data, type) {
                            return $.validate.unique(data);
                        }
                    }
                },
                contactPhone: {
                    required: true,
                    isPhone: true
                },
            },
            messages: {
                "identityCard": {
                    remote: "身份证号已存在"
                },
            }
        });
    
    		/**
    		 * 校验身份证
    		 */
    		@PostMapping("/checkIdentityCard")
    		@ResponseBody
    		public Integer checkIdentityCard(String identityCard, Integer id)
    		{
                // 存在
                return CommonEnum.EXIST.getCode();
                // 不存在
                return CommonEnum.EXIST.NOT_EXIST();
            }
    
    package com.ruoyi.common.constant;
    import lombok.Getter;
    /**
     * @author: [青衫] 'QSSSYH@QQ.com'
     * @Date: 2019-08-08 10:24
     * @Description: < 通用校验是否存在返回状态码 >
     */
    @Getter
    public enum CommonEnum
    	{
    		/**
    		 * 用户是否存在返回码
    		 */
    		EXIST(1, "存在"), NOT_EXIST(0, "不存在");
    		private Integer code;
    		private String msg;
    
    		CommonEnum(Integer code, String msg)
    			{
    				this.code = code;
    				this.msg = msg;
    			}
    	}
    
    

    自定义校验

    jQuery.validator.addMethod("isAllNumber", function (value, element) {
            var loginName = $("#loginName").val();
            var patrn = /^[0-9]*$/;
            if (patrn.test(loginName)) {
                return false;
            } else {
                return true;
            }
        }, "用户名不能为纯数字");
    
    
    $("#form-product-edit").validate({
            rules: {
                    loginName: {
                    required: true,
                    // 自定义属性 属性名要和上方的一参一样
                    isAllNumber: true,
                },
            
            }
        });
    

    成功截图

    回显选中图片

    在下方已经写过了

    路径:前端 --> 其他 --> 回显选中图片

    如果需要放大回显图片可以看

    前端 --> 其他 --> 放大图片

    edit.html

    下拉列

      <div class="form-group">
                <label class="col-sm-3 control-label">性别:</label>
                <div class="col-sm-8">
                    <select id="xxx"  name="xxx" class="form-control m-b" th:with="type=${@dict.getType('sys_user_sex')}">
                        <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{sex}"></option>
                    </select>
                </div>
            </div>
    

    回显时间

    	<div class="form-group">
                <label class="col-sm-3 control-label">合同到期日期:</label>
                <div class="col-sm-8" >
                    <input id="xxxxxx" name="xxxxxx" class="time-input" type="text" readonly   th:value="${#dates.format(xx.xxxxxx,'yyyy-MM-dd HH:mm:ss')}">
                </div>
            </div>
    




    list.html

    搜索栏

    下拉列

    <li>
       用户状态:<select name="status" th:with="type=${@dict.getType('sys_normal_disable')}">
                	<option value="">所有</option>
               		<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
               </select>
    </li>
    
    
    //2: 下拉列带搜索功能 主要是select class加了form-control 属性
    // 然后引入 <script th:src="@{/ajax/libs/select/select2.js}"></script>
       
    <li style="width: 280px;">
        <p>设备类别: </p>
         <select name="equipmentType" id="equipmentType" th:with="type=${@dict.getType('t_equipment_equipment_type')}" class="form-control">
           <option value="">所有</option>
             <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
          </select>
        </li>
    
    

    sys_normal_disable值位置

    sys_normal_disable 为字典类型值 字典类型值一般为表名字段名来命名防止出现重复

    时间框

    根据开始时间结束时间搜索

    如果使用的是MybatisPlus版本 注意后台接收数据需要创建Vo对象 或者直接使用Map对象来进行接收开始时间结束时间 不然会报错的哈

    **Html: **

    <li class="select-time">
    	<label>创建时间: </label>
        	<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginTime]"/>
        <span>-</span>
              <input type="text" class="time-input" id="endTime" placeholder="结束时间"name="params[endTime]"/>
    </li>
    

    Vo:

    注意set get方法和普通实体类有区别

    这么写的原因是防止前端没有传入开始时间和结束时间

    然后mapper.xml 这样去判断就会报错 因为params是null 可以在这个判断外边再加一层if判断params是否为空即可解决 但还是推荐 下边这种方式写get set方法

    		/** 请求参数 */
    		private Map<String, Object> params;
    		/** get()*/
    		public Map<String, Object> getParams(){if (params == null){params = new HashMap<>();}return params;}
    		/** set() */
    		public void setParams(Map<String, Object> params){this.params = params;}
    

    mapper.xml:

    <if test="params.beginTime != null and params.beginTime !=''"><!-- 开始时间检索 -->
          AND date_format(xxxxx,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
    </if>
    
    <if test="params.endTime != null and params.endTime  !='' "><!-- 结束时间检索 -->
          AND date_format(xxxxx,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
     </if>
    

    Table表格

    刷新表格

    // 这是封装好的方法  不需要在去调用原生的JS了
    $.table.refresh();
    

    按钮颜色

    后边加上 btn-xs 样式会使按钮缩小

    	深蓝色    btn btn-primary
    ​	浅蓝色    btn btn-info
    ​	绿色     	btn btn-success
    ​	黄色      btn btn-warning
    ​	红色      btn btn-danger
    ​	透明      btn btn-link
    ​	默认		btn btn-default
    
    

    输入图片说明

    关于徽章

    参考文章

    https://www.cnblogs.com/xiaohuochai/p/7113645.html

    http://www.360doc.com/content/19/0429/22/59156820_832398875.shtml

    格式化时间

    		/** 合同创建日期 */
    		@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")
    		private Date contractCreateTime;
    

    前端

    th:value="*{#dates.format(reserveTime,'yyyy-MM-dd HH:mm:ss')}"
    

    设置默认排序列

    sortName: 'createTime',
    sortOrder: "desc",
    

    例:

    输入图片说明

    表格匹配字典值

     var userType = [[${@dict.getType('sys_user_user_type')}]];
    
     // 在table相关属性字段的操作
         {
             field: 'userType',
             title: '类型',
             align: "left",
             formatter: function (value, item, index) {
             return $.table.selectDictLabel(userType, value);
             }
          },
    

    表格增加.减少功能项

    单页

    若依的table是用BootstarpTable 而且若依也BootStarpTable简单封装了 如果想要去掉 table右上角的 下载 列表刷新搜索 几个按钮该怎么做呢?也很简单 增加这几个的属性该并为false即可:

    输入图片说明

    全局

    找到 ry-ui.js 将这几个属性设置为false即可

    输入图片说明





    其他

    JS循环

    添加个链接这个博主写的很详细

    https://blog.csdn.net/qq_41899174/article/details/82797089

    放大图片

    有时候为了页面美观显示的图片比较小 只能看到缩略图 但是在某些情况下又想看到放大后的图片 这时候就需要图片放大功能了 layui的就不介绍了 这里介绍两种其他的

    • 放大镜方法图片(鼠标悬浮在缩略图上就可以放大)
    • 弹出层放大图片(点击弹出遮罩层,放大图片)

    放大镜放大:

    使用 jQuery Zoom Plugin插件

    github: https://github.com/elevateweb/elevatezoom

    文档地址: https://www.myfreax.com/elevatezoom-image-zoom/

    Html

    <img id="zoom_01" src='images/small/image1.png' data-zoom-image="images/large/image1.jpg"/>
    <!-- src 指向的是缩略图 data-zoom-image指向的是大图 (可以指向同一个图片 设置当前img的宽高缩小显示图片 当鼠标悬浮就会显示未缩小的图片了)-->
    

    JQuery

    有六种显示效果 根据需要选择 推荐第一种 如果需要可以访问文档看它的其他属性

    
    $('#zoom_01').elevateZoom({});//默认效果 
     
    $('#zoom_01').elevateZoom({ //内置镜头 
        zoomType: "inner",//类型:内置镜头 
        cursor: "crosshair", //光标:十字 
        zoomWindowFadeIn: 500,//镜头窗口淡入速度 
        zoomWindowFadeOut: 750 //镜头窗口淡出速度 
    }); 
     
    $("#zoom_01").elevateZoom({ //镜头聚焦 
        zoomType: "lens",//类型:透镜效果 
        lensShape: "round", //透镜形状:圆形 
        lensSize: 200 //透镜尺寸:长和宽:200px 
    }); 
     
    $("#zoom_01").elevateZoom({ //淡入/淡出设置 
        zoomWindowFadeIn: 500,//镜头窗口淡入速度 
        zoomWindowFadeOut: 500,//镜头窗口淡出速度 
        lensFadeIn: 500,//透镜淡入速度 
        lensFadeOut: 500//透镜淡出速度 
    }); 
     
    $("#zoom_01").elevateZoom({ //动画 
        easing: true //是否开启动画效果 
    }); 
     
    $("#zoom_01").elevateZoom({ //鼠标滚动 
        scrollZoom: true //是否开启鼠标滚动 
    });
    

    弹出层放大:

    这个就是弹出一个遮罩层 显示图片 没什么好说的直接是上代码吧

    原文链接: https://blog.csdn.net/m0_37865510/article/details/84636488

    缩略图位置:

    注意class为:pimg 下边会用到 
    <img  src='images/image1.png'  class="pimg"/>
    

    在html最下边 添加下边这一段代码(遮罩层)

    注意:z-index:2; 为遮罩层显示的高度如果想显示在最上层直接将2改为9999就行了

    <div id="outerdiv" style="position:fixed;top:0;left:0;background:rgba(0,0,0,0.7);z-index:2;width:100%;height:100%;display:none;">
        <div id="innerdiv" style="position:absolute;">
            <img id="bigimg" style="border:5px solid #fff;" src="" />
        </div>
    </div>
    

    JS:

    <script>  
        $(function(){  
            $(".pimg").click(function(){  
                var _this = $(this);//将当前的pimg元素作为_this传入函数  
                imgShow("#outerdiv", "#innerdiv", "#bigimg", _this);  
            });  
        });  
     
        function imgShow(outerdiv, innerdiv, bigimg, _this){  
            var src = _this.attr("src");//获取当前点击的pimg元素中的src属性  
            $(bigimg).attr("src", src);//设置#bigimg元素的src属性  
          
                /*获取当前点击图片的真实大小,并显示弹出层及大图*/  
            $("<img/>").attr("src", src).load(function(){  
                var windowW = $(window).width();//获取当前窗口宽度  
                var windowH = $(window).height();//获取当前窗口高度  
                var realWidth = this.width;//获取图片真实宽度  
                var realHeight = this.height;//获取图片真实高度  
                var imgWidth, imgHeight;  
                var scale = 0.8;//缩放尺寸,当图片真实宽度和高度大于窗口宽度和高度时进行缩放  
                  
                if(realHeight>windowH*scale) {//判断图片高度  
                    imgHeight = windowH*scale;//如大于窗口高度,图片高度进行缩放  
                    imgWidth = imgHeight/realHeight*realWidth;//等比例缩放宽度  
                    if(imgWidth>windowW*scale) {//如宽度扔大于窗口宽度  
                        imgWidth = windowW*scale;//再对宽度进行缩放  
                    }  
                } else if(realWidth>windowW*scale) {//如图片高度合适,判断图片宽度  
                    imgWidth = windowW*scale;//如大于窗口宽度,图片宽度进行缩放  
                                imgHeight = imgWidth/realWidth*realHeight;//等比例缩放高度  
                } else {//如果图片真实高度和宽度都符合要求,高宽不变  
                    imgWidth = realWidth;  
                    imgHeight = realHeight;  
                }  
                        $(bigimg).css("width",imgWidth);//以最终的宽度对图片缩放  
                  
                var w = (windowW-imgWidth)/2;//计算图片与窗口左边距  
                var h = (windowH-imgHeight)/2;//计算图片与窗口上边距  
                $(innerdiv).css({"top":h, "left":w});//设置#innerdiv的top和left属性  
                $(outerdiv).fadeIn("fast");//淡入显示#outerdiv及.pimg  
            });  
              
            $(outerdiv).click(function(){//再次点击淡出消失弹出层  
                $(this).fadeOut("fast");  
            });  
        }  
    </script>
    

    新建标签页

    若依已经对创建新的标签页已经进行封装 JS方法为: createMenuItem()

    使用:

    // 要打开的地址
    var url=prefix+"/details?userId="+userId;
    
    // 调用createMenuItem()方法 1参:要打开的地址 ,2参:标签页名称
    createMenuItem(url, "用户详情");
    

    注意:

    1. 如果提示调用createMenuItem of undefined 那就记得引入这个common.js生成的代码里默认会引入
    2. 提示random of undefined 就引入ry-ui.js
    <script th:src="@{/ruoyi/js/common.js?v=3.2.0}"></script>
    
    <script th:src="@{/ruoyi/js/ry-ui.js?v=3.2.0}"></script>
    

    方法源代码:

    源代码就不贴出来了 贴出来也没什么意义 位置:

    common.js  -->  createMenuItem(dataUrl, menuName)
    

    关闭标签页

    // 源代码在index.js里
      $('.tabCloseCurrent').on('click', function () {
            $('.page-tabs-content').find('.active i').trigger("click");
        });
    

    输入框锁定

    这个相信大家都会 还是再写一下吧 这段话是从网站上直接复制过来的

    disabled 属性规定应该禁用 input 元素,被禁用的 input 元素,不可编辑,不可复制,不可选择,不能接收焦点,后台也不会接收到传值。设置后文字的颜色会变成灰色。disabled 属性无法与

    //disabled 属性无法与 <input type="hidden">一起使用。
    示例:<input type="text" disabled="disabled" />
    

    readonly 属性规定输入字段为只读可复制,但是,用户可以使用Tab键切换到该字段,可选择,可以接收焦点,还可以选中或拷贝其文本。后台会接收到传值. readonly 属性可以防止用户对值进行修改。

    // readonly 属性可与 <input type="text"> 或 <input type="password"> 配合使用。
    示例:<input type="text" readonly="readonly">
    

    readonly unselectable=“on” 该属性跟disable类似,input 元素,不可编辑,不可复制,不可选择,不能接收焦点,设置后文字的颜色也会变成灰色,但是后台可以接收到传值。

    示例:<input type="text"  readonly  unselectable="on" >
    

    弹出某页面

    弹窗

    // 弹出添加用户积分日志页面
    function open_account_log(userId) {
        // 调用方法弹出
        $.modal.open("用户积分修改", '/system/accountDetailsLog/add');
    }
    

    JS校验空值

    function isEmpty(obj){
        if(typeof obj == "undefined" || obj == null || obj == ""){
            return true;
        }else{
            return false;
        }
    }
    

    自定义AJAX

    这里是使用解绑按钮来进行示例

    解绑操作不需要弹窗 如果直接调用封装好的修改的方法或者操作成功处理操作成功的方法会关闭弹窗刷新父级页面 导致全局刷新 这样写就可以 既可以向后台执行想要执行的操作 也可以弹出消息提醒 又不导致全局刷新 只刷新Table表格

      // 上传文件
                function sendFile(file, obj) {
                    var data = new FormData();
                    data.append("file", file);
                    $.ajax({
                        type: "POST",
                        url: ctx + "common/upload",
                        data: data,
                        cache: false,
                        contentType: false,
                        processData: false,
                        dataType: 'json',
                        success: function (result) {
                            if (result.code == web_status.SUCCESS) {
                                $(obj).summernote('editor.insertImage', result.url, result.fileName);
                            } else {
                                $.modal.alertError(result.msg);
                            }
                        },
                        error: function (error) {
                            $.modal.alertWarning("图片上传失败。");
                        }
                    });
                }
    

    添加Class元素

     .abc{
      background: red;
      }
    test div
        var div = document.getElementById('d1');
        div.classlist.add("abc");      //添加
        div.classlist.remove("abc");   //删除
    

    操作结果提示

    // 需要引入 ry-ui.js文件 content为提示文字
    <script th:src="@{/ruoyi/js/ry-ui.js?v=3.2.0}"></script>
    
    // 错误
      $.modal.msg(content, modal_status.FAIL);
    // 成功
     $.modal.msg(content, modal_status.SUCCESS);
    

    回显选中图片

    如果需要放大回显图片可以看

    前端 --> 其他 --> 放大图片

    回显浏览器选中的图片

    如果在选择文件的时候,只想显示图片文件可以这样写

    <input type="file" accept="image/*">
    

    HTML示例:

        <div class="form-group">
           <label class="col-sm-3 control-label">主图:</label>
            <div class="col-sm-8">
             	<input id="file" name="mainImageA" class="filepath" onchange="changepic(this)" type="file"><br>
             	<img src="" id="show" width="200">
            </div>
            </div>
    

    JS:

      function changepic(obj) {
            var reads = new FileReader();
            f = document.getElementById('file').files[0];
            reads.readAsDataURL(f);
            reads.onload = function (e) {
                document.getElementById('show').src = this.result;
            };
        }
    

    JS创建集合对象

    // js中创建集合
    var list=[];
    // js中创建cs对象
    var cs = {
        id=1,
        name='admin',
        password='admin'
    }
    //保存对象
    list.push( cs );
    

    显示隐藏HTML

    <span id='vip_user_input'> hello</span>
    
     var userType =2;
            if (userType == 2) {
                // 显示
                //获取要显示的div对象
                var otherDiv = document.getElementById('vip_user_input');
                //显示
                otherDiv.style.display = "block";
            } else {
                // 隐藏
                document.getElementById('vip_user_input').style.display = "none";
            }
    

    页面加载完成执行

    页面加载完成执行有两种加载时机

    1. 页面所有资源加载完成后执行 (包括图片或者其他资源)
    2. 页面的Dom结构在家完成就开始执行
    //1 资源加载完成才执行 (图片资源等等)
    window.onload = function() { 
    }; 
    
    //2 Dom加载完成就执行
    $(document).ready(function() { 
    }); 
    
    //2.1 简写
    $(function() {
    });
    
    

    默认全屏打开添加页

    <a class="btn btn-success" onclick="$.operate.addFull()" shiro:hasPermission="system:notice:add">
        <i class="fa fa-plus"></i> 新增
    </a>
    

    Thymeleaf

    标签

    关键字功能介绍案例
    th:id替换id<input th:id="'xxx' + ${collect.id}"/>
    th:text文本替换<p th:text="${collect.description}">description</p>
    th:utext支持html的文本替换<p th:utext="${htmlcontent}">content</p>
    th:object替换对象<div th:object="${session.user}">
    th:value属性赋值<input th:value = "${user.name}" />
    th:with变量赋值运算<div th:with="isEvens = ${prodStat.count}%2 == 0"></div>
    th:style设置样式<div th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''"></div>
    th:onclick点击事件<td th:onclick = "'getCollect()'"></td>
    th:each属性赋值循环<tr th:each = "user,userStat:${users}">
    th:if判断条件<a th:if = "${userId == collect.userId}">
    th:unless和th:if判断相反<a th:href="@{/login} th:unless=${session.user != null}">Login</a>
    th:href链接地址<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
    th:switch多路选择配合th:case使用<div th:switch="${user.role}">
    th:fragmentth:switch的一个分支<p th:case = "'admin'">User is an administrator</p>
    th:includ布局标签,替换内容到引入的文件<head th:include="layout :: htmlhead" th:with="title='xx'"></head>
    th:replace布局标签,替换整个标签到引入的文件<div th:replace="fragments/header :: title"></div>
    th:selectdselected选择框选中th:selected="(${xxx.id} == ${configObj.dd})"
    th:src图片类地址引入<img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" />
    th:inline定义js脚本可以使用变量<script type="text/javascript" th:inline="javascript">
    th:action表单提交的地址<form action="subscribe.html" th:action="@{/subscribe}">
    th:remove删除某个属性
    th:attr设置标签属性,多个属性可以用逗号分隔比如 th:attr=“src=@{/image/aa.jpg},title=#{logo}”,此标签不太优雅,一般用的比较少。
    1.all:删除包含标签和所有的孩子。2.body:不包含标记删除,但删除其所有的孩子。3.tag:包含标记的删除,但不删除它的孩子。4.all-but-first:删除所有包含标签的孩子,除了第一个。5.none:什么也不做。这个值是有用的动态评估。

    循环

       <tr  th:each="user,userStat : ${list}">  
                    <td th:text="${user.userName}">Onions</td>  
                    <td th:text="${user.email}">test@test.com.cn</td>  
                    <td th:text="${user.isAdmin}">yes</td>  
                     <th th:text="${userStat.index}">状态变量:index</th>  
                    <th th:text="${userStat.count}">状态变量:count</th>  
                    <th th:text="${userStat.size}">状态变量:size</th>  
                    <th th:text="${userStat.current.userName}">状态变量:current</th>  
                    <th th:text="${userStat.even}">状态变量:even****</th>  
                    <th th:text="${userStat.odd}">状态变量:odd</th>  
                    <th th:text="${userStat.first}">状态变量:first</th>  
                    <th th:text="${userStat.last}">状态变量:last</th>  
        </tr>
    

    判断

    <th:block th:if="...">
    	<div id="div1">
    	</div>
    	<div id="div2">
    	</div>
    </th:block>
    

    JS取值

    // 注意script属性
    <script th:inline="javascript">
        var message = [[${message}]];
        console.log(message);
    
    // 注意 这种也可以取值 并且取出的值为字符串类型  作用嘛
    // 举例 比如在加载页面的icon的时候 如果直接取值fa fa-user-o 就会报错  但是如果在去之前外边加上''那取出的值就是字符串类型 
          // 设置icon图标
        var one_icon = $('#one_icon');
    	// 正确赋值
        one_icon.addClass('[[${oneIcon}]]');
    	// 报错
    	one_icon.addClass([[${oneIcon}]]);
    </script>
    

    th:onclick

    传递单个参数

    th:οnclick="searchHot([[${hot.name}]])"
    

    传递多个Model中参数

    th:οnclick="'javascript:searchHot(\''+${hot.name}+'\',\''+${hot.hotType}+'\')'"
    

    传递一个Model中参数 一个非Model中参数

    th:οnclick="'javascript:searchHot(\''+${hot.name}+'\','+this+')'"
    

    格式化时间

    th:value="*{#dates.format(reserveTime,'yyyy-MM-dd HH:mm:ss')}"
    

    截取字符串

    msg.content为取出的字符串 15为截取长度
    <span th:utext="${#strings.abbreviate( msg.content,15)}"></span>
    
    其他-网络文章

    https://blog.csdn.net/zoubo0812/article/details/54906297#commentBox

    JQuery相关

    返回上页

    function goBack() {
        window.history.go(-1);
    }
    

    后端

    系统

    当前用户

    对当前登录用户的操作已经进行了封装

    有获取当前登陆用户 获取当前登录用户ID 等这里不贴源码了

    该工具类位置:

    com.ruoyi.framework.util.ShiroUtils

    定时器

    关闭定时器

    有时候定时器大家并不一定需要用到 又想把定时器阉割掉 时怎么做呢?
    难道要删大量的定时器相关代码吗? 很显然不需要只需要将定时器在启动时初始化的注解注释掉就可以了

    输入图片说明

    新增定时器

    输入图片说明

    输入图片说明

    在系统监控 --> 定时任务 -->新增定时任务

    输入图片说明





    Controller

    关于权限

    若依框架使用的是Shiro来进行权限控制

    下边介绍一下在Controller新增一个请求地址 然后使这个地址被管理需要做那些操作

    1. 添加注解
    2. 插入sql
    3. 按钮控制

    Service

    Dao

    Mapper

    属性封装

    发现一篇很有意思的关于封装返回的文章 大概看了一下 这里记录一下 有时间再看

    https://www.cnblogs.com/stefanking/articles/5092474.html

    说到Mapper不得不说一下vo封装 之前都是写一个association然后再写相应的属性的result 然后导致mapper文件 全是result

    这里介绍一下封装的时候引入本文件的其他 或其他文件里的

    POJO:

    // 继承原实体类得到原实体类的所有属性
    @Data
    public class EquipmentVo extends Equipment implements Serializable
    	{
    	//增加两个属性
    		/** 供应商 */
    		private Supplier supplier;
    
    		/** 所属用户 */
    		private SysUser sysUser;
    
    	}
    

    association 标签中的属性

    property:	vo中的属性名
    column:		该属性id对应的的字段名[非必须]
    javaType:	该属性的Java类型
    resultMap:	引入的本文件的话就是resultMap 的id
    			resultMap的id 引入其他文件的resultMap 时是xml文件所对应的Dao的全路径加					resultMap的Id
    

    ​ 例:

    注意:

    Association和Collection使用时机区别:

    Association 在一对一,多对一时使用

    Collection 在一对多,多对多时使用

    在association标签中 javaType属性指向的是实体类的属性

    在collection标签中 javaType属性指向的是集合的类型 ofType指向的是集合的泛型类型

    Mapper:

     <resultMap type="com.ruoyi.iot.domain.vo.EquipmentVo" id="EquipmentVoResult">
            <result property="id" column="id"/>
            <result property="equipmentNumber" column="equipment_number"/>
            <result property="createTime" column="create_time"/>
    
            <!-- 供应商 引入其他文件的resultMap 路径dao层路径加resultMap 的id-->
            <association property="supplier" column="s.id" javaType="com.ruoyi.iot.domain.Supplier" resultMap="com.ruoyi.iot.mapper.SupplierMapper.SupplierResult">
                <result property="createTime" column="screate_time"/>
            </association>
            <!--用户 引入当前文件resultMap-->
            <association property="sysUser" column="user_id" javaType="com.ruoyi.system.domain.SysUser" resultMap="SysUserResult">
            </association>
        </resultMap>
    
    
    <!--用户-->
        <resultMap type="com.ruoyi.system.domain.SysUser" id="SysUserResult">
            <id property="userId" column="user_id"/>
            <result property="deptId" column="dept_id"/>
            <result property="loginName" column="login_name"/>
        </resultMap>
    

    集合遍历

    单参数

    Dao:

    Integer selectEquipmentNumber(List<Integer> statusList);
    

    XML:

    <foreach collection="list" item="status" index="index" separator="or" open="(" close=")">
             equipment_status = #{item}
    </foreach>
    
    多参数:

    Dao:

    XML:

    <!-- 多参数的 collection为参数的名称 -->
    
    

    其他

    MP忽略null值

      // 修改时忽略null 和空值
        @TableField(strategy = FieldStrategy.IGNORED)
        private BigDecimal discountPrice;
    

    BigDecimal使用

    直接复制过来的就不在重复写了

    注意除法 divide 是重载的方法 如果直接 a.divide(b) 的话可能会出现该异常:

    [ Non-terminating decimal expansion; no exact representable decimal result.]

    相当于10/3 无法除尽 尽量指定小数长度和规则

    BigDecimal bignum1 = new BigDecimal("10");  
    BigDecimal bignum2 = new BigDecimal("5");  
    BigDecimal bignum3 = null;  
      
    // 加法  
    bignum3 =  bignum1.add(bignum2);       
    System.out.println("和 是:" + bignum3);  
      
    // 减法  
    bignum3 = bignum1.subtract(bignum2);  
    System.out.println("差  是:" + bignum3);  
      
    // 乘法  
    bignum3 = bignum1.multiply(bignum2);  
    System.out.println("积  是:" + bignum3);  
      
    // 除法  
    bignum3 = bignum1.divide(bignum2);  
    System.out.println("商  是:" + bignum3);
    
    // 除法2
    // scale表示保留小数位数 roundingMode表示为小数模式
    divide(BigDecimal divisor, int scale, RoundingMode roundingMode) ;
    
    BigDecimal bignum3 = bignum1.divide(bignum2,10,ROUND_HALF_DOWN);
    

    小数模式常量

    ROUND_CEILING=如果 BigDecimal 是正的,则做 ROUND_UP 操作;如果为负,则做 ROUND_DOWN 操作。
    ROUND_DOWN=从不在舍弃(即截断)的小数之前增加数字。
    ROUND_FLOOR=如果 BigDecimal 为正,则作 ROUND_UP ;如果为负,则作 ROUND_DOWN 。
    ROUND_HALF_DOWN=若舍弃部分> .5,则作 ROUND_UP;否则,作 ROUND_DOWN 。
    ROUND_HALF_EVEN=如果舍弃部分左边的数字为奇数,则作 ROUND_HALF_UP ;如果它为偶数,则作ROUND_HALF_DOWN 。
    ROUND_HALF_UP=若舍弃部分>=.5,则作 ROUND_UP ;否则,作 ROUND_DOWN 。
    ROUND_UNNECESSARY=该“伪舍入模式”实际是指明所要求的操作必须是精确的,因此不需要舍入操作。
    ROUND_UP=总是在非 0 舍弃小数(即截断)之前增加数字。
    

    比较大小

    
    BigDecimal a = new BigDecimal (101);
    BigDecimal b = new BigDecimal (111);
     
    //使用compareTo方法比较
    //注意:a、b均不能为null,否则会报空指针
    if(a.compareTo(b) == -1){
        System.out.println("a小于b");
    }
     
    if(a.compareTo(b) == 0){
        System.out.println("a等于b");
    }
     
    if(a.compareTo(b) == 1){
        System.out.println("a大于b");
    }
     
    if(a.compareTo(b) > -1){
        System.out.println("a大于等于b");
    }
     
    if(a.compareTo(b) < 1){
        System.out.println("a小于等于b");
    }
    

    MYSQL

    获取时间

    mysql查询当前系统时间不保留时分秒,保留时分秒,当前时间加一天,当前时间减少一天等

    转发至CSDN 原文链接 :https://blog.csdn.net/liu_yulong/article/details/90447555

    SELECT
    	CURDATE( ),
    	now( ),
    	CURTIME( ),
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) yestorday,
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) today 
    FROM
    	DUAL;
    

    img

     
    SELECT
    	CURDATE( ) date,
    	now( ) dateTime,
    	DATE_FORMAT( now( ), '%Y-%m-%d' ) dateFmt,
    	DATE_FORMAT( now( ), '%Y-%m-%d' ) dateTimeFmt,
    	DATE_FORMAT( now( ), '%Y-%m-%d %H:%i:%s' ) daymins,
    	CURTIME( ) times,
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) Yesterday ,
    	date_sub( CURDATE( ), INTERVAL 0 DAY ) Today  ,
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) Tomorrow 
    FROM
    	DUAL;
    

    img

    展开全文
  • simulink的官方使用手册,适合新手入门学习,内容非常全,可作为参考手册来使用。希望对大家有用。
  • pycharm使用手册

    2018-03-12 14:04:43
    python,代码编辑器,使用手册。pycharm,开发软件,编辑器
  • STM32F1_HAL库使用手册

    2018-04-10 14:41:13
    STM32F1_HAL库使用手册 详细介绍说stm32最新库hal库和l库
  • 建议收藏!!! 若依框架文档开发手册[持续更新]

    万次阅读 多人点赞 2019-08-08 15:54:04
    若依开发手册前端add.html下拉列时间框Ajax校验自定义校验edit.html下拉列回显时间xxxx.html搜索栏下拉列...用若依也很长时间了一直想写个手册 无奈中间又是离职又是接手老项目一直没机会 最近在开发新系统 果断用...

    首页

    作者

    💘 :青衫

    ✉️ :2940500@qq.com

    🚀 :

    前言:

    💥接触若依也很长时间了从1.0到现在的4.0 期间一直想写个手册 但一直没有很好地切入点 最近在开发新系统 正好根据开发中遇到或者使用到的内容作为切入点来进行写文档 可能会有些混乱 一开始先写上准备后续再排版精修

    最近更新日期 :2020-07-30

    目录结构:

    大致分为前端、后端,前端根据使用的页面add、edit、list来进行详细划分,后端根据三层加上其他特殊内容点划分

    前端

    add.html

    下拉列

    // 1 其中t_vip_user_details_vip_type 为字典表的字典类型 可前往-系统管理-->字段管理 --> 添加新的字典
    <div class="form-group">
                <label class="col-sm-3 control-label">VIP用户类别:</label>
                <div class="col-sm-8">
                    <select id="xxxxx" name="xxxxx" class="form-control m-b"
                            th:with="type=${@dict.getType('t_vip_user_details_vip_type')}">
                        <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
                    </select>
                </div>
            </div>
    
    
    // 2 取非字典的数据(model)
            <div class="form-group">
                <label class="col-sm-3 control-label">司机:</label>
                <div class="col-sm-8">
    		<select id="xxxx" name="xxxx" class="form-control m-b">
                  <option value="">--请选择(非必选)--</option>
                  <option th:each="xxxx : ${xxxxList}" th:text="${xxxx.name}" th:value="${xxxx.id}"></option>
            </select>
                </div>
            </div>
    
    //3 使下拉列带有搜索功能:引入该JS即可
    https://www.cnblogs.com/tianxinyu/p/9988763.html
    
    select的class样式为
    <div th:include="include::footer"></div>
    // 该JS需要在include下方
    <script th:src="@{/ajax/libs/select/select2.js}"></script>
    

    时间框

    <div class="form-group">
        <label class="col-sm-3 control-label">设备到期时间:</label>
        <div class="col-sm-8">
            <div class="input-group date">
               <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
               <input name="xxxxx" class="time-input" placeholder="yyyy-MM-dd" type="text">
            </div>
        </div>
    </div>
    

    大文本框

    <textarea name="content" style="width: 762px ;margin: 0px; height: 295px;"></textarea>
    
    

    Ajax校验

     $("#form-motorman-add").validate({
            rules: {
                name: {
                    required: true,
                },
                identityCard: {
                    required: true,
                    isIdentity: true,
                    remote: {
                        url: ctx + "iot/motorman/checkIdentityCard",
                        type: "post",
                        dataType: "json",
                        data: {
                            name: function () {
                                return $.common.trim($("#identityCard").val());
                            },
                            id: ''
                        },
                        dataFilter: function (data, type) {
                            return $.validate.unique(data);
                        }
                    }
                },
                contactPhone: {
                    required: true,
                    isPhone: true
                },
            },
            messages: {
                "identityCard": {
                    remote: "身份证号已存在"
                },
            }
        });
    
    		/**
    		 * 校验身份证
    		 */
    		@PostMapping("/checkIdentityCard")
    		@ResponseBody
    		public Integer checkIdentityCard(String identityCard, Integer id)
    		{
                // 存在
                return CommonEnum.EXIST.getCode();
                // 不存在
                return CommonEnum.EXIST.NOT_EXIST();
            }
    
    package com.ruoyi.common.constant;
    import lombok.Getter;
    /**
     * @author: [青衫] 'QSSSYH@QQ.com'
     * @Date: 2019-08-08 10:24
     * @Description: < 通用校验是否存在返回状态码 >
     */
    @Getter
    public enum CommonEnum
    	{
    		/**
    		 * 用户是否存在返回码
    		 */
    		EXIST(1, "存在"), NOT_EXIST(0, "不存在");
    		private Integer code;
    		private String msg;
    
    		CommonEnum(Integer code, String msg)
    			{
    				this.code = code;
    				this.msg = msg;
    			}
    	}
    
    

    自定义校验

    jQuery.validator.addMethod("isAllNumber", function (value, element) {
            var loginName = $("#loginName").val();
            var patrn = /^[0-9]*$/;
            if (patrn.test(loginName)) {
                return false;
            } else {
                return true;
            }
        }, "用户名不能为纯数字");
    
    
    $("#form-product-edit").validate({
            rules: {
                    loginName: {
                    required: true,
                    // 自定义属性 属性名要和上方的一参一样
                    isAllNumber: true,
                },
            
            }
        });
    

    成功截图

    回显选中图片

    在下方已经写过了

    路径:前端 --> 其他 --> 回显选中图片

    如果需要放大回显图片可以看

    前端 --> 其他 --> 放大图片

    JS对添加下拉列元素

    http://ourjs.com/detail/5be7fa5cac52fe63eba502af 看这种方式 很好用
    

    edit.html

    下拉列

      <div class="form-group">
                <label class="col-sm-3 control-label">性别:</label>
                <div class="col-sm-8">
                    <select id="xxx"  name="xxx" class="form-control m-b" th:with="type=${@dict.getType('sys_user_sex')}">
                        <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{sex}"></option>
                    </select>
                </div>
            </div>
    

    回显时间

    	<div class="form-group">
                <label class="col-sm-3 control-label">合同到期日期:</label>
                <div class="col-sm-8" >
                    <input id="xxxxxx" name="xxxxxx" class="time-input" type="text" readonly   th:value="${#dates.format(xx.xxxxxx,'yyyy-MM-dd HH:mm:ss')}">
                </div>
            </div>
    




    list.html

    搜索栏

    下拉列

    <li>
       用户状态:<select name="status" th:with="type=${@dict.getType('sys_normal_disable')}">
                	<option value="">所有</option>
               		<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
               </select>
    </li>
    
    
    //2: 下拉列带搜索功能 主要是select class加了form-control 属性
    // 然后引入
    //  <script th:src="@{/ajax/libs/select/select2.css}"></script>
    //  <script th:src="@{/ajax/libs/select/select2.js}"></script>
    
    
    <li style="width: 280px;">
        <p>设备类别: </p>
         <select name="equipmentType" id="equipmentType" th:with="type=${@dict.getType('t_equipment_equipment_type')}" class="form-control">
           <option value="">所有</option>
             <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
          </select>
        </li>
    
    

    sys_normal_disable值位置

    sys_normal_disable 为字典类型值 字典类型值一般为表名字段名来命名防止出现重复

    时间框

    根据开始时间结束时间搜索

    如果使用的是MybatisPlus版本 注意后台接收数据需要创建Vo对象 或者直接使用Map对象来进行接收开始时间结束时间 不然会报错的哈

    **Html: **

    <li class="select-time">
    	<label>创建时间: </label>
        	<input type="text" class="time-input" id="startTime" placeholder="开始时间" name="params[beginTime]"/>
        <span>-</span>
              <input type="text" class="time-input" id="endTime" placeholder="结束时间"name="params[endTime]"/>
    </li>
    

    Vo:

    注意set get方法和普通实体类有区别

    这么写的原因是防止前端没有传入开始时间和结束时间

    然后mapper.xml 这样去判断就会报错 因为params是null 可以在这个判断外边再加一层if判断params是否为空即可解决 但还是推荐 下边这种方式写get set方法

    		/** 请求参数 */
    		private Map<String, Object> params;
    		/** get()*/
    		public Map<String, Object> getParams(){if (params == null){params = new HashMap<>();}return params;}
    		/** set() */
    		public void setParams(Map<String, Object> params){this.params = params;}
    

    mapper.xml:

    <if test="params.beginTime != null and params.beginTime !=''"><!-- 开始时间检索 -->
          AND date_format(xxxxx,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
    </if>
    
    <if test="params.endTime != null and params.endTime  !='' "><!-- 结束时间检索 -->
          AND date_format(xxxxx,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
     </if>
    

    Table表格

    刷新表格

    // 这是封装好的方法  不需要在去调用原生的JS了
    $.table.refresh();
    

    按钮颜色

    后边加上 btn-xs 样式会使按钮缩小

    	深蓝色    btn btn-primary
    ​	浅蓝色    btn btn-info
    ​	绿色     	btn btn-success
    ​	黄色      btn btn-warning
    ​	红色      btn btn-danger
    ​	透明      btn btn-link
    ​	默认		btn btn-default
    
    

    输入图片说明

    自定义按钮颜色

    有时候bootstrap提供的按钮颜色并不能完全满足系统的需要 只有仅限的几个 所以在这时候需要增加自定义的按钮颜色

    下边是两个在线生成bootstrap按钮颜色的网址

    https://blog.koalite.com/bbg/v2/

    http://twitterbootstrap3buttons.w3masters.nl/

    以下为增加一个紫色按钮的示例

    1. 创建一个.css文件

    2. 将下方的css复制到css文件中

    3. 页面引入该css文件

    4. 页面创建个按钮

      1. <a class="btn btn-sample  single disabled">
          <i class="fa fa-sun-o"></i> 审核
        </a>
        

      第二步所需要的代码:

      .btn-sample {
          color: #FFFFFF;
          text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
          background-color: #611BBD;
          *background-color: #611BBD;
          background-image: -moz-linear-gradient(top, #AF4CE8, #611BBD);
          background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#AF4CE8), to(#611BBD));
          background-image: -webkit-linear-gradient(top, #AF4CE8, #611BBD);
          background-image: -o-linear-gradient(top, #AF4CE8, #611BBD);
          background-image: linear-gradient(to bottom, #AF4CE8, #611BBD);
          background-repeat: repeat-x;
          border-color: #611BBD;
          border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
          filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#AF4CE8', endColorstr='#611BBD', GradientType=0);
          filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
      }
      
      .btn-sample:hover,
      .btn-sample:focus,
      .btn-sample:active,
      .btn-sample.active,
      .btn-sample.disabled,
      .btn-sample[disabled] {
          color: #FFFFFF;
          background-color: #611BBD;
          *background-color: #003bb3;
      }
      

    按钮大小

      <div class="container">
            <button class="btn btn-primary">btn-primary</button>
            <button class="btn btn-warning btn-xs">btn-warning</button>
            <button class="btn btn-success btn-sm">btn-success</button>
            <button class="btn btn-info btn-lg">btn-info</button>
        </div>
    

    img

    关于徽章

    参考文章

    https://www.cnblogs.com/xiaohuochai/p/7113645.html

    http://www.360doc.com/content/19/0429/22/59156820_832398875.shtml

    格式化时间

    		/** 合同创建日期 */
    		@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")
    		private Date contractCreateTime;
    

    前端

    th:value="*{#dates.format(reserveTime,'yyyy-MM-dd HH:mm:ss')}"
    

    设置默认排序列

    sortName: 'createTime',
    sortOrder: "desc",
    

    例:

    输入图片说明

    表格匹配字典值

     var userType = [[${@dict.getType('sys_user_user_type')}]];
    
     // 在table相关属性字段的操作
         {
             field: 'userType',
             title: '类型',
             align: "left",
             formatter: function (value, item, index) {
             return $.table.selectDictLabel(userType, value);
             }
          },
    

    表格增加.减少功能项

    单页

    若依的table是用BootstarpTable 而且若依也BootStarpTable简单封装了 如果想要去掉 table右上角的 下载 列表刷新搜索 几个按钮该怎么做呢?也很简单 增加这几个的属性该并为false即可:

    输入图片说明

    全局

    找到 ry-ui.js 将这几个属性设置为false即可

    输入图片说明

    表格初始化完成后执行的回调

    其实就是BootstarpTable的回调函数 网上有很多介绍 这里直接放怎么使用就不介绍了

    onLoadSuccess: function (data) {    
    }
    

    用法:

    <script th:inline="javascript">
        $(function () {
            var options = {
                url: prefix + "/list",
                createUrl: prefix + "/add",
                updateUrl: prefix + "/edit/{id}",
                removeUrl: prefix + "/remove",
                exportUrl: prefix + "/export",
                modalName: "车辆信息",
                fixedColumns: true,                 // 是否启用冻结列(左侧)
                fixedNumber: 7,                   // 列冻结的个数(左侧)
                rightFixedColumns: false,       // 是否启用冻结列(右侧)
                rightFixedNumber: 1,
                columns: [{
                    checkbox: true
                	},
                    {
                        field: 'id',
                        title: '车辆编号',
                        visible: false
                    },
          
                
                    ],
                onLoadSuccess: function (data) {
                  console.log("页面初始化完成后会调用一次本方法");
                },
            };
            $.table.init(options);
        });
    </script>
    

    表格固定左|右列后,滚动条被覆盖的bug以及解决

    找到bootstrap-table-fixed-columns.js 的224行 heigth属性值减13就好了

    更改后:

    this.$fixedBody.css({
      width: this.$fixedHeader.width(),
      height: height-13,
      top: top + 1
    }).show();
    



    其他

    JS循环

    添加个链接这个博主写的很详细

    https://blog.csdn.net/qq_41899174/article/details/82797089

    validator

    1. 动态校验提示信息

      来源:

      $.validator.addMethod('PD_password', function (value, element) {
          var len = value.length;
          if(len<6){
              $(element).data('error-msg','长度不能少于6位');
              return false;
          }
          if(len>15){
              $(element).data('error-msg','长度不能大于15位');
              return false;
          }
          return true;
      }, function(params, element) {
          return $(element).data('error-msg');
      });
      
    2. 清空提示信息
      $("#form-consignor-add").validate().resetForm();
      
    3. 单独校验指定输入框
    4. // 某个表单里的指定行
      $("#form-xxx").validate().element($("#xxx"))
      
    5. validate使用tooltip提示错误信息
          $("#form-add").validate({
              rules: {
              },
              // 下边这些是重要的
              unhighlight: function (element, errorClass, validClass) { //验证通过
                  $(element).tooltip('destroy').removeClass(errorClass);
              },
              errorPlacement: function (error, element) {
                  if ($(element).next("div").hasClass("tooltip")) {
                      $(element).attr("data-original-title", $(error).text()).tooltip("show");
                  } else {
                      $(element).attr("title",
                          $(error).text()).tooltip("show");
                  }
              },
      
      
          });
      

    放大图片

    有时候为了页面美观显示的图片比较小 只能看到缩略图 但是在某些情况下又想看到放大后的图片 这时候就需要图片放大功能了 layui的就不介绍了 这里介绍两种其他的

    • 放大镜方法图片(鼠标悬浮在缩略图上就可以放大)
    • 弹出层放大图片(点击弹出遮罩层,放大图片)

    放大镜放大:

    使用 jQuery Zoom Plugin插件

    github: https://github.com/elevateweb/elevatezoom

    文档地址: https://www.myfreax.com/elevatezoom-image-zoom/

    Html

    <img id="zoom_01" src='images/small/image1.png' data-zoom-image="images/large/image1.jpg"/>
    <!-- src 指向的是缩略图 data-zoom-image指向的是大图 (可以指向同一个图片 设置当前img的宽高缩小显示图片 当鼠标悬浮就会显示未缩小的图片了)-->
    

    JQuery

    有六种显示效果 根据需要选择 推荐第一种 如果需要可以访问文档看它的其他属性

    $('#zoom_01').elevateZoom({});//默认效果 
    
    $('#zoom_01').elevateZoom({ //内置镜头 
     zoomType: "inner",//类型:内置镜头 
     cursor: "crosshair", //光标:十字 
     zoomWindowFadeIn: 500,//镜头窗口淡入速度 
     zoomWindowFadeOut: 750 //镜头窗口淡出速度 
    }); 
    
    $("#zoom_01").elevateZoom({ //镜头聚焦 
     zoomType: "lens",//类型:透镜效果 
     lensShape: "round", //透镜形状:圆形 
     lensSize: 200 //透镜尺寸:长和宽:200px 
    }); 
    
    $("#zoom_01").elevateZoom({ //淡入/淡出设置 
     zoomWindowFadeIn: 500,//镜头窗口淡入速度 
     zoomWindowFadeOut: 500,//镜头窗口淡出速度 
     lensFadeIn: 500,//透镜淡入速度 
     lensFadeOut: 500//透镜淡出速度 
    }); 
    
    $("#zoom_01").elevateZoom({ //动画 
     easing: true //是否开启动画效果 
    }); 
    
    $("#zoom_01").elevateZoom({ //鼠标滚动 
     scrollZoom: true //是否开启鼠标滚动 
    });
    

    弹出层放大:

    这个就是弹出一个遮罩层 显示图片 没什么好说的直接是上代码吧

    原文链接: https://blog.csdn.net/m0_37865510/article/details/84636488

    缩略图位置:

    注意class为:pimg 下边会用到 
    <img  src='images/image1.png'  class="pimg"/>
    

    在html最下边 添加下边这一段代码(遮罩层)

    注意:z-index:2; 为遮罩层显示的高度如果想显示在最上层直接将2改为9999就行了

    <div id="outerdiv" style="position:fixed;top:0;left:0;background:rgba(0,0,0,0.7);z-index:2;width:100%;height:100%;display:none;">
     <div id="innerdiv" style="position:absolute;">
         <img id="bigimg" style="border:5px solid #fff;" src="" />
     </div>
    </div>
    

    JS:

    <script>  
     $(function(){  
         $(".pimg").click(function(){  
             var _this = $(this);//将当前的pimg元素作为_this传入函数  
             imgShow("#outerdiv", "#innerdiv", "#bigimg", _this);  
         });  
     });  
    
     function imgShow(outerdiv, innerdiv, bigimg, _this){  
         var src = _this.attr("src");//获取当前点击的pimg元素中的src属性  
         $(bigimg).attr("src", src);//设置#bigimg元素的src属性  
       
             /*获取当前点击图片的真实大小,并显示弹出层及大图*/  
         $("<img/>").attr("src", src).load(function(){  
             var windowW = $(window).width();//获取当前窗口宽度  
             var windowH = $(window).height();//获取当前窗口高度  
             var realWidth = this.width;//获取图片真实宽度  
             var realHeight = this.height;//获取图片真实高度  
             var imgWidth, imgHeight;  
             var scale = 0.8;//缩放尺寸,当图片真实宽度和高度大于窗口宽度和高度时进行缩放  
               
             if(realHeight>windowH*scale) {//判断图片高度  
                 imgHeight = windowH*scale;//如大于窗口高度,图片高度进行缩放  
                 imgWidth = imgHeight/realHeight*realWidth;//等比例缩放宽度  
                 if(imgWidth>windowW*scale) {//如宽度扔大于窗口宽度  
                     imgWidth = windowW*scale;//再对宽度进行缩放  
                 }  
             } else if(realWidth>windowW*scale) {//如图片高度合适,判断图片宽度  
                 imgWidth = windowW*scale;//如大于窗口宽度,图片宽度进行缩放  
                             imgHeight = imgWidth/realWidth*realHeight;//等比例缩放高度  
             } else {//如果图片真实高度和宽度都符合要求,高宽不变  
                 imgWidth = realWidth;  
                 imgHeight = realHeight;  
             }  
                     $(bigimg).css("width",imgWidth);//以最终的宽度对图片缩放  
               
             var w = (windowW-imgWidth)/2;//计算图片与窗口左边距  
             var h = (windowH-imgHeight)/2;//计算图片与窗口上边距  
             $(innerdiv).css({"top":h, "left":w});//设置#innerdiv的top和left属性  
             $(outerdiv).fadeIn("fast");//淡入显示#outerdiv及.pimg  
         });  
           
         $(outerdiv).click(function(){//再次点击淡出消失弹出层  
             $(this).fadeOut("fast");  
         });  
     }  
    </script>
    

    新建标签页

    若依已经对创建新的标签页已经进行封装 JS方法为: createMenuItem()

    1. $.modal.openTab()

      现在 在ry-ui.js里已经又对新建菜单页(createMenuItem)进行了封装

      // 方式1 打开新的选项卡
      function dept() {
      	var url = ctx + "system/dept";
      	$.modal.openTab("部门管理", url);
      }
      // 方式2 选卡页同一页签打开
      function dept() {
      	var url = ctx + "system/dept";
      	$.modal.parentTab("部门管理", url);
      }
      // 方式3 html创建
      <a class="menuItem" href="/system/dept">部门管理</a>
      
    2. createMenuItem

    // 要打开的地址
    var url=prefix+"/details?userId="+userId;
    
    // 调用createMenuItem()方法 1参:要打开的地址 ,2参:标签页名称
    createMenuItem(url, "用户详情");
    

    注意:

    1. 如果提示调用 createMenuItem of undefined 那就记得引入 common.js 生成的代码里默认会引入
    2. 提示random of undefined 就引入ry-ui.js
    <script th:src="@{/ruoyi/js/common.js?v=3.2.0}"></script>
    
    <script th:src="@{/ruoyi/js/ry-ui.js?v=3.2.0}"></script>
    

    方法源代码:

    源代码就不贴出来了 贴出来也没什么意义 位置:

    common.js  -->  createMenuItem(dataUrl, menuName)
    

    关闭标签页

    // 源代码在index.js里
      $('.tabCloseCurrent').on('click', function () {
            $('.page-tabs-content').find('.active i').trigger("click");
        });
    

    输入框锁定

    这个相信大家都会 还是再写一下吧 这段话是从网站上直接复制过来的

    disabled 属性规定应该禁用 input 元素,被禁用的 input 元素,不可编辑,不可复制,不可选择,不能接收焦点,后台也不会接收到传值。设置后文字的颜色会变成灰色。disabled 属性无法与

    //disabled 属性无法与 <input type="hidden">一起使用。
    示例:<input type="text" disabled="disabled" />
    

    readonly 属性规定输入字段为只读可复制,但是,用户可以使用Tab键切换到该字段,可选择,可以接收焦点,还可以选中或拷贝其文本。后台会接收到传值. readonly 属性可以防止用户对值进行修改。

    // readonly 属性可与 <input type="text"> 或 <input type="password"> 配合使用。
    示例:<input type="text" readonly="readonly">
    

    readonly unselectable=“on” 该属性跟disable类似,input 元素,不可编辑,不可复制,不可选择,不能接收焦点,设置后文字的颜色也会变成灰色,但是后台可以接收到传值。

    示例:<input type="text"  readonly  unselectable="on" >
    

    弹出某页面

    弹窗

    // 弹出添加用户积分日志页面
    function open_account_log(userId) {
        // 调用方法弹出
        $.modal.open("用户积分修改", '/system/accountDetailsLog/add');
    }
    

    JS校验空值

    function isEmpty(obj){
        if(typeof obj == "undefined" || obj == null || obj == ""){
            return true;
        }else{
            return false;
        }
    }
    

    JS绑定input事件

    js绑定input事件而不是使用改变值的change事件

    可以实现输入值后就做某些操作 而不是在输入完然后失去焦点再进行触发

      // 输入框自动去空格  其中propertychange 是对ie9以下浏览器的支持
        $(".form-control").bind("input propertychange", function () {
                $(this).val($(this).val().replace(/\s*/g, ""));
            }
        );
    

    自定义AJAX

    这里是使用解绑按钮来进行示例

    解绑操作不需要弹窗 如果直接调用封装好的修改的方法或者操作成功处理操作成功的方法会关闭弹窗刷新父级页面 导致全局刷新 这样写就可以 既可以向后台执行想要执行的操作 也可以弹出消息提醒 又不导致全局刷新 只刷新Table表格

      // 上传文件
                function sendFile(file, obj) {
                    var data = new FormData();
                    data.append("file", file);
                    $.ajax({
                        type: "POST",
                        url: ctx + "common/upload",
                        data: data,
                        cache: false,
                        contentType: false,
                        processData: false,
                        dataType: 'json',
                        success: function (result) {
                            if (result.code == web_status.SUCCESS) {
                                $(obj).summernote('editor.insertImage', result.url, result.fileName);
                            } else {
                                $.modal.alertError(result.msg);
                            }
                        },
                        error: function (error) {
                            $.modal.alertWarning("图片上传失败。");
                        }
                    });
                }
    

    添加Class元素

     .abc{
      background: red;
      }
    test div
        var div = document.getElementById('d1');
        div.classlist.add("abc");      //添加
        div.classlist.remove("abc");   //删除
    

    操作结果提示

    // 需要引入 ry-ui.js文件 content为提示文字
    <script th:src="@{/ruoyi/js/ry-ui.js?v=3.2.0}"></script>
    
    // 错误
      $.modal.msg(content, modal_status.FAIL);
    // 成功
     $.modal.msg(content, modal_status.SUCCESS);
    

    回显选中图片

    如果需要放大回显图片可以看

    前端 --> 其他 --> 放大图片

    回显浏览器选中的图片

    如果在选择文件的时候,只想显示图片文件可以这样写

    <input type="file" accept="image/*">
    

    HTML示例:

        <div class="form-group">
           <label class="col-sm-3 control-label">主图:</label>
            <div class="col-sm-8">
             	<input id="file" name="mainImageA" class="filepath" onchange="changepic(this)" type="file"><br>
             	<img src="" id="show" width="200">
            </div>
            </div>
    

    JS:

      function changepic(obj) {
            var reads = new FileReader();
            f = document.getElementById('file').files[0];
            reads.readAsDataURL(f);
            reads.onload = function (e) {
                document.getElementById('show').src = this.result;
            };
        }
    

    JS创建集合对象

    // js中创建集合
    var list=[];
    // js中创建cs对象
    var cs = {
        id=1,
        name='admin',
        password='admin'
    }
    //保存对象
    list.push( cs );
    

    显示隐藏HTML

    隐藏html代码块 分为两种方式隐藏

    1. style=“visibility: hidden;” (隐藏但是位置会占用)
    2. style=“display: none;” (隐藏并且位置会释放)
    <span id='vip_user_input'> hello</span>
    
    // visibility: none
    document.getElementById("id").style.visibility="hidden";//隐藏
    
    document.getElementById("id").style.visibility="visible";//显示
    
    
    
    
    // display: none
    var userType =2;
      if (userType == 2) {
      //获取要显示的div对象
     document.getElementById('id').style.display = "block"; //显示
      } else {
      document.getElementById('id').style.display = "none";  // 隐藏
      }
    

    Js版本

      $("#id").hide();// 隐藏
      $("#id").show();// 显示
    

    页面加载完成执行

    页面加载完成执行有两种加载时机

    1. 页面所有资源加载完成后执行 (包括图片或者其他资源)
    2. 页面的Dom结构在家完成就开始执行
    //1 资源加载完成才执行 (图片资源等等)
    window.onload = function() { 
    }; 
    
    //2 Dom加载完成就执行
    $(document).ready(function() { 
    }); 
    
    //2.1 简写
    $(function() {
    });
    
    

    默认全屏打开添加页

    <a class="btn btn-success" onclick="$.operate.addFull()" shiro:hasPermission="system:notice:add">
        <i class="fa fa-plus"></i> 新增
    </a>
    

    Thymeleaf

    标签

    关键字功能介绍案例
    th:id替换id<input th:id="'xxx' + ${collect.id}"/>
    th:text文本替换<p th:text="${collect.description}">description</p>
    th:utext支持html的文本替换<p th:utext="${htmlcontent}">content</p>
    th:object替换对象<div th:object="${session.user}">
    th:value属性赋值<input th:value = "${user.name}" />
    th:with变量赋值运算<div th:with="isEvens = ${prodStat.count}%2 == 0"></div>
    th:style设置样式<div th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''"></div>
    th:onclick点击事件<td th:onclick = "'getCollect()'"></td>
    th:each属性赋值循环<tr th:each = "user,userStat:${users}">
    th:if判断条件<a th:if = "${userId == collect.userId}">
    th:unless和th:if判断相反<a th:href="@{/login} th:unless=${session.user != null}">Login</a>
    th:href链接地址<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
    th:switch多路选择配合th:case使用<div th:switch="${user.role}">
    th:fragmentth:switch的一个分支<p th:case = "'admin'">User is an administrator</p>
    th:includ布局标签,替换内容到引入的文件<head th:include="layout :: htmlhead" th:with="title='xx'"></head>
    th:replace布局标签,替换整个标签到引入的文件<div th:replace="fragments/header :: title"></div>
    th:selectdselected选择框选中th:selected="(${xxx.id} == ${configObj.dd})"
    th:src图片类地址引入<img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" />
    th:inline定义js脚本可以使用变量<script type="text/javascript" th:inline="javascript">
    th:action表单提交的地址<form action="subscribe.html" th:action="@{/subscribe}">
    th:remove删除某个属性
    th:attr设置标签属性,多个属性可以用逗号分隔比如 th:attr=“src=@{/image/aa.jpg},title=#{logo}”,此标签不太优雅,一般用的比较少。
    1.all:删除包含标签和所有的孩子。2.body:不包含标记删除,但删除其所有的孩子。3.tag:包含标记的删除,但不删除它的孩子。4.all-but-first:删除所有包含标签的孩子,除了第一个。5.none:什么也不做。这个值是有用的动态评估。

    循环

       <tr  th:each="user,userStat : ${list}">  
                    <td th:text="${user.userName}">Onions</td>  
                    <td th:text="${user.email}">test@test.com.cn</td>  
                    <td th:text="${user.isAdmin}">yes</td>  
                     <th th:text="${userStat.index}">状态变量:index</th>  
                    <th th:text="${userStat.count}">状态变量:count</th>  
                    <th th:text="${userStat.size}">状态变量:size</th>  
                    <th th:text="${userStat.current.userName}">状态变量:current</th>  
                    <th th:text="${userStat.even}">状态变量:even****</th>  
                    <th th:text="${userStat.odd}">状态变量:odd</th>  
                    <th th:text="${userStat.first}">状态变量:first</th>  
                    <th th:text="${userStat.last}">状态变量:last</th>  
        </tr>
    

    判断

    <th:block th:if="...">
    	<div id="div1">
    	</div>
    	<div id="div2">
    	</div>
    </th:block>
    

    JS取值

    // 注意script属性
    <script th:inline="javascript">
        var message = [[${message}]];
        console.log(message);
    
    // 注意 这种也可以取值 并且取出的值为字符串类型  作用嘛
    // 举例 比如在加载页面的icon的时候 如果直接取值fa fa-user-o 就会报错  但是如果在去之前外边加上''那取出的值就是字符串类型 
          // 设置icon图标
        var one_icon = $('#one_icon');
    	// 正确赋值
        one_icon.addClass('[[${oneIcon}]]');
    	// 报错
    	one_icon.addClass([[${oneIcon}]]);
    </script>
    

    th:onclick

    传递单个参数

    th:οnclick="searchHot([[${hot.name}]])"
    

    传递多个Model中参数

    th:οnclick="'javascript:searchHot(\''+${hot.name}+'\',\''+${hot.hotType}+'\')'"
    

    传递一个Model中参数 一个非Model中参数

    th:οnclick="'javascript:searchHot(\''+${hot.name}+'\','+this+')'"
    

    格式化时间

    th:value="*{#dates.format(reserveTime,'yyyy-MM-dd HH:mm:ss')}"
    

    截取字符串

    msg.content为被截取的字符串 15为截取长度
    <span th:utext="${#strings.abbreviate( msg.content,15)}"></span>
    
    其他-网络文章

    https://blog.csdn.net/zoubo0812/article/details/54906297#commentBox

    JQuery相关

    返回上页

    function goBack() {
        window.history.go(-1);
    }
    

    后端

    系统

    当前用户

    对当前登录用户的操作已经进行了封装

    有获取当前登陆用户 获取当前登录用户ID 等这里不贴源码了

    该工具类位置:

    com.ruoyi.framework.util.ShiroUtils

    定时器

    关闭定时器

    有时候定时器大家并不一定需要用到 又想把定时器阉割掉 时怎么做呢?
    难道要删大量的定时器相关代码吗? 很显然不需要只需要将定时器在启动时初始化的注解注释掉就可以了

    输入图片说明

    新增定时器

    输入图片说明

    输入图片说明

    在系统监控 --> 定时任务 -->新增定时任务

    输入图片说明





    Controller

    关于权限

    若依框架使用的是Shiro来进行权限控制

    下边介绍一下在Controller新增一个请求地址 然后使这个地址被管理需要做那些操作

    1. 添加注解
    2. 插入sql
    3. 按钮控制

    Service

    Dao

    Mapper

    属性封装

    发现一篇很有意思的关于封装返回的文章 大概看了一下 这里记录一下 有时间再看

    https://www.cnblogs.com/stefanking/articles/5092474.html

    说到Mapper不得不说一下vo封装 之前都是写一个association然后再写相应的属性的result 然后导致mapper文件 全是result

    这里介绍一下封装的时候引入本文件的其他 或其他文件里的

    POJO:

    // 继承原实体类得到原实体类的所有属性
    @Data
    public class EquipmentVo extends Equipment implements Serializable
    	{
    	//增加两个属性
    		/** 供应商 */
    		private Supplier supplier;
    
    		/** 所属用户 */
    		private SysUser sysUser;
    
    	}
    

    association 标签中的属性

    property:	vo中的属性名
    column:		该属性id对应的的字段名[非必须]
    javaType:	该属性的Java类型
    resultMap:	引入的本文件的话就是resultMap 的id
    			resultMap的id 引入其他文件的resultMap 时是xml文件所对应的Dao的全路径加					resultMap的Id
    

    ​ 例:

    注意:

    Association和Collection使用时机区别:

    Association 在一对一,多对一时使用

    Collection 在一对多,多对多时使用

    在association标签中 javaType属性指向的是实体类的属性

    在collection标签中 javaType属性指向的是集合的类型 ofType指向的是集合的泛型类型

    Mapper:

     <resultMap type="com.ruoyi.iot.domain.vo.EquipmentVo" id="EquipmentVoResult">
            <result property="id" column="id"/>
            <result property="equipmentNumber" column="equipment_number"/>
            <result property="createTime" column="create_time"/>
    
            <!-- 供应商 引入其他文件的resultMap 路径dao层路径加resultMap 的id-->
            <association property="supplier" column="s.id" javaType="com.ruoyi.iot.domain.Supplier" resultMap="com.ruoyi.iot.mapper.SupplierMapper.SupplierResult">
                <result property="createTime" column="screate_time"/>
            </association>
            <!--用户 引入当前文件resultMap-->
            <association property="sysUser" column="user_id" javaType="com.ruoyi.system.domain.SysUser" resultMap="SysUserResult">
            </association>
        </resultMap>
    
    
    <!--用户-->
        <resultMap type="com.ruoyi.system.domain.SysUser" id="SysUserResult">
            <id property="userId" column="user_id"/>
            <result property="deptId" column="dept_id"/>
            <result property="loginName" column="login_name"/>
        </resultMap>
    

    集合遍历

    单参数

    Dao:

    Integer selectEquipmentNumber(List<Integer> statusList);
    

    XML:

    <foreach collection="list" item="status" index="index" separator="or" open="(" close=")">
             equipment_status = #{item}
    </foreach>
    
    多参数:

    Dao:

    XML:

    <!-- 多参数的 collection为参数的名称 -->
    
    

    其他

    MP忽略null值

      // 修改时忽略null 和空值
        @TableField(strategy = FieldStrategy.IGNORED)
        private BigDecimal discountPrice;
    

    BigDecimal使用

    直接复制过来的就不在重复写了

    注意除法 divide 是重载的方法 如果直接 a.divide(b) 的话可能会出现该异常:

    [ Non-terminating decimal expansion; no exact representable decimal result.]

    相当于10/3 无法除尽 尽量指定小数长度和规则

    BigDecimal bignum1 = new BigDecimal("10");  
    BigDecimal bignum2 = new BigDecimal("5");  
    BigDecimal bignum3 = null;  
      
    // 加法  
    bignum3 =  bignum1.add(bignum2);       
    System.out.println("和 是:" + bignum3);  
      
    // 减法  
    bignum3 = bignum1.subtract(bignum2);  
    System.out.println("差  是:" + bignum3);  
      
    // 乘法  
    bignum3 = bignum1.multiply(bignum2);  
    System.out.println("积  是:" + bignum3);  
      
    // 除法  
    bignum3 = bignum1.divide(bignum2);  
    System.out.println("商  是:" + bignum3);
    
    // 除法2
    // scale表示保留小数位数 roundingMode表示为小数模式
    divide(BigDecimal divisor, int scale, RoundingMode roundingMode) ;
    
    BigDecimal bignum3 = bignum1.divide(bignum2,10,ROUND_HALF_DOWN);
    

    小数模式常量

    ROUND_CEILING=如果 BigDecimal 是正的,则做 ROUND_UP 操作;如果为负,则做 ROUND_DOWN 操作。
    ROUND_DOWN=从不在舍弃(即截断)的小数之前增加数字。
    ROUND_FLOOR=如果 BigDecimal 为正,则作 ROUND_UP ;如果为负,则作 ROUND_DOWN 。
    ROUND_HALF_DOWN=若舍弃部分> .5,则作 ROUND_UP;否则,作 ROUND_DOWN 。
    ROUND_HALF_EVEN=如果舍弃部分左边的数字为奇数,则作 ROUND_HALF_UP ;如果它为偶数,则作ROUND_HALF_DOWN 。
    ROUND_HALF_UP=若舍弃部分>=.5,则作 ROUND_UP ;否则,作 ROUND_DOWN 。
    ROUND_UNNECESSARY=该“伪舍入模式”实际是指明所要求的操作必须是精确的,因此不需要舍入操作。
    ROUND_UP=总是在非 0 舍弃小数(即截断)之前增加数字。
    

    比较大小

    BigDecimal a = new BigDecimal (101);
    BigDecimal b = new BigDecimal (111);
     
    //使用compareTo方法比较
    //注意:a、b均不能为null,否则会报空指针
    if(a.compareTo(b) == -1){
        System.out.println("a小于b");
    }
     
    if(a.compareTo(b) == 0){
        System.out.println("a等于b");
    }
     
    if(a.compareTo(b) == 1){
        System.out.println("a大于b");
    }
     
    if(a.compareTo(b) > -1){
        System.out.println("a大于等于b");
    }
     
    if(a.compareTo(b) < 1){
        System.out.println("a小于等于b");
    }
    

    MYSQL

    获取时间

    mysql查询当前系统时间不保留时分秒,保留时分秒,当前时间加一天,当前时间减少一天等

    转发至CSDN 原文链接 :https://blog.csdn.net/liu_yulong/article/details/90447555

    SELECT
    	CURDATE( ),
    	now( ),
    	CURTIME( ),
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) yestorday,
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) today 
    FROM
    	DUAL;
    

    img

     
    SELECT
    	CURDATE( ) date,
    	now( ) dateTime,
    	DATE_FORMAT( now( ), '%Y-%m-%d' ) dateFmt,
    	DATE_FORMAT( now( ), '%Y-%m-%d' ) dateTimeFmt,
    	DATE_FORMAT( now( ), '%Y-%m-%d %H:%i:%s' ) daymins,
    	CURTIME( ) times,
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) Yesterday ,
    	date_sub( CURDATE( ), INTERVAL 0 DAY ) Today  ,
    	date_sub( CURDATE( ), INTERVAL 1 DAY ) Tomorrow 
    FROM
    	DUAL;
    

    img

    展开全文
  • Grafana最新版使用手册.pdf 可视化技术设施性能数据和应用分析序列数据, 监控数据和日志数据分析展示分析聚合展示
  • java 调用 Cplex 使用手册, CPLEX Tutorial Handout。
  • Burpsuite最全模块说明文档,Burpsuite使用手册中文版下载!
  • sklearn使用手册,包括实例step by step,迄今为止讲解得最为详细的该库的中文版使用手册。既有理论也有代码的实现,只要稍微会点Python,理解起来就十分容易了。如果有数学基础的话,那就更好了!(非必须)。
  • 组态用软件手册,比较详细。希望对大家有所帮助。。。。。。。。。。。
  • 通达OA 2015版使用手册

    热门讨论 2015-06-16 16:32:35
    通达OA 2015版使用手册
  • sklearn使用手册中文版

    2017-06-23 11:09:54
    sklearn使用手册,包括实例step by step
  • 若依微服务框架ruoyi-cloud使用手册(持续更新中)

    万次阅读 多人点赞 2020-10-12 18:17:51
    主要对使用ruoyi-cloud过程中遇到的坑进行记录和解决,包括以下: 一、项目启动事项 二、新建模块案例 三、一些坑~ 一、项目启动事项 1.首先进行项目相关工具及环境准备,官方文档也有,不过还是贴一下。 JDK >= ...

    一、项目启动事项

    1.首先进行项目相关工具及环境准备,官方文档也有,不过还是贴一下。
    JDK >= 1.8 (推荐1.8版本)
    Mysql >= 5.5.0 (推荐5.7版本)
    Redis >= 3.0
    Maven >= 3.0
    Node >= 10
    Nacos >= 1.1.0
    sentinel >= 1.6.0(启动项目非必要)
    这里需要注意的是:
    NodeJavaScript 是运行在服务端的 JavaScript环境,这里配合vue进行前端界面展示。
    Redis进行必要的数据缓存。
    Nacos在这里作为spring cloud微服务的注册中心和配置中心。
    详情请自查。

    2.环境配置好后,执行操作类似若依官网,用idea或eclipse都行,贴一下网址好了:

    https://doc.ruoyi.vip/ruoyi-cloud/document/hjbs.html#%E8%BF%90%E8%A1%8C%E7%B3%BB%E7%BB%9F

    注意事项如下:

    后端运行:

    注意Redis和Nacos都要启动;
    可能在运行RuoYiSystemApplication (系统模块)时连接数据库失败,这里因为直接导入数据脚本ry_config.sql的话会导入默认的System模块的数据库配置,数据库密码为password,如下图:
    在这里插入图片描述
    可以在ry_config.sql文件中查找修改成自己的mysql密码后重新导入本地数据库(注意不止修改一处)。

    前端运行(在idea或vscode的Terminal(终端)执行命令):
    在通过npm命令安装依赖时可能会有以下错误:
    Downloading binary from https://github.com/sass/node-sass/releases/download/v4.14.1/win32-x64-72_bin
    原因是node-sass被墙掉了,下载不了,可通过以下命令下载:

    npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
    

    之后基本没问题啦操作执行完毕后可自动跳转界面进行登录访问,如果存在问题可检查以上操作步骤,重启各模块查看。
    在这里插入图片描述

    二、新建功能模块案例

    步骤如下:
    1.创建新模块:ruoyi-test;
    2.进行新模块代码的基础配置调整
    3.在nacos进行新模块的配置管理
    4.新增测试表,生成代码,并进行前后端代码的修改和使用
    5.进行界面菜单配置,启动新建的模块,重启前端vue界面,登录查看新模块基础界面及功能。

    具体如下:

    1.创建新模块ruoyi-test:
    这里在ruoyi-modules目录下新建test模块并新增界面,可参考ruoyi-system模块的目录结构及命名,类似若依原始框架的module创建,不贴图了吧;

    2.进行新模块代码的基础配置调整:
    修改ruoyi-test下的pom文件,参考ruoyi-system模块,可复制ruoyi-system的pom文件内容,修改system相关字段即可;
    修改ruoyi-modules下的pom文件,增加 ruoyi-test 代码,参考ruoyi-system部分;
    参考ruoyi-system模块修改TestApplication启动类代码,新增相关注解即可,如下:

    在这里插入图片描述另外对于resources可复制ruoyi-system模块文件进行调整(注意在bootstrap.yml文件中端口号不要冲突,可全局搜索一下,避免冲突)

    在这里插入图片描述

    3.在nacos进行新模块的配置管理
    登录nacos:http://localhost:8848/nacos/
    克隆 ruoyi-system-dev.yml ,命名为 ruoyi-test-dev.yml(名称对应自己模块),
    在这里插入图片描述
    点击编辑,修改下方的mybatis.typeAliasesPackage,改为 自己的对应名称,发布。如下:

    在这里插入图片描述修改 ruoyi-gateway-dev.yml,添加新增的模块,发布。界面如下:

    在这里插入图片描述
    4.新增测试表,生成代码,并进行前后端代码的修改和使用
    创建测试表student,设置字段注释,在系统界面生成代码;
    生成的后端代码参考其他们模块的目录结构进行复制粘贴,修改maoper等各层级的代码,消除bug,保证后端各方法到持久层的正常跳转;
    修改控制层的权限标识为自己对应的模块。如下:

    在这里插入图片描述前端代码包括.vue文件和.js文件,可参考system模块在ruoyi-ui的views和api文件下创建新增自己的模块代码,这里js文件包含各接口路径,需要保证是自己模块路径。界面类似如下:
    在这里插入图片描述
    5.进行界面菜单配置,启动新建的模块,重启前端vue界面,登录查看新模块基础界面及功能。
    菜单配置可参考system模块样式进行路径及权限标识,按钮等的配置即可;
    启动新建的模块,重启前端vue界面,可查看测试模块的基础功能。如下:

    在这里插入图片描述

    三、不同微服务系统间接口调用案例

    进行微服务系统A对微服务系统B进行接口调用的操作测试,这里系统A与系统B共用同一个nacos配置中心,步骤如下:
    1、在系统B中添加测试接口
    2、在系统A的ruoyi-api中进行测试接口的调用配置。
    3、在系统A中某功能模块调用步骤2中配置好的接口,打印获取的接口数据。
    4、在测试接口的基础上添加含有对象参数的接口,这里贴一下格式

    具体如下,注意这里包括两种接口调用方式,以无参和对象参数传递:
    1、在系统B中添加测试接口
    在系统B的功能模块的控制层中添加需要测试用的接口,可以是系统模块功能中的普通接口(比如某获取某模块的列表数据),这里简单来,直接返回字符串。界面如下:

    在这里插入图片描述2、在系统A的ruoyi-api中进行测试接口的调用配置。
    简单一些可直接在ruoyi-api的ruoyi-api-system中进行测试,这个项目里ruoyi替换为了ctt,不用在意。仿照RemoteUserService文件和factory / RemoteUserFallbackFactory文件创建测试用的对应文件,这里我们创建RemoteTestService(接口文件)和RemoteTestFallbackFactory(降级处理)文件,目录如下(注意最后一行的spring.factorys文件,后面有用):
    在这里插入图片描述
    注意在RemoteTestService接口文件中,要自己定义需要调用的服务名称,就是下图中图一的红线标识和图二的服务名称配置(这里图二的服务名称即我们调用的系统B接口所在的的module服务名称)
    图一:
    在这里插入图片描述图二:

    在这里插入图片描述最后在spring.factorys中配置我们的RemoteUserFallbackFactory文件,保证降级处理功能正常,RemoteUserFallbackFactory文件在这里类似于异常处理的操作。
    在这里插入图片描述
    3、在系统A中某功能模块调用步骤2中配置好的接口,打印获取的接口数据。
    在系统A的,随便某常用控制层接口中,调用我们刚刚创建的RemoteTestService接口并打印,如下:
    引入:

     @Autowired
        private RemoteTestService remoteTestService;
    

    调用及打印(第四行插入的语句打印获取的接口数据):

     @GetMapping("/list")
        public TableDataInfo list(OrderBookFx orderBookFx)
        {
            System.err.println("???" + remoteTestService.getInfo());
            startPage();
            List<OrderBookFx> list = orderBookFxService.selectOrderBookFxList(orderBookFx);
            return getDataTable(list);
        }
    

    打印结果如下:在这里插入图片描述
    4、在测试接口的基础上添加含有对象参数的接口,这里贴一下格式
    对于常用的有对象参数的接口上面的GetMapping是不适用的,同样是上述的微服务系统A对微服务系统B进行接口调用,这里贴一下正确格式,也可以参考链接(https://blog.csdn.net/qq_42422368/article/details/109381309
    系统B接口:

        @PostMapping(value = "/company/list")
        public List<CruiseCompInfo> companyList(@RequestBody CruiseCompInfo cruiseCompInfo)
        {
            return cruiseCompInfoService.selectCruiseCompInfoList(cruiseCompInfo);
        }
    

    系统A接口:

        @RequestMapping(value = "/company/list", method = RequestMethod.POST)
        public List<CruiseCompInfo> companyList(@RequestBody CruiseCompInfo cruiseCompInfo);
    

    有一个注意点是A系统调用接口传参时可以new一个空的对象做参数,但是不能直接拿null做参数,因为在系统B中用到的@RequestBody 的 required 默认值是true。
    贴一下效果:
    在这里插入图片描述

    四、服务器部署

    可以参考若依官网,微服务版项目部署文档:https://doc.ruoyi.vip/ruoyi-cloud/document/hjbs.html#%E9%83%A8%E7%BD%B2%E7%B3%BB%E7%BB%9F
    这里在linux系统进行jar包发布,前端生成的dist文件在nginx配置展示,操作如下:

    1、环境准备
    2、后端部署
    3、前端部署
    4、项目启动

    具体如下:
    1、环境准备
    服务器环境配置:主要是nginx配置以及常规nacos、redis配置
    注意点:
    nginx环境:https://www.cnblogs.com/xxoome/p/5866475.html

    2、后端部署
    后端需要保证nacos配置中心的配置信息正确,主要是路径方面的,比如redis及nacos配置在服务器部署后可以正常访问和连接。
    运行项目一级目录下的打包文件bin/package.bat
    会默认在项目下生成 target文件夹,包含jar
    注意是在Terminal(终端)运行命令,生成的jar包可以先拿几个必要的比如auth、gateway、system模块的jar包部署测试。
    jar包可以放服务器随便某目录进行启动,比如:
    在这里插入图片描述运行一个jar包的命令举例,进入到对应的文件夹,执行:
    nohup java -jar ctt-auth-2.1.0.jar > ./logs/ctt-auth.log 2>&1 &
    jar包改成自己的名称,./logs/ctt-auth.log为自定义的日志目录。
    也可以按自己习惯的jar包命令执行。

    3、前端部署
    修改相关配置,运行命令生成dist包文件。
    配置修改:前端ui文件中的index.js文件、vue.config.js文件
    如下图:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述图二下方红线未服务器ip。
    修改后在前端执行 npm run build:prod 生成dist包文件,放在nginx文件下。
    在这里插入图片描述这里的上级目录ctt是自己建的项目名称,改成自己的,下面的nginx配置对应上就好。

    然后是nginx/sbin下的nginx文件配置,可参考若依文档的nginx配置:https://doc.ruoyi.vip/ruoyi-vue/document/hjbs.html#nginx%E9%85%8D%E7%BD%AE
    可以复制链接里nginx配置的代码再进行调整,调整时注意以下红线的3个地方:
    在这里插入图片描述1、服务器项目访问端口:字面意思。
    2、root /home/ruoyi/projects/ruoyi-ui;
    这里是配置前端文件访问路径,ruoyi-ui就相当于生成的dist文件名称,比如我们的dist在ngingx目录下,为ngingx/ctt/dist,路径就改为/ctt/dist。
    3、http://localhost:8080/;
    这个是对应的是后端网关,对应下图标红的路径和端口,在前端代码的vue.config.js文件:

    在这里插入图片描述有时候红线部分用localhost不用服务器ip的话,生成的dist文件部署到服务器上可能会识别不了localhost,就红线部分要改成对应的服务器ip。

    rhou项目启动
    一般后端jar包启动,nginx启动就可以访问部署的项目了。
    在这里插入图片描述

    五、一些坑~

    大多数人过着他人的生活,他们的思想是他人的观点,
    他们的生活是对他人的模仿,他们的热情是一句引言。

    展开全文
  • 第一款真正的任意多物理场直接耦合分析软件COMSOL Multiphysics 中文使用手册。 AC/DC模块(AC/DC Module) 声学模块(Acoustics Module) CAD导入模块(CAD Import Module) 化学工程模块(Chemical Engineering Module) ...
  • swig使用手册

    热门讨论 2013-02-25 11:47:07
    swig使用手册,swig使用必备必备
  • sqlserver使用手册

    热门讨论 2012-04-01 10:47:17
    sqlserver使用手册,使用说明十分详尽,希望能够给大家的工作提供帮助
  • MySQL Workbench使用手册

    2017-01-11 10:24:15
    MySQL Workbench使用手册
  • Loadrunner12中文版用户手册,共1648页,loadrunner一种预测系统行为和性能的负载测试工具。通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner能够对整个企业架构进行测试。企业...
  • STM32F1系列的固件函数库,包含所有使用到的函数介绍,可在写程序时配置,比官方的更容易理解
  • FFmpeg使用手册(FFmpeg官方文档中文翻译).rar
  • Muduo_网络库使用手册

    热门讨论 2014-07-03 15:49:58
    Muduo_网络库使用手册
  • mysql workbench使用手册完整版

    热门讨论 2012-05-08 01:03:10
    史上最权威,官方版mysql使用指导手册,让你轻松掌握mysql workbench从入门到精通全过程,适合新手及专业认识。
  • STM8S固件库使用手册

    热门讨论 2012-04-15 15:08:21
    STM8S系列8位微控制器 固件函数库 version 1.1.0
  • STM32固件库V3.5以及使用手册中文版,参考手册中文,数据手册中文,数据手册有对STM32引脚进行介绍的内容
  • Scikit-learn 使用手册中文版 有监督学习 广义线性模型 11.广义线性模型 英文原文 以下介绍的方法均是用于求解回归问题,其目标值预计是输入变量的一个线性组合。写成数 学语言为:假设!是预测值,则有 y(,x)=0+u1x1+....
  • nginx使用手册chm版

    热门讨论 2012-10-24 11:02:23
    很好的nginx参考手册,大家可以下载下来做工具书用
  • word2016微软官方使用手册

    千次阅读 2020-03-31 15:51:49
    word 2016 微软官方使用文档: https://support.office.com/zh-cn/word word 2016 快捷键汇总及自定义快捷键的方式。 ...
    1. word 2016 微软官方使用文档: https://support.office.com/zh-cn/word
    2. word 2016 快捷键 微软官方
    3. word 2016 自定义快捷键 微软官方:
    4. 参考书籍: 【Office 2016实战技巧精粹辞典】.
    5. 在 word2016 操作说明搜索框中搜索 解决方案
      在这里插入图片描述
      在这里插入图片描述
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 579,456
精华内容 231,782
关键字:

若依使用手册