建议收藏!!! 若依框架文档开发手册[持续更新]

首页

作者

:青衫

✉️ :[email protected]

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

前言:

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

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

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

目录结构:

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

若依开发手册

  • 首页
  • 前端
    • add.html
        • 下拉列
        • 时间框
        • 大文本框
        • Ajax校验
        • 自定义校验
        • 回显选中图片
    • edit.html
        • 下拉列
        • 回显时间
    • list.html
      • 搜索栏
        • 下拉列
        • 时间框
      • Table表格
        • 刷新表格
        • 按钮颜色
        • 关于徽章
        • 格式化时间
        • 设置默认排序列
        • 表格匹配字典值
        • 表格增加.减少功能项
            • 单页
            • 全局
    • 其他
        • JS循环
        • 放大图片
        • 新建标签页
        • 关闭标签页
        • 输入框锁定
        • 弹出某页面
        • JS校验空值
        • 自定义AJAX
        • 添加Class元素
        • 操作结果提示
        • 回显选中图片
        • JS创建集合对象
        • 显示隐藏HTML
        • 页面加载完成执行
        • 默认全屏打开添加页
    • Thymeleaf
        • 标签
        • 循环
        • 判断
        • JS取值
        • th:onclick
        • 格式化时间
        • 截取字符串
          • 其他-网络文章
    • JQuery相关
        • 返回上页
  • 后端
    • 系统
      • 当前用户
      • 定时器
          • 关闭定时器
          • 新增定时器
    • Controller
      • 关于权限
    • Service
    • Dao
    • Mapper
        • 属性封装
        • 集合遍历
          • 单参数
          • 多参数:
    • 其他
        • MP忽略null值
        • BigDecimal使用
    • MYSQL
        • 获取时间

前端

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: [青衫] '[email protected]'
 * @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,
            },
        
        }
    });

建议收藏!!! 若依框架文档开发手册[持续更新]_第1张图片

回显选中图片

在下方已经写过了

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

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

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

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>

建议收藏!!! 若依框架文档开发手册[持续更新]_第2张图片

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>
          
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') >= date_format(#{params.beginTime},'%y%m%d')
if>

<if test="params.endTime != null and params.endTime  !='' ">
      AND date_format(xxxxx,'%y%m%d') <= 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

建议收藏!!! 若依框架文档开发手册[持续更新]_第3张图片

关于徽章

参考文章

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",

例:

建议收藏!!! 若依框架文档开发手册[持续更新]_第4张图片

表格匹配字典值

 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即可:

建议收藏!!! 若依框架文档开发手册[持续更新]_第5张图片

全局

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

建议收藏!!! 若依框架文档开发手册[持续更新]_第6张图片





其他

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"/>

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属性  
      
            /*获取当前点击图片的真实大小,并显示弹出层及大图*/  
        $("").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="text" disabled="disabled" />

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

// readonly 属性可与  配合使用。
示例:<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'> hellospan>
 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
th:text 文本替换

description

th:utext 支持html的文本替换

content

th:object 替换对象
th:value 属性赋值
th:with 变量赋值运算
th:style 设置样式
th:onclick 点击事件
th:each 属性赋值循环
th:if 判断条件
th:unless 和th:if判断相反 Login
th:href 链接地址 Login
th:switch 多路选择配合th:case使用
th:fragment th:switch的一个分支

User is an administrator

th:includ 布局标签,替换内容到引入的文件
th:replace 布局标签,替换整个标签到引入的文件
th:selectd selected选择框选中 th:selected="(${xxx.id} == ${configObj.dd})"
th:src 图片类地址引入 App Logo
th:inline 定义js脚本可以使用变量

你可能感兴趣的:(若依框架)