layui2--SSM--网上订餐系统
- 如果想看用servelet和layui写的图书管理系统的话,请参考我的上一篇文章:链接地址.
- 作者在写这篇文章时还只是小白,目的是为了巩固知识,意料之内的写的不好,请多谅解.
- 本文只是扩展一些要记的和一些项目中的问题,仅有助于作者本人,请多谅解.
开始(layui部分)
当弹出层的type为1时,也就是content需要自己写时最好加上body,并且body可以直接用layero赋值,还有弹出层的渲染问题,详情见下面代码。
layer.open({
type: 1 ,//Page层类型,
btn: ['确定'],
area: ['400px', '200px'],
offset: '100px',
title: '<li id="icon" class="layui-icon layui-icon-release layui-anim layui-anim-scaleSpring" ' +
'style="font-size: 30px; color: #009688;" data-anim="layui-anim-scaleSpring"></li> 请填写信息',
shade: 0.6, //遮罩透明度
maxmin: true, //允许全屏最小化
anim: 1, //0-6的动画形式,-1不开启
content: '<body>'+'<div>'+
'</div>'+'</body>',
success:function(layero, index){
//或者使用 body = layer.getChildFrame('body',index);
//对弹出层一些元素如,CheckBox的渲染需要以下两行代码渲染
//获取新窗口对象
var iframeWindow = layero.find('iframe')[0].contentWindow;
//重新渲染
frameWindow.layui.form.render();
body = layero;
},
yes:function(layero, index){
var value = body.find("#value").val();
}
});
如果你只需要使用到layui的弹出层,并把弹出事件绑定到一个button的onclick事件上时,你需要以下的操作:
function onclick()
{
layui.use(['layer','form'], function(){
var layer = layui.layer; //弹层
var $ = layui.$;
layer.ready(function(){
var body;
//如果你弹出层的背景不只是要iframe当背景时,可以加上parent
parent.layer.open({
}
});
});
}
layui的提示
//提示内容(5是失败提示,6是成功)
parent.layer.msg("message", {icon: 5});
//关闭全部后刷新表格,testReload是table.render()上的id属性
layer.closeAll();
table.reload('testReload', {
where: {
//里面穿条件
}
});
//删除提示
layer.confirm('确定删除该行么', function(index){
btn: ['按钮1', '按钮2', '按钮3'], //可以无限个按钮,如果没写默认事件只有yes
yes: function(index, layero){
//需要手动关闭弹出层
},btn2:function(index, layero){
//不需要手动关闭
},btn3:function(index, layero){
//不需要手动关闭,依次类推...
}
}
关于layui的表格一些扩展,包括加入图片,绑定字段事件,字段显示处理
table.render({
elem: '#dishTable',
url: BASE_PATH+'/dishCtrl/queryAllDishMessage.do',
page:true, //开启分页
id: 'testReload',
//修改传入数据的字段名
response: {
statusName: 'status', //数据状态的字段名称,默认:code
statusCode: 200,//成功的状态码,默认:0
msgName: 'messages',//状态信息的字段名称,默认:msg
countName: 'count', //数据总数的字段名称,默认:count
dataName: 'data' //数据列表的字段名称,默认:data
},
done: function(res, curr, count) { //表格数据加载完后的事件
//调用示例
layer.photos({//点击图片弹出
photos: '.layer-photos-demo',
anim: 1 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
});
},
cols: [[ //表头
{type: 'checkbox', fixed: 'left'},
//隐藏字段
{field: 'dishTypeId',hide:true},
//图片加载 (需要更改css样式,后面贴)
{field:'dishImg', title: '图片', width:110,templet:function (d) {
var str = d.dishImg + "";
var dishImg = BASE_PATH + str.substring(14,str.length);
return '<div class="layer-photos-demo" style="cursor:pointer;">' +
'<img src="' + dishImg + '" width="80px" height="100px"></div>';
}},
//更改字段颜色,并绑定时间
{field: 'orderState', title: '状态', width:100,templet: function(res){
if(res.orderState == "1"){
//lay-event事件依旧在table.on('tool()', function(obj){if(obj.event === '')});中实现
return '<a style="color:green" href="javaScript:void(0);" lay-event="orderCtrl"></a>';
}
}},
{field:'right',title: '操作', align:'center', toolbar: '#bar' }
]],
page: {
layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'], //自定义分页布局
groups: 1, //只显示 1 个连续页码
first: '首页', //不显示首页
last: '末页', //不显示尾页
limit:5,
limits:[1,2,3,4,5,6,7,8,9,10]
}
});
以上table操作需要修改css(添加了一些自己用的,让table具有立体感)
<style type="text/css">
.layui-table-box{
box-shadow: 0 -1px 8px rgba(0,0,0,.3);
background:#ffffff;
}
.layui-table th{
font-weight: 800
}
.layui-card-body{
box-shadow: 0 -1px 8px rgba(0,0,0,.3);
background:#ffffff;
}
.layui-card-header{
padding: 0px 0px 0px 0px;
height:100%;
padding: 10px
}
.layui-form layui-border-box layui-table-view{
padding-left: 10px
}
.layui-table-cell .layui-form-checkbox[lay-skin="primary"]{
top: 50%;
transform: translateY(-50%);
}
//如果只满足于图片或者改变table行号只要写下面的就行
.layui-table-cell{
height:100px;
line-height: 100px;
}
</style>
layui外部事件监听(下拉框,搜索框)
$('.layui-card-body .layui-btn').on('click', function(){
var type = $(this).data('type');
active[type] ? active[type].call(this) : '';
});
//搜索框
$("#key").bind('input propertychange', function () {
table.reload('testReload', {
where: {
key: $('#key').val()
}
});
});
//下拉框
form.on('select(dishTypeId)', function(data){
var key = $('#key').val();
var dishTypeId = $('#dishTypeId').val();
table.reload('testReload', {
page: {
curr: 1 //重新从第 1 页开始
},
where: {
key: key,
dishTypeId: dishTypeId
}
});
});
其他一些东西
前台的时间戳处理(需要扩展data)
Date.prototype.format = function(format)
{
var o = {
"M+" : this.getMonth()+1, //month
"d+" : this.getDate(), //day
"h+" : this.getHours(), //hour
"m+" : this.getMinutes(), //minute
"s+" : this.getSeconds(), //second
"q+" : Math.floor((this.getMonth()+3)/3), //quarter
"S" : this.getMilliseconds() //millisecond
}
if(/(y+)/.test(format)) format=format.replace(RegExp.$1,
(this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)if(new RegExp("("+ k +")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length==1 ? o[k] :
("00"+ o[k]).substr((""+ o[k]).length));
return format;
}
//字段操作
{
field: 'createTime', title: '创建时间', width:200,templet: function(res){
var a = new Date(res.createTime).format("yyyy-MM-dd");
return a;
}},
有关图片上传
/**
* @description: 图片上传
* @createTime: 2018年10月26日 上午9:02:29
* @author: huang.weikun
* @param file
* @param request
* @param userId
* @return
*/
@RequestMapping(value = "/uploadDishImg",method=RequestMethod.POST)
@ResponseBody
public Map<String,Object> uploadDishImg(@RequestParam("file") MultipartFile file,
HttpServletRequest request,String dishId) {
Map<String,Object> map = new HashMap<String,Object>();
try {
String filename = file.getOriginalFilename();
String suffix = filename.substring(filename.lastIndexOf("."));
String savename = UUIDUtil.getUUID()+suffix;
String path = "/dishImg/"+ DateUtil.formatDate(new Date(), "yyyyMMdd");
String realpath = request.getSession().getServletContext().getRealPath(path);
File dir = new File(realpath);
if (!dir.exists()) {// 判断文件目录是否存在
dir.mkdirs();
}
String filePath = "";
if (!file.isEmpty()) {
// 文件保存路径
filePath = realpath +"/"+ savename;
// 转存文件
file.transferTo(new File(filePath));
}
DishPO dish = null;
dish = sysDishService.getDishById(dishId);
if(dish != null){
//编辑
dish.setDishImg("/TakeoutSystem/"+path+"/"+ savename);
sysDishService.update(dish);
}else{
//新增
dish = new DishPO();
dish.setDishId(dishId);
dish.setDishImg("/TakeoutSystem/"+path+"/"+ savename);
dish.setCreateTime(System.currentTimeMillis());
sysDishService.insert(dish);
}
map.put("code", 0);
} catch (Exception e) {
map.put("code", 1);
e.printStackTrace();
}
return map;
}
在做这个项目中遇到的问题
- 场景:用户点菜,但是没有默认的收货地址,需要判断如果没有默认的地址话直接跳转到添加地址页面,但是地址在iframe中
$(document).ready(function(){
var isAddress = $('#isAddress').val();
if(isAddress != null && isAddress == "no"){
$('#iframe').attr('src',BASE_PATH+"backCtrl/addressMessgae.do");
}
if(isAddress != null && isAddress == "yes"){
$('#iframe').attr('src',BASE_PATH+"backCtrl/completeOrderMessage.do");
}
});
- 场景:图片的懒加载问题,用户进入主页后先加载一个菜系(重点是在后台查询完成之后用StringBuffer拼成html代码传到前台)
layui.use('flow', function(){
var flow = layui.flow;
flow.load({
elem: '#dishimg2' //流加载容器(div的id)
scrollElem: '#dishimg2'
isAuto: false
isLazyimg: true
done: function(page, next){ //加载下一页
//模拟插入
setTimeout(function(){
var lis = [];
$.ajax({
url: BASE_PATH+'dishCtrl/getDishImg.do',
async:false,
type: "POST",
data:{
id:page
},
dataType: "json",
success: function(data){
lis.push(data.data);
},
error: function()
{
}
});
next(lis.join(''), page < 8); //假设总页数为 8
}, 500);
}
});
});
有关前台需要展示的代码块需要后台查询需要的数据,之后拼接成html代码,这里给出关键语句
StringBuffer url = request.getRequestURL();
//获取路径
String BASE_PATH = url.delete(url.length() - request.getRequestURI().length(),
url.length()).append(request.getContextPath()).append("/").toString();
- 如果SQL语句有用到多个or(如在搜索框里可以用多个条件查询)则and 后面的or语句需要用括号括起来
- 一些数据库操作的语句
<where>
<if test="">
</if>
<choose>
<when test="">
</when>
<otherwise>
</otherwise>
</choose>
</where>
//更据create_time 降序排序 并且分页
//这里的分页是指从page个开始查询limit个 所以传入的page要进行处理 int newpage = (page-1)*limit;
ORDER BY table.create_time desc limit #{page},#{limit}