Рекомендуемая коллекция!!!Руководство по разработке фреймворка Ruoyi [постоянное обновление]

Java задняя часть

титульная страница

автор

голубая рубашка

2940500@qq.com

Нажмите, чтобы ввести адрес обновления документа в режиме реального времени - Code Cloud

Предисловие:

:boom: Давно общаюсь с Ruoyi.От 1.0 до 4.0 давно хотел написать мануал,но не получилось получить хорошую точку входа.В последнее время разрабатываю новую систему и просто используйте контент, с которым вы столкнулись или который использовался в разработке, в качестве точки входа. Написание документов в начале может быть немного запутанным. Сначала напишите их и подготовьте к последующей верстке. Рекомендуется использовать Git, чтобы облегчить обновление в реальном времени документы.

Примечание для студентов, пришедших из CSDN, документация в CSDN больше не поддерживается.

Структура каталога:

Он примерно разделен на внешний и внутренний интерфейс.Внешний интерфейс подробно разделен в соответствии с используемыми страницами добавления, редактирования и списка, а задний конец разделен на три слоя плюс другие специальные элементы контента.

@TOC

внешний интерфейс

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>

Стол

обновить таблицу

// 这是封装好的方法  不需要在去调用原生的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

输入图片说明

пользовательский цвет кнопки

Иногда цвета кнопок, предоставляемые бутстрапом, не могут полностью удовлетворить потребности системы, их всего несколько, поэтому в это время вам нужно добавить пользовательские цвета кнопок.

Ниже приведены два URL-адреса, которые генерируют цвета кнопки начальной загрузки онлайн.

blog.koalite.com/bbg/v2/

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

О значках

Справочная статья

блог woo woo woo.cn на.com/smallmatch…

Woohoo.360doc.com/content/19/…

время форматирования

		/** 合同创建日期 */
		@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);
         }
      },

Увеличить форму Уменьшить функциональные элементы

одна страница

Таблица Ruoyi использует BootstarpTable, а Ruoyi также просто инкапсулирует BootStarpTable.Что делать, если вы хотите удалить кнопки обновления списка загрузок и поиска в правом верхнем углу таблицы?Кроме того, очень просто добавить эти атрибуты и установить для них неверно. :

输入图片说明

Глобальный

оказатьсяry-ui.jsУстановите для этих свойств значение false

输入图片说明

Обратный вызов, выполняемый после завершения инициализации таблицы

По сути, это callback-функция 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>

После того, как таблица исправлена ​​в левом | правом столбце, ошибка, связанная с перекрытием полосы прокрутки, и решение

Найдите строку 224 файла bootstrap-table-fixed-columns.js и вычтите 13 из значения атрибута высоты.

После изменения:

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



разное

цикл JS

Добавить ссылку Этот блогер очень подробно написал

blog.CSDN.net/QQ_41899174…

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 использует всплывающую подсказку для отображения сообщений об ошибках
    
        $("#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");
                }
            },
    
    
        });
    

Увеличить изображение

Иногда изображения, отображаемые для красоты страницы, относительно малы, и вы можете видеть только эскизы, но в некоторых случаях вы хотите увидеть увеличенные изображения.В это время вам нужна функция увеличения изображения.Лаюи не будет их представлять , Вот два других типа.

  • Изображение метода увеличительного стекла (наведите указатель мыши на миниатюру, чтобы увеличить)
  • Всплывающий слой для увеличения изображения (щелкните слой всплывающей маски, чтобы увеличить изображение)

Увеличительное стекло для увеличения:

использоватьjQuery Zoom Pluginплагин

github: GitHub.com/elevate Web/…

Адрес документа:Ууууу, никакой лихорадки ashin.com/elevate 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 //是否开启鼠标滚动 
});

Масштаб всплывающего слоя:

Это всплывающий слой-маска для отображения картинки Тут нечего говорить, просто переходим к коду.

Оригинальная ссылка:blog.CSDN.net/no 0_37865510…

Местоположение миниатюры:

注意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>

Новая вкладка

Если Yi уже инкапсулировал создание новой вкладки, метод JS: createMenuItem()

  1. $.modal.openTab()

    Теперь новая страница меню (createMenuItem) инкапсулирована в ry-ui.js.

    // 方式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 из undefined, не забудьте импортировать common.js. Сгенерированный код будет импортирован по умолчанию.
  2. Запросить случайное из неопределенного для импорта 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");
    });

// common.js增加了一个 closeItem方法
	function closes() {
        // 关闭当前页
    	closeItem();
        // 关闭指定Item页, 123为指定的选项卡Id
        closeItem(123);
	}

блокировка поля ввода

Я думаю, все это знают, давайте напишем еще раз, этот абзац скопирован прямо с сайта.

disabledАтрибут указывает, что элемент ввода должен быть отключен.Отключенный элемент ввода не может быть отредактирован, скопирован или выбран, он не может получить фокус, а фон не получит переданные значения. После настройки цвет текста станет серым. Атрибут 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"Это свойство аналогично отключению. Элемент ввода нельзя редактировать, копировать или выбирать, и он не может получать фокус. После установки цвет текста также станет серым, но значение фона можно получить.

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

открыть страницу

Всплывающие окна

// 弹出添加用户积分日志页面
function open_account_log(userId) {
    // 1. 调用方法弹出
    $.modal.open("用户积分修改", '/system/accountDetailsLog/add');
    // 2. 指定弹窗宽高(后两个参数分别为宽,高)
        $.modal.open("用户积分修改", '/system/accountDetailsLog/add','80','120');

}


JS проверить нулевое значение

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

Событие ввода привязки JS

js связывает событие ввода вместо использования события изменения, которое изменяет значение

Можно выполнять определенные операции после ввода значения вместо срабатывания после потери ввода и затем потери фокуса.

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

Пользовательский AJAX

Вот пример использования кнопки отвязки

Для операции отмены привязки не требуется всплывающее окно. Если инкапсулированный метод модификации вызван напрямую или операция прошла успешно, метод успешной операции закроет всплывающее окно и обновит родительскую страницу, что приведет к глобальному обновлению. таким образом, вы можете выполнить операцию, которую хотите выполнить, в фоновом режиме.Вы можете вывести напоминание о сообщении, не вызывая глобального обновления, только обновить таблицу таблицы.

  // 上传文件
            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("图片上传失败。");
                    }
                });
            }

Добавьте элемент класса

 .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. Дом структура страницы выполнена дома
//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

Этикетка

1.all: удалить содержащий тег и все дочерние элементы. 2.body: не содержит маркера для удаления, но удаляет все его дочерние элементы. 3.tag: содержит удаление тега, но не удаляет его дочерние элементы. 4. все, кроме первого: удалить всех дочерних элементов, содержащих метку, кроме первого. 5.none: ничего не делать. Это значение полезно для динамической оценки.
ключевые слова Функции кейс
th: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 Вопреки суждению <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:fragment th: ветвь переключателя <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:selectd выбранное поле выбора 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}", этот тег выглядит не очень элегантно и обычно используется реже.

цикл

   <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}]])"

Передать несколько параметров в модель

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

Передайте параметр модели и параметр, не относящийся к модели

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>
Другое – веб-статьи

blog.CSDN.net/Zou Bo0812/Ах…

связанные с JQuery

Вернуться на предыдущую страницу

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

задняя часть

система

Текущий пользователь

Операция текущего пользователя, вошедшего в систему, инкапсулирована

Нужно получить текущего вошедшего в систему пользователя, получить текущий идентификатор вошедшего в систему пользователя и т. д. Исходный код здесь не публикуется.

Расположение класса инструмента:

com.ruoyi.framework.util.ShiroUtils

таймер

Таймер выключения

Иногда вам не обязательно использовать таймер, но что делать, если вы хотите кастрировать таймер? Нужно ли удалять много кода, связанного с таймером?Очевидно, что нет необходимости комментировать аннотацию, которую таймер инициализирует при запуске.

输入图片说明

Добавить таймер

输入图片说明

输入图片说明

В «Мониторинг системы» -> «Запланированные задачи» -> «Добавить запланированные задачи».

输入图片说明





Controller

О разрешениях

Если фреймворк использует Shiro для управления разрешениями

Далее описаны операции, которые необходимо выполнить, чтобы добавить адрес запроса в контроллер, а затем сделать этот адрес управляемым.

  1. добавить аннотацию
  2. вставить sql
  3. кнопка управления

Service

Dao

Mapper

инкапсуляция свойств

Нашел интересную статью про инкапсуляцию и возврат, прочитал и записал сюда, прочитаю, когда будет время.

Блог woohoo.cn на.com/Стефан Кинг/…

Когда дело доходит до Mapper, я должен сказать vo инкапсуляция, Прежде чем написать ассоциацию, а затем записать результат соответствующего атрибута, файл mapper полон результатов.

Вот описание других илиДругие файлывнутренний

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

Пример:

Уведомление:

Разница во времени между ассоциацией и коллекцией:

Ассоциация используется в «один к одному», «многие к одному».

Коллекция используется в режимах «один ко многим», «многие ко многим».

В теге ассоциации атрибут javaType указывает наСвойства класса сущностей

Атрибут 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 和空值
    @TableField(strategy = FieldStrategy.IGNORED)
    private BigDecimal discountPrice;

BigDecimal использует

Непосредственно скопированное не будет повторяться.

Учтите, что метод Division Division является перегруженным, и это исключение может возникнуть, если вы напрямую выполняете 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 bigDecimal = new BigDecimal();
int num = bigDecimal.signum();
// num是-1, 负数
// num是0, 零
// num是1,正数

Сравнение размеров


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");
}

Преобразовать строку

  		// 浮点数的打印 10000000000
        System.out.println(new BigDecimal("10000000000").toString());

        // 普通的数字字符串 100.000
        System.out.println(new BigDecimal("100.000").toString());

        // 去除末尾多余的0 1E+2
        System.out.println(new BigDecimal("100.000").stripTrailingZeros().toString());

        // 避免输出科学计数法 100
        System.out.println(new BigDecimal("100.000").stripTrailingZeros().toPlainString());

MYSQL

Получить время

mysql запрос текущего системного времени не сохраняет час, минуту и ​​секунду, сохраняет час, минуту и ​​секунду, добавляет один день к текущему времени, уменьшает текущее время на один день и т. д.

Переслать в CSDNОригинальная ссылка:blog.CSDN.net/Liu_Yulong/…

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