首页
作者
青衫
前言:
:boom:接触若依也很长时间了从1.0到现在的4.0 期间一直想写个手册 但一直没有很好地切入点 最近在开发新系统 正好根据开发中遇到或者使用到的内容作为切入点来进行写文档 可能会有些混乱 一开始先写上准备后续再排版精修 推荐Git拉取,方便文档实时更新
CSDN过来的同学注意 文档已经停止在CSDN的维护
目录结构:
大致分为前端、后端,前端根据使用的页面add、edit、list来进行详细划分,后端根据三层加上其他特殊内容点划分
@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 为字典类型值 字典类型值一般为表名字段名来命名防止出现重复
时间框
根据开始时间结束时间搜索
如果使用的是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') >= 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
自定义按钮颜色
有时候bootstrap提供的按钮颜色并不能完全满足系统的需要 只有仅限的几个 所以在这时候需要增加自定义的按钮颜色
下边是两个在线生成bootstrap按钮颜色的网址
twitterbootstrap3buttons.w3masters.nl/
以下为增加一个紫色按钮的示例
-
创建一个.css文件
-
将下方的css复制到css文件中
-
页面引入该css文件
-
页面创建个按钮
-
<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>
关于徽章
参考文章
格式化时间
/** 合同创建日期 */
@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循环
添加个链接这个博主写的很详细
validator
-
动态校验提示信息
来源:
$.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'); });
-
清空提示信息
$("#form-consignor-add").validate().resetForm();
-
单独校验指定输入框
-
// 某个表单里的指定行 $("#form-xxx").validate().element($("#xxx"))
-
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: github.com/elevateweb/…
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 //是否开启鼠标滚动 });
弹出层放大:
这个就是弹出一个遮罩层 显示图片 没什么好说的直接是上代码吧
缩略图位置:
注意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()
-
$.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>
-
createMenuItem
// 要打开的地址
var url=prefix+"/details?userId="+userId;
// 调用createMenuItem()方法 1参:要打开的地址 ,2参:标签页名称
createMenuItem(url, "用户详情");
注意:
- 如果提示调用 createMenuItem of undefined 那就记得引入 common.js 生成的代码里默认会引入
- 提示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");
});
// common.js增加了一个 closeItem方法
function closes() {
// 关闭当前页
closeItem();
// 关闭指定Item页, 123为指定的选项卡Id
closeItem(123);
}
输入框锁定
这个相信大家都会 还是再写一下吧 这段话是从网站上直接复制过来的
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) {
// 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绑定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代码块 分为两种方式隐藏
- style="visibility: hidden;" (隐藏但是位置会占用)
- 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();// 显示
页面加载完成执行
页面加载完成执行有两种加载时机
- 页面所有资源加载完成后执行 (包括图片或者其他资源)
- 页面的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
标签
1.all:删除包含标签和所有的孩子。2.body:不包含标记删除,但删除其所有的孩子。3.tag:包含标记的删除,但不删除它的孩子。4.all-but-first:删除所有包含标签的孩子,除了第一个。5.none:什么也不做。这个值是有用的动态评估。关键字 | 功能介绍 | 案例 |
---|---|---|
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:fragment | th: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:selectd | selected选择框选中 | 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}]])"
传递多个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>
其他-网络文章
JQuery相关
返回上页
function goBack() {
window.history.go(-1);
}
后端
系统
当前用户
对当前登录用户的操作已经进行了封装
有获取当前登陆用户 获取当前登录用户ID 等这里不贴源码了
该工具类位置:
com.ruoyi.framework.util.ShiroUtils
定时器
关闭定时器
有时候定时器大家并不一定需要用到 又想把定时器阉割掉 时怎么做呢? 难道要删大量的定时器相关代码吗? 很显然不需要只需要将定时器在启动时初始化的注解注释掉就可以了
新增定时器
在系统监控 --> 定时任务 -->新增定时任务
Controller
关于权限
若依框架使用的是Shiro来进行权限控制
下边介绍一下在Controller新增一个请求地址 然后使这个地址被管理需要做那些操作
- 添加注解
- 插入sql
- 按钮控制
Service
Dao
Mapper
属性封装
发现一篇很有意思的关于封装返回的文章 大概看了一下 这里记录一下 有时间再看
说到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 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");
}
转String
// 浮点数的打印 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;
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;