任务描述
基于layui的中后台开发项目,前后端联调,HTML语言编写前端界面,架构更加轻量级,动态组合按钮,并绑定点击事件。以两票考核的预览为例进行说明。
两票考核界面
首先是进行前端的界面设计
list.ftl文件
<!DOCTYPE html>
<html>
<head>
<#include "/head.ftl">
<script>
<#if (tid==360)>
<#assign tpye_disp_str="两票"/>
</#if>
<#if (tid==359)>
<#assign tpye_disp_str="安规"/>
</#if>
</script>
</head>
<body>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-body ">
<form class="layui-form layui-col-space5" id="l_form">
<input type="hidden" value="${ tid!}" name="taskTypeId"/>
<div class="layui-inline layui-show-xs-block">
<input type="text" name="autoId" placeholder="autoId" autocomplete="off"
class="layui-input">
</div>
<div class="layui-inline layui-show-xs-bltock">
<input type="text" name="name" placeholder="请输入任务名称" autocomplete="off"
class="layui-input">
</div>
<div class="layui-inline layui-show-xs-block">
<input type="text" id="startDate_se" style="width: 300px" name="startDate_se" placeholder="请输入任务开始日期范围"
autocomplete="off"
class="layui-input ">
</div>
<div class="layui-inline layui-show-xs-block">
<button class="layui-btn " lay-submit="" lay-filter="sreach"><i
class="layui-icon layui-icon-search"></i>
</button>
</div>
<div class="layui-inline layui-show-xs-block">
<button class="layui-btn layui-btn-primary" id="reset_btn" type="button"><i
class="layui-icon layui-icon-refresh"></i>
</button>
</div>
</form>
</div>
<div class="layui-card-body ">
<@shiro.hasPermission name="business:task:batchRemove">
<button class="layui-btn layui-btn-danger" onclick="batchDelete()"><i
class="layui-icon"></i>批量删除
</button>
</@shiro.hasPermission>
<@shiro.hasPermission name="business:task:add">
<button class="layui-btn "
onclick="parent.xadmin.add_tab('添加${tpye_disp_str!}考核任务','/business/task/add/${ tid!}',true)"><i
class="layui-icon"></i>添加${tpye_disp_str!}考核任务
</button>
</@shiro.hasPermission>
</div>
<div class="layui-card-body ">
<table id="mytable" class="layui-table layui-form" lay-filter="l_table">
</table>
</div>
</div>
</div>
</div>
</div>
<script type="text/html" id="l_toolbar">
<@shiro.hasPermission name="business:task:detail">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="review">预览试卷</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">人员</a>
</@shiro.hasPermission>
<@shiro.hasPermission name="business:task:update">
<a class="layui-btn layui-btn-xs" lay-event="update">编辑</a>
</@shiro.hasPermission>
<@shiro.hasPermission name="business:task:remove">
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="remove">撤销</a>
</@shiro.hasPermission>
</script>
<script>
<#if tid?? >
var rid =${ tid!};
<#else>
var rid = null;
</#if>
</script>
<script type="text/javascript" src="/js/business/task/list.js"></script>
</body>
</html>
list.js文件
var table;
var prefix = "/business/task";
var devflag = layui.data('mis').devflag;
var initWhere = {
"taskTypeId": rid,
"name": "",
"startDate_se":"",
"startDate_s":"",
"startDate_e":""
}
layui.use(['laydate'], function () {
var laydate = layui.laydate;
laydate.render({
// elem: '#dob' //指定元素
elem: '#startDate_se',
type: 'datetime',
range: '~',
trigger: 'click'
});
})
layui.use('table', function () {
table = layui.table;
//第一个实例
table.render({
elem: '#mytable'
, id: 'autoId'
, url: prefix + '/list' //数据接口
, limits: limitsArray
// , loading: true
, where: initWhere
, toolbar: true //开启表格上方工具栏
, defaultToolbar: ['filter', 'exports', 'print']//默认工具
, page: true //开启分页
, cols: [[ //表头
{type: 'checkbox', fixed: 'left'}
, {field: 'autoId', title: 'autoId', minWidth: 90, sort: true, fixed: 'left'}
, {field: 'name', title: '考核任务名称', minWidth: 248, sort: true, fixed: 'left'}
, {field: 'createUserName',minWidth: 140,title: '任务创建人', sort: true}
, {field: 'organname',minWidth: 140, title: '任务创建单位'}
, {
field: 'duration', title: '考试时长(分钟)', sort: true, minWidth: 160, templet: function (d) {
return d.duration / 60000;
}
}
, {field: 'renci', title: '参加任务人数', sort: true, minWidth: 160}
, {field: 'c60', title: '及格人数', minWidth: 110, sort: true}
, {
field: 'jigelv', title: '及格率', minWidth: 110, sort: true
}
, {field: 'minScore', title: '最低分', minWidth: 90, sort: true}
, {field: 'maxScore', title: '最高分', minWidth: 90, sort: true}
, {field: 'avgScore', title: '平均分', minWidth: 90, sort: true}
, {
field: 'startDate', title: '任务开始日期', minWidth: 180, sort: true, templet: function (d) {
return layui.util.toDateString(d.startDate, 'yyyy-MM-dd HH:mm:ss')
}
}
, {
field: 'endDate', title: '任务截止日期', minWidth: 180, sort: true, templet: function (d) {
return layui.util.toDateString(d.endDate, 'yyyy-MM-dd HH:mm:ss')
}
}
, {toolbar: '#l_toolbar', title: '操作', fixed: 'right', width: 278, align: 'center'}
]]
, done: function (data) {
console.log(data);
}
});
table.on('sort(l_table)', function (obj) { //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
// console.log(obj.field); //当前排序的字段名
// console.log(obj.type); //当前排序类型:desc(降序)、asc(升序)、null(空对象,默认排序)
// console.log(this); //当前排序的 th 对象
obj.field = jd_tuofeng(obj.field);
//尽管我们的 table 自带排序功能,但并没有请求服务端。
//有些时候,你可能需要根据当前排序的字段,重新向服务端发送请求,从而实现服务端排序,如:
table.reload('autoId', {
initSort: obj //记录初始排序,如果不设的话,将无法标记表头的排序状态。 layui 2.1.1 新增参数
, where: { //请求参数(注意:这里面的参数可任意定义,并非下面固定的格式)
sort: obj.field //排序字段
, order: obj.type //排序方式
}
});
});
//监听工具条
table.on('tool(l_table)', function (obj) {
var data = obj.data;
if (obj.event === 'detail') {
// layer.msg('ID:' + data.autoId + ' 的查看操作');
jd_show('详情', '/business/taskUser/task/' + data.autoId, 1, 1);
} else if (obj.event === 'remove') {
layer.confirm('真的删除么?', function (index) {
// return;
// obj.del();
$.ajax({
type: 'POST',
data: {
"autoId": data.autoId
},
url: prefix + '/remove',
success: function (r) {
if (r.code == 0) {
layer.msg('删除成功', {icon: 1, time: 1000});
table.reload('autoId', {});
} else {
layer.msg(r.msg);
}
}
});
layer.close(index);
});
} else if (obj.event === 'update') {
// layer.alert('编辑行:<br>' + JSON.stringify(data))
jd_show('编辑', prefix + '/edit/' + data.autoId);
} else if (obj.event === 'review') {
// layer.alert('编辑行:<br>' + JSON.stringify(data))
jd_show('预览试卷', '/business/task/review/' + data.paperId);
}
});
});
layui.use('form', function () {
var form = layui.form;
//监听提交
form.on('submit(sreach)', function (data) {
var formData = data.field;
if (data.field.startDate_se != "") {
var ee = data.field.startDate_se.split("~");
console.log(formData)
var start = new Date(ee[0]);
var end = new Date(ee[1]);
data.field.startDate_s = start.getTime();
data.field.startDate_e = end.getTime();
}
table.reload('autoId', {
where: formData
, page: {curr: 1} //开启分页
});
// layer.msg(JSON.stringify(data.field));
return false;
});
$("#reset_btn").click(function () {
$('#l_form')[0].reset();
table.reload('autoId', {
where: initWhere
, page: true //开启分页
});
})
});
function batchDelete(argument) {
var checkStatus = table.checkStatus('autoId');
var total = checkStatus.data.length
if (total == 0) {
layer.msg('请选择数据!', {icon: 2});
return
}
// debugger;
layer.confirm('确认要删除这' + total + '条数据吗?', function (index) {
var autoIds = new Array();
// 遍历所有选择的行数据,取每条数据对应的ID
$.each(checkStatus.data, function (i, row) {
autoIds[i] = row['autoId'];
});
$.ajax({
type: 'POST',
data: {
"autoIds": autoIds
},
url: prefix + '/batchRemove',
success: function (r) {
if (r.code == 0) {
layer.msg('删除成功', {icon: 1, time: 1000});
table.reload('autoId', {
where: $('#l_form').serialize()
, page: true //开启分页
});
} else {
layer.msg(r.msg);
}
}
});
});
}
jd_show('预览试卷', '/business/task/review/' + data.paperId);
发出url
请求,跳转至Controller
TaskController.java文件
package com.feizhaishui.mis.controller.business;
import cn.hutool.core.date.DateUtil;
import com.feizhaishui.mis.annotation.Log;
import com.feizhaishui.mis.common.Constant;
import com.feizhaishui.mis.controller.BaseController;
import com.feizhaishui.mis.domain.PaperDO;
import com.feizhaishui.mis.domain.TaskDO;
import com.feizhaishui.mis.domain.vo.PaperQuesVO;
import com.feizhaishui.mis.domain.vo.TaskUserVO;
import com.feizhaishui.mis.domain.vo.TaskVO;
import com.feizhaishui.mis.service.*;
import com.feizhaishui.mis.utils.Query;
import com.feizhaishui.mis.utils.Rs;
import com.feizhaishui.mis.utils.TpUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@Controller
@RequestMapping("/business/task")
public class TaskController extends BaseController {
private final static Logger logger = LoggerFactory.getLogger(TaskController.class);
@Autowired
private TaskService taskService;
@Autowired
private TaskUserService taskUserService;
@Autowired
private ImagesService imagesService;
@Autowired
private PaperService paperService;
@Autowired
private PaperQuesService paperQuesService;
@GetMapping("/review/{autoId}")
@Log("预览两票考核试卷")
@RequiresPermissions("business:task:detail")
String tPiaoReview(@PathVariable("autoId") Long autoId, Model model) {
PaperDO theObj = paperService.get(autoId);
List<PaperQuesVO> ques = paperQuesService.listVoByPaperId(autoId);
model.addAttribute("theObj", theObj);
model.addAttribute("autoId", autoId);
model.addAttribute("ques", ques);
// if (theObj.getPaperTypeId() == Constant.ANGUI_ID) {
if (theObj.getPaperTypeId() == 359L) {
Collection<List<PaperQuesVO>> hl = TpUtils.getPaperQuesVOList(ques);
model.addAttribute("hl", hl);
return "/business/paper/angui_review";
} else if (theObj.getPaperTypeId() == 360L) {
return "/business/paper/tpiao_review";
} else {
return null;
}
}
}
跳转至tpiao_review.ftl
tpiao_review.ftl
<!DOCTYPE html>
<html>
<head>
<#include "/head.ftl">
<#-- <script type="text/javascript" src="/lib/template-web.js"></script>-->
<#-- <script type="text/html" id="paperTemplate">-->
<#-- <form class="layui-form">-->
<#-- {{each data piao index}}-->
<#-- <div class="layui-btn-group">-->
<#-- <button id="" type="button" class="layui-btn"> 票{{piao.order}}预览 </button>-->
<#-- </div>-->
<#-- {{/each}}-->
<#-- </form>-->
<#-- </script>-->
</head>
<body>
<script>
var autoId=${autoId!0};
</script>
<div class="layui-fluid">
<div class="layui-row">
<fieldset class="layui-elem-field">
<legend><b>${ theObj.name!}(ID:${theObj.autoId!})</b></legend>
<div class="layui-field-box" style="text-align: center">
满分:${ theObj.fullScore!} 及格分:${ theObj.passScore!}
</div>
<div class="layui-field-box" style="text-align: center">
出卷人:${ theObj.createUserName!}
出卷时间:${ theObj.createDate?datetime}
</div>
<#-- <div class="layui-card-body" id="setTab">-->
<#-- </div>-->
<div class="layui-card-body" >
<div class="layui-btn-group">
<#list ques as q>
<button type="button" class="loadpiao layui-btn layui-btn-sm <#if q_index!=0>layui-btn-primary</#if> " pid="${q.quesId}">票${q_index+1}(${q.score}分)</button>
</#list>
</div>
</div>
</fieldset>
<iframe onload="setHeight()" width=100% id="my-iframe" marginheight="0" frameborder="no" height="1" src="/business/tpiao/p_review?autoId=${ques[0].quesId}&flag=preview" scrolling="no"></iframe>
</div>
</div>
<script type="text/javascript" src="/js/business/paper/tpiao_review.js"></script>
</body>
</html>
tpiao_review.js
在js
中写入
var prefix = "/business/paper";
var tags=[];
var step = 111;
var table;
var dataPiao = [];
var order= [];
var piaoId= [];
$(".loadpiao").click(function () {
console.log($(this).attr("pid"))
$(".loadpiao").addClass("layui-btn-primary");
$(this).removeClass("layui-btn-primary")
$('#my-iframe').attr( 'src','/business/tpiao/p_review?autoId=' + $(this).attr("pid") + '&flag=preview')
})
// $.ajax({
// id: 'autoId'
// ,url: '/business/paper/listById/'+autoId //数据接口
// ,success: function (result) {
// if(result.code==0){
// console.log(result);
// var counts = result.data.length;
// for(var i=0;i<counts;i++){
// dataPiao[i] = {autoIds:result.data[i].autoId, order:i+1};
// piaoId[i]=dataPiao[i].autoIds;
// console.log(dataPiao[i].autoIds);
// }
//
// var htmldata = template("paperTemplate",{data:dataPiao});
// var container = document.querySelector("#setTab");
// container.innerHTML=htmldata;
// document.getElementById('my-iframe').setAttribute('src','/business/tpiao/p_review?autoId=' + dataPiao[0].autoIds + '&flag=' + 'preview');
// let btns=document.querySelectorAll("button");
// for (let j= 0; j <btns.length; j++) {
// //为每个按钮都要注册点击事件
// btns[j].onclick = function () {
// document.getElementById('my-iframe').setAttribute('src','/business/tpiao/p_review?autoId=' + dataPiao[j].autoIds + '&flag=' + 'preview');
// };
// }
// }
// }
// });
function getIframeWindow(obj) {
return obj.contentWindow || obj.contentDocument.parentWindow;
}
function getIframeHeight(obj){
var idoc = getIframeWindow(obj).document;
if(idoc.body){
return Math.max(idoc.body.scrollHeight,idoc.body.offsetHeight);
}else if(idoc.documentElement){
return Math.max(idoc.documentElement.scrollHeight,idoc.documentElement.offsetHeight);
}
}
function setHeight(){
var myiframe = document.getElementById("my-iframe");
myiframe.height = getIframeHeight(myiframe);
}
效果