fullcalendar 日历插件的使用
【需求】:使用 fullcalendar日历插件,完成如下功能:可以进行拖动,点击空白处添加,双击后修改和删除等功能。API 链接
一、html 文件中引入相关依赖,主要包括引入的 css和 js;
1 <!DOCTYPE html> 2 <html lang="zh_CN" xmlns:th="http://www.thymeleaf.org" 3 xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> 4 <meta charset="utf-8"> 5 <head th:include="include :: header"></head> 6 <body class="gray-bg"> 7 <div class="wrapper wrapper-content "> 8 <div class="col-sm-12"> 9 <div class="ibox"> 10 <div class="ibox-body"> 11 <div class="fixed-table-toolbar"> 12 <div class="columns pull-left col-md-2 nopadding"> 13 <input id="orgCode2" name="orgCode2" th:value="${orgCode2}" type="hidden"> 14 <select id="filter_orgCode" name="filter_orgCode" class="form-control" type="text" required="true"> 15 <option> </option> 16 </select> 17 <div class="error-msg"></div> 18 </div> 19 20 <div class="columns pull-left"> 21 <button class="btn btn-success" type="button" class="btn btn-primary" onclick="reloadCalendar()" id="btnSearch"> 22 <i aria-hidden="true"></i>查询 23 </button> 24 <button shiro:hasPermission="centerInfo:personSchedul:add" type="button" class="btn btn-primary" onclick="add()"> 25 <i class="fa fa-plus" aria-hidden="true"></i>添加排班 26 </button> 27 <!--<button shiro:hasPermission="centerInfo:personSchedul:batchRemove" type="button" class="btn btn-danger" 28 onclick="batchRemove()"> 29 <i class="fa fa-trash" aria-hidden="true"></i>批量删除 30 </button>--> 31 </div> 32 <div class="columns pull-left"> 33 <span style="font-size: 9px;">说明:点击单元格空白处,可添加排班;双击单条排班可编辑和删除</span> 34 </div> 35 </div> 36 <div id="senscloud-container" class="form-group table-contain senscloud-container" 37 style="border-top: solid 1px #EDEEF2;"> 38 <div style="padding: 10px 0;"> 39 <div id='calendar' class="col-xs-12"></div> 40 </div> 41 </div> 42 </div> 43 </div> 44 </div> 45 </div> 46 <!--shiro控制bootstraptable行内按钮看见性 来自bootdo的创新方案 --> 47 <div> 48 <script type="text/javascript"> 49 var s_edit_h = 'hidden'; 50 var s_remove_h = 'hidden'; 51 var s_resetPwd_h = 'hidden'; 52 </script> 53 </div> 54 <div shiro:hasPermission="centerInfo:personSchedul:edit"> 55 <script type="text/javascript"> 56 s_edit_h = ''; 57 </script> 58 </div> 59 <div shiro:hasPermission="centerInfo:personSchedul:remove"> 60 <script type="text/javascript"> 61 var s_remove_h = ''; 62 </script> 63 </div> 64 <div shiro:hasPermission="centerInfo:personSchedul:resetPwd"> 65 <script type="text/javascript"> 66 var s_resetPwd_h = ''; 67 </script> 68 </div> 69 </div> 70 <div th:include="include :: footer"></div> 71 <link th:href="@{/css/plugins/fullcalendar/fullcalendar.css}" rel='stylesheet'/> 72 <link th:href="@{/css/plugins/fullcalendar/fullcalendar.print.css}" rel='stylesheet' media='print'/> 73 <link th:href="@{/css/bootstrap.min.css}" rel='stylesheet' type="text/css"/> 74 <script type="text/javascript" th:src="@{/js/plugins/jquery-ui/jquery-ui.min.js}"></script> 75 76 <script type="text/javascript" th:src="@{/js/plugins/fullcalendar/moment.min.js}"></script> 77 <script type="text/javascript" th:src="@{/js/plugins/fullcalendar/fullcalendar.min.js}"></script> 78 79 <link th:href="@{/css/plugins/bootstrap-timepicker/bootstrap-timepicker.min.css}" rel='stylesheet'/> 80 <script type="text/javascript" th:src="@{/js/plugins/bootstrap-timepicker/bootstrap-timepicker.min.js}"></script> 81 <script type="text/javascript" th:src="@{/js/plugins/datapicker/bootstrap-datepicker.js}"></script> 82 <script type="text/javascript" th:src="@{/js/appjs/centerInfo/perSchedul/personSchedul.js}"></script> 83 </body> 84 </html>
二、js 中使用 fullCalendar 插件完成该功能
1 var prefix = "/dms/centerInfo/personSchedul" 2 /** 3 * 在页面加载此js文件 4 * 使用例:new Date().format("yyyy-MM-dd hh:mm:ss") 5 */ 6 Date.prototype.format = function (fmt) { 7 var o = { 8 "M+": this.getMonth() + 1, //月份 9 "d+": this.getDate(), //日 10 "h+": this.getHours(), //小时 11 "m+": this.getMinutes(), //分 12 "s+": this.getSeconds(), //秒 13 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 14 "S": this.getMilliseconds() //毫秒 15 }; 16 if (/(y+)/.test(fmt)) { 17 fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 18 } 19 for (var k in o) { 20 if (new RegExp("(" + k + ")").test(fmt)) { 21 fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 22 } 23 } 24 return fmt; 25 } 26 27 var myCalendar; 28 var nextWeek = new Date(); 29 var tomorrow = new Date(); 30 nextWeek.setDate(nextWeek.getDate() + 7); 31 tomorrow.setDate(tomorrow.getDate() + 1); 32 33 var tomorrowWord = tomorrow.format('yyyy-MM-dd'); 34 var nextWeekWord = nextWeek.format('yyyy-MM-dd'); 35 $(function() { 36 37 //下拉框 orgcode 赋值 38 $("#filter_orgCode").select2({ 39 data:getOrgCode(), 40 placeholder:"请选择", 41 allowClear:true, 42 language:"zh-CN" 43 }).val($("#orgCode2").val()).trigger("change"); 44 45 //如果分拨编码为空,说明是超级管理员,可以进行下拉选择,否则不允许修改 46 if($("#filter_orgCode").val() != null && $("#filter_orgCode").val() != ""){ 47 $("#filter_orgCode").attr("disabled",true); 48 } 49 50 //查询条件进行复制 51 $('.timepicker').timepicker({ 52 defaultTime: '9:00', 53 showMeridian: false, 54 minuteStep: 1 55 }); 56 myCalendar = $("#calendar").fullCalendar({ 57 header: { 58 left: '', 59 center: 'title', 60 right: 'today prev,next' 61 }, 62 height: window.parent.document.body.clientHeight - 180, 63 windowResize: function (view) { 64 $('#calendar').fullCalendar('option', 'height', window.parent.document.body.clientHeight - 180); 65 }, 66 fixedWeekCount: false, 67 locale: getNowLanguage(1).toLowerCase(), 68 //设置是否可被单击或者拖动选择 69 selectable: true, 70 //点击或者拖动选择时,是否显示时间范围的提示信息,该属性只在agenda视图里可用 71 selectHelper: true, 72 //点击或者拖动选中之后,点击日历外的空白区域是否取消选中状态 true为取消 false为不取消,只有重新选择时才会取消 73 unselectAuto: true, 74 events: function (start, end, callback) { 75 var submitGroup = $("#filter_orgCode").val().toString(); 76 if (myCalendar != null && myCalendar != undefined) { 77 serachCalendarWorkSchedule(submitGroup, start, end, callback); 78 } 79 }, 80 eventClick: function (event) { 81 //当点击日历中的某一日程(事件)时,触发此操作,编辑人员排版 82 //edit(event.id) 83 }, 84 dayClick: function (date, allDay, jsEvent, view) { 85 //当单击日历中的某一天时,触发callback,添加人员排版 86 add(date); 87 }, 88 //Event是否可被拖动或者拖拽 89 editable: true, 90 //Event被拖动时的不透明度 91 dragOpacity: 0.6, 92 eventDrop: function (event, dayDelta, minuteDelta, allDay, revertFunc) {//当拖拽完成并且时间改变时触发 93 var color = event.backgroundColor; 94 if(color=='#E0FFFF'){ 95 layer.alert("已过期排班不能拖动!", {skin:'layui-layer-red',closeBtn:0,icon:2}); 96 revertFunc(); //恢复原状 97 return; 98 } 99 $.ajax({ 100 type : 'POST', 101 url: prefix+"/dropView", 102 data: { 103 "dayDelta": dayDelta, 104 "id": event.id 105 }, 106 dataType: "json", 107 success: function (data) { 108 reloadCalendar(); 109 } 110 }); 111 }, 112 eventRender: function (event, element) { 113 //alert("eventRender") 114 }, 115 eventAfterRender: function (event, element, view) { 116 $(element).on("dblclick", function () { 117 //双击触发该事件 118 edit(event.id); 119 }); 120 }, 121 eventResize: function (event, dayDelta, revertFunc) { 122 //alert("eventResize") 123 }, 124 }); 125 126 $("#beginDay").datepicker({ 127 format: 'yyyy-mm-dd',//显示格式 128 todayHighlight: 1,//今天高亮 129 autoclose: 1,//选择后自动关闭 130 minView: 1, 131 language: getNowLanguage(1) 132 }); 133 $("#endDay").datepicker({ 134 format: 'yyyy-mm-dd',//显示格式 135 todayHighlight: 1,//今天高亮 136 autoclose: 1,//选择后自动关闭 137 minView: 1, 138 language: getNowLanguage(1) 139 }); 140 141 $("#beginDay").val(tomorrowWord); 142 $("#endDay").val(nextWeekWord); 143 144 $(document).keyup(function (event) {//回车查询 145 if (event.keyCode == 13) { 146 $("#btnSearch").trigger("click"); 147 } 148 }); 149 }); 150 151 //重新加载日历中的信息 152 reloadCalendar = function () { 153 myCalendar.fullCalendar('refetchEvents'); 154 } 155 156 //添加员工排班 157 function add(date) { 158 layer.open({ 159 type : 2, 160 title : '添加排班', 161 maxmin : true, 162 shadeClose : false, // 点击遮罩关闭层 163 area : [ '800px', '520px' ], 164 content : prefix + '/add' +"?date=" + date // iframe的url 165 }); 166 } 167 168 //批量删除 169 function batchRemove() { 170 var rows = $('#exampleTable').bootstrapTable('getSelections'); // 返回所有选择的行,当没有选择的记录时,返回一个空数组 171 if (rows.length == 0) { 172 layer.msg("请选择要删除的数据"); 173 return; 174 } 175 layer.confirm("确认要删除选中的'" + rows.length + "'条数据吗?", { 176 btn : [ '确定', '取消' ] 177 // 按钮 178 }, function() { 179 var ids = new Array(); 180 // 遍历所有选择的行数据,取每条数据对应的ID 181 $.each(rows, function(i, row) { 182 ids[i] = row['id']; 183 }); 184 $.ajax({ 185 type : 'POST', 186 data : { 187 "ids" : ids 188 }, 189 url : prefix + '/batchRemove', 190 success : function(r) { 191 if (r.code == 0) { 192 layer.msg(r.msg); 193 reLoad(); 194 } else { 195 layer.msg(r.msg); 196 } 197 } 198 }); 199 }, function() { 200 201 }); 202 } 203 204 //将数据库的时间戳转成 *年*月*日 字符串 205 function getDate(DBTime){ 206 var date = new Date(DBTime); 207 var year = date.getFullYear(); 208 var month = date.getMonth()+1; 209 var day = date.getDate(); 210 var dateStr; 211 if(month<10&&day<10){ 212 dateStr = year+"-0"+month+"-0"+day; 213 }else if(month<10&&day>=10){ 214 dateStr = year+"-0"+month+"-"+day; 215 }else if(month>=10&&day<10){ 216 dateStr = year+"-"+month+"-0"+day; 217 }else if(month>=10&&day>=10){ 218 dateStr = year+"-"+month+"-"+day; 219 } 220 return dateStr; 221 } 222 223 //将数据库的时间戳转成 *时*分 字符串 224 function getTime(DBTime){ 225 var time = DBTime.substring(0,2)+"-"+DBTime.substring(3,5); 226 return time; 227 } 228 229 /** 230 * 获取当前语言类型 231 * @return {*} 232 */ 233 function getNowLanguage(type) { 234 try { 235 var rk = $.cookie('resource_key'); 236 if (!rk) { 237 rk = "zh_CN"; 238 } 239 if (type) { 240 // 日期控件 241 if ("1" == type) { 242 if ("en_US" == rk) { 243 return "en"; 244 } 245 if ("zh_CN" == rk) { 246 return "zh-CN"; 247 } 248 // 评分控件 249 } else if ("2" == type) { 250 if ("en_US" == rk) { 251 return "en"; 252 } 253 if ("zh_CN" == rk) { 254 return "zh"; 255 } 256 } 257 } 258 return rk; 259 } catch (e) { 260 return "en_US"; 261 } 262 } 263 264 //查询,按用户组织查询排班 265 serachCalendarWorkSchedule = function (addGroup, start, end, callback) { 266 var groupIds = ""; 267 if (addGroup != null && addGroup != '' && addGroup != 'undefined') { 268 groupIds = addGroup; 269 } else { 270 groupIds = $("#filter_orgCode").val().toString(); 271 272 } 273 myCalendar.fullCalendar('removeEvents'); 274 var startDate = start; 275 if (undefined == startDate || null == startDate || "" == startDate) { 276 startDate = myCalendar.fullCalendar('getView').start.valueOf(); 277 } 278 var endDate = end; 279 if (undefined == endDate || null == endDate || "" == endDate) { 280 endDate = myCalendar.fullCalendar('getView').end.valueOf(); 281 } 282 283 if (groupIds == null || groupIds == undefined || groupIds == "" || groupIds == "null") { 284 return; 285 } 286 287 $.ajax({ 288 type: "POST", 289 url: prefix + "/list", 290 data: { 291 "start": TimeStampConvertDate(startDate), 292 "end": TimeStampConvertDate(endDate), 293 "orgCode": groupIds 294 }, 295 async: false, 296 dataType: "json", 297 success: function (data) { 298 var dataList = []; 299 var jsonData = data; 300 for (var i = 0; i < jsonData.length; i++) { 301 var begin_time = DataTimeConvertDate(jsonData[i].startTime); 302 var ccDate = begin_time.replace(/\-/g,""); 303 var nowDate = new Date().format("yyyyMMdd"); 304 if( ccDate > nowDate ){ 305 data = { 306 id: jsonData[i].id, 307 title: timestampToHourMinute(jsonData[i].startTime) + "-" + timestampToHourMinute(jsonData[i].endTime) + ":【" + jsonData[i].staffName + "】" + "分拨:"+ jsonData[i].orgCode, 308 start: begin_time, 309 allday: true, 310 backgroundColor: '#FFFFE0',//大于今天的设置 311 borderColor:'black' 312 }; 313 }else if (ccDate == nowDate){ 314 data = { 315 id: jsonData[i].id, 316 title: timestampToHourMinute(jsonData[i].startTime) + "-" + timestampToHourMinute(jsonData[i].endTime) + ":【" + jsonData[i].staffName + "】" + "分拨:"+ jsonData[i].orgCode, 317 start: begin_time, 318 allday: true, 319 backgroundColor: '#98FB98',//当天的设置 320 borderColor:'black', 321 }; 322 }else{ 323 data = { 324 id: jsonData[i].id, 325 title: timestampToHourMinute(jsonData[i].startTime) + "-" + timestampToHourMinute(jsonData[i].endTime) + ":【" + jsonData[i].staffName + "】" + "分拨:"+ jsonData[i].orgCode, 326 start: begin_time, 327 allday: true, 328 backgroundColor: '#E0FFFF',//过期的设置 329 borderColor:'black' 330 }; 331 } 332 dataList.push(data); 333 } 334 //反馈,重新赋值event的值,进行绑定 335 callback(dataList); 336 } 337 }); 338 } 339 340 //日期截取 341 function DataTimeConvertDate(timeStamp) { 342 var newDate = new Date(timeStamp); 343 return newDate.format('yyyy-MM-dd'); 344 } 345 346 //时间戳转成时间格式(带跨时区差值处理) 347 function TimeStampConvertDate(timeStamp) { 348 var timestamp3; 349 if(typeof(timeStamp) == "number") 350 timestamp3 = convertTimestampCompensate(timeStamp); 351 else 352 timestamp3 = timeStamp; 353 354 var newDate = new Date(); 355 newDate.setTime(timestamp3); 356 return newDate.format('yyyy-MM-dd'); 357 } 358 359 //找到小时和分钟 360 function timestampToHourMinute(timestamp) { 361 var date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000 362 h = date.getHours() + ':'; 363 m = date.getMinutes(); 364 if (m < 10) { 365 m = "0" + m; 366 } 367 return h + m; 368 } 369 370 /** 371 * timestamp型转date型前的时区补差 372 * @param dateTime 373 * @returns {string|*} 374 */ 375 function convertTimestampCompensate(timestamp) { 376 if (!timestamp) 377 return null; 378 379 const serverTimeZone = getServerTimeZone(); 380 if(!serverTimeZone) 381 return timestamp; 382 383 // 当前时区与中时区时差,以min为维度 384 const _dif = new Date().getTimezoneOffset(); 385 // 计算当前时区时间: 当前时区时间 = 服务器时区时间 + 服务器时区 - 当前时区 386 const localDateTime = timestamp + serverTimeZone * 60 * 60 * 1000 - (-_dif * 60 * 1000); 387 return localDateTime; 388 } 389 390 function edit(id) { 391 layer.open({ 392 type : 2, 393 title : '编辑排班', 394 maxmin : true, 395 shadeClose : false, // 点击遮罩关闭层 396 area : [ '800px', '520px' ], 397 content : prefix + '/edit/' + id // iframe的url 398 }); 399 } 400 401 /** 获取 orgCode 下拉列表 402 * @Description 403 * @Author zhengzhaoxiang 404 * @Date 2020/8/24 8:58 405 * @Param 406 * @Return 407 */ 408 function getOrgCode() { 409 var orgCode = ""; 410 $.ajax({ 411 type: "POST", 412 async: false, 413 url: "/dms/common/baseInfo/selectCenter", 414 data: "", 415 dataType: "json", 416 contentType: "application/json", 417 success: function (data) { 418 if (data) { 419 orgCode = data; 420 } 421 } 422 }) 423 return orgCode; 424 }
三、controller 层实现代码展示
1 import cn.hutool.core.util.StrUtil; 2 import org.apache.commons.beanutils.BeanMap; 3 import org.apache.shiro.authz.annotation.RequiresPermissions; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.stereotype.Controller; 6 import org.springframework.ui.Model; 7 import org.springframework.web.bind.annotation.*; 8 9 import javax.servlet.http.HttpServletRequest; 10 import java.sql.Timestamp; 11 import java.util.*; 12 13 /** 14 * 人员排班 15 * @author zzx 16 * @email zhengzhaojava@163.com 17 * @date 2020-08-18 13:32:22 18 */ 19 20 @Controller 21 @RequestMapping("/centerInfo/personSchedul") 22 public class PersonSchedulController extends BaseController { 23 @Autowired 24 private PersonSchedulService personSchedulService; 25 /** 26 * @Description 页面初始化功能 27 * @Author zhengzhaoxiang 28 * @Date 2020/8/24 15:03 29 * @Param [model] 30 * @Return java.lang.String 31 */ 32 @GetMapping() 33 @RequiresPermissions("centerInfo:personSchedul:personSchedul") 34 String PersonSchedul(Model model){ 35 model.addAttribute("orgCode2",getOrgCode()); 36 return "centerInfo/perSchedul/personSchedul"; 37 } 38 39 @ResponseBody 40 @PostMapping("/list") 41 public List list(@RequestParam Map<String, Object> params){ 42 //查询列表数据 43 List<PersonSchedulDO> personSchedulList = personSchedulService.list(params); 44 return personSchedulList; 45 } 46 47 /** 48 * @Description 添加页面 49 * @Author zhengzhaoxiang 50 * @Date 2020/8/24 15:00 51 * @Param [model] 52 * @Return java.lang.String 53 */ 54 @GetMapping("/add") 55 String add(HttpServletRequest request,Model model){ 56 String currDate = request.getParameter("date"); 57 //当前日期 58 model.addAttribute("currDate",currDate); 59 model.addAttribute("orgCode",getOrgCode()); 60 return "centerInfo/perSchedul/add"; 61 } 62 63 /** 64 * @Description 修改页面,同时返回 回显信息。 65 * @Author zhengzhaoxiang 66 * @Date 2020/8/24 15:01 67 * @Param [id, model] 68 * @Return java.lang.String 69 */ 70 @GetMapping("/edit/{id}") 71 String edit(@PathVariable("id") Integer id,Model model){ 72 PersonSchedulDO personSchedul = personSchedulService.get(id); 73 Map<String, Object> personSchedulMap = new HashMap<>(); 74 Map map = new BeanMap(personSchedul); 75 personSchedulMap.putAll(map); 76 Date startTime = personSchedul.getStartTime(); 77 String times = DateUtils.formatDate(startTime, DateUtils.DATE_TIME_PATTERN); 78 //修改页面的日期和时间是分开存储的 79 if(StrUtil.isNotBlank(times)){ 80 String[] time = times.split(" "); 81 personSchedulMap.put("beginDay",time[0]); 82 personSchedulMap.put("beginTime",time[1].substring(0,5)); 83 } 84 Date endTime = personSchedul.getEndTime(); 85 String endTimes = DateUtils.formatDate(endTime, DateUtils.DATE_TIME_PATTERN); 86 if(StrUtil.isNotBlank(endTimes)){ 87 String[] time = endTimes.split(" "); 88 personSchedulMap.put("endDay",time[0]); 89 personSchedulMap.put("endTime",time[1].substring(0,5)); 90 } 91 model.addAttribute("personSchedul", personSchedulMap); 92 return "centerInfo/perSchedul/edit"; 93 } 94 95 /** 96 * @Description 保存, 需求修改:为了方便后期单个任务的修改,这里将 开始时间 与 结束时间 区间进行拆分,每一个时间存储一个单独的任务,方便后期其他处理 97 * @Author zhengzhaoxiang 98 * @Date 2020/8/24 15:00 99 * @Param 100 * @Return 101 */ 102 @ResponseBody 103 @PostMapping("/save") 104 @RequiresPermissions("centerInfo:personSchedul:add") 105 public R save(HttpServletRequest request){ 106 //获取所属分拨中心 107 String orgCode = request.getParameter("orgCode"); 108 //获取员工姓名 109 String staffName = request.getParameter("staffName"); 110 //开始日期 111 String beginDay = request.getParameter("beginDay"); 112 //结束日期 113 String endDay = request.getParameter("endDay"); 114 //工作时间 115 String beginTime = request.getParameter("beginTime"); 116 //工作时间 117 String endTime = request.getParameter("endTime"); 118 //数据校验 119 R x = checkSaveAndUpdate(staffName, beginDay, endDay, beginTime, endTime,orgCode); 120 if (x != null) return x; 121 //备注 122 String remark = request.getParameter("remark"); 123 //组装数据 124 PersonSchedulDO personSchedulDO = getPersonSchedulDO(orgCode, staffName, beginDay, beginDay, beginTime, endTime, remark); 125 /** 126 * 组装保存的对象:根据 startDay 与 endDay 进行循环插入多条 127 */ 128 int start = Integer.valueOf(beginDay.replace("-", "")); 129 int end = Integer.valueOf(endDay.replace("-", "")); 130 //开始时间 131 String startTimeString = personSchedulDO.getStartTime().toString(); 132 //结束时间 133 String endTimeString = personSchedulDO.getEndTime().toString(); 134 for(int i=start; i<= end; i++){ 135 //开始时间 136 String dateAfterDays = DateUtils.getDateAfterNDays(startTimeString, i-start); 137 //结束时间 138 String dateEndDays = DateUtils.getDateAfterNDays(endTimeString, i-start); 139 //修改组装数据的 startTime 和 endTime 140 personSchedulDO.setStartTime(DateUtils.getDateFromString(dateAfterDays,DateUtils.DATE_FORMAT_DATETIME)); 141 personSchedulDO.setEndTime(DateUtils.getDateFromString(dateEndDays,DateUtils.DATE_FORMAT_DATETIME)); 142 //入库 143 personSchedulService.save(personSchedulDO); 144 } 145 return R.ok(); 146 } 147 148 /** 149 * @Description 增加修改时,数据封装 150 * @Author zhengzhaoxiang 151 * @Date 2020/8/24 15:05 152 * @Param [orgCode, staffName, beginDay, endDay, beginTime, endTime, remark] 153 * @Return com.yunda.base.centerInfo.domain.PersonSchedulDO 154 */ 155 private PersonSchedulDO getPersonSchedulDO(String orgCode, String staffName, String beginDay, String endDay, String beginTime, String endTime, String remark) { 156 //创建需要进行存库的对象 157 PersonSchedulDO personSchedulDO = new PersonSchedulDO(); 158 personSchedulDO.setOrgCode(orgCode); 159 personSchedulDO.setStaffName(staffName); 160 personSchedulDO.setRemark(remark); 161 //组装时间 162 String newBegintime = beginDay + " " + beginTime + ":00"; 163 String newEndtime = endDay + " " + endTime + ":00"; 164 165 personSchedulDO.setStartTime(Timestamp.valueOf(newBegintime)); 166 personSchedulDO.setEndTime(Timestamp.valueOf(newEndtime)); 167 return personSchedulDO; 168 } 169 170 /** 171 * @Description 修改 172 * @Author zhengzhaoxiang 173 * @Date 2020/8/24 15:02 174 * @Param 175 * @Return 176 */ 177 @ResponseBody 178 @RequestMapping("/update") 179 @RequiresPermissions("centerInfo:personSchedul:edit") 180 public R update( HttpServletRequest request){ 181 //获取用户ID 182 String id = request.getParameter("id"); 183 if(StrUtil.isBlank(id)){ 184 return R.error("id不能为空"); 185 } 186 //获取所属分拨中心 187 String orgCode = request.getParameter("orgCode"); 188 //获取员工姓名 189 String staffName = request.getParameter("staffName"); 190 //工作日期 191 String beginDay = request.getParameter("beginDay"); 192 //工作时间 193 String beginTime = request.getParameter("beginTime"); 194 //工作时间 195 String endTime = request.getParameter("endTime"); 196 //数据校验 197 R x = checkSaveAndUpdate(staffName, beginDay, beginDay, beginTime, endTime,orgCode); 198 if (x != null) return x; 199 //备注 200 String remark = request.getParameter("remark"); 201 //组装保存的对象 202 PersonSchedulDO personSchedulDO = getPersonSchedulDO(orgCode, staffName, beginDay, beginDay, beginTime, endTime, remark); 203 personSchedulDO.setId(Integer.valueOf(id)); 204 personSchedulService.update(personSchedulDO); 205 return R.ok(); 206 } 207 208 /** 209 * @Description 删除 210 * @Author zhengzhaoxiang 211 * @Date 2020/8/24 15:02 212 * @Param 213 * @Return 214 */ 215 @PostMapping( "/remove") 216 @ResponseBody 217 public R remove( String id){ 218 if(StrUtil.isNotBlank(id) && personSchedulService.remove(Integer.valueOf(id))>0){ 219 return R.ok(); 220 } 221 return R.error(); 222 } 223 224 /** 225 * @Description 批量删除 226 * @Author zhengzhaoxiang 227 * @Date 2020/8/24 15:03 228 * @Param 229 * @Return 230 */ 231 @PostMapping( "/batchRemove") 232 @ResponseBody 233 @RequiresPermissions("centerInfo:personSchedul:batchRemove") 234 public R remove(@RequestParam("ids[]") Integer[] ids){ 235 personSchedulService.batchRemove(ids); 236 return R.ok(); 237 } 238 239 240 /** 241 * @Description 拖动任务时,进行时间上的处理 242 * @Author zhengzhaoxiang 243 * @Date 2020/8/24 15:04 244 * @Param [request] 245 * @Return com.yunda.base.common.utils.R 246 */ 247 @PostMapping("/dropView") 248 @ResponseBody 249 public R dropView(HttpServletRequest request){ 250 String id = request.getParameter("id"); 251 if(StrUtil.isBlank(id)){ 252 return R.error("id 不能为空"); 253 } 254 String dayDelta = request.getParameter("dayDelta"); 255 if(StrUtil.isBlank(dayDelta)){ 256 return R.error("dayDelta"); 257 } 258 //拖动日期进行计算 259 PersonSchedulDO personSchedulDO = personSchedulService.get(Integer.valueOf(id)); 260 Date startTime = personSchedulDO.getStartTime(); 261 String dateTime = DateUtils.formatDate(startTime, DateUtils.DATE_TIME_PATTERN); 262 String dateAfterNDays = DateUtils.getDateAfterNDays(dateTime, Integer.valueOf(dayDelta)); 263 //日期 264 Date dateFromString = DateUtils.getDateFromString(dateAfterNDays, DateUtils.DATE_TIME_PATTERN); 265 personSchedulDO.setStartTime(dateFromString); 266 //根据ID进行更新 267 personSchedulService.update(personSchedulDO); 268 return R.ok(); 269 } 270 }
四、表结构展示
1 SET NAMES utf8mb4; 2 SET FOREIGN_KEY_CHECKS = 0; 3 4 -- ---------------------------- 5 -- Table structure for person_schedul 6 -- ---------------------------- 7 DROP TABLE IF EXISTS `person_schedul`; 8 CREATE TABLE `person_schedul` ( 9 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', 10 `org_code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '所属分拨中心', 11 `staff_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '员工姓名', 12 `start_time` datetime(0) NULL DEFAULT NULL COMMENT '开始日期', 13 `end_time` datetime(0) NULL DEFAULT NULL COMMENT '结束日期', 14 `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '备注', 15 PRIMARY KEY (`id`) USING BTREE 16 ) ENGINE = InnoDB AUTO_INCREMENT = 150 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '人员排班' ROW_FORMAT = Compact; 17 18 SET FOREIGN_KEY_CHECKS = 1;
五、add 页面展示,edit 与之类似,需要添加 th:value="${personSchedul.endTime}" 等进行回显。
1 <!DOCTYPE html> 2 <html lang="zh_CN" xmlns:th="http://www.thymeleaf.org"> 3 <meta charset="utf-8"> 4 <head th:include="include :: header"></head> 5 <body class="gray-bg"> 6 <div class="wrapper wrapper-content "> 7 <div class="row"> 8 <div class="col-sm-12"> 9 <div class="ibox float-e-margins"> 10 <div class="ibox-content"> 11 <form class="form-horizontal m-t" id="signupForm"> 12 <input id="currDate" name="currDate" th:value="${currDate}" type="hidden"> 13 <div class="form-group"> 14 <label class="col-sm-3 control-label">所属分拨中心:</label> 15 <div class="col-sm-8"> 16 <input id="orgCode" name="orgCode" class="form-control" th:value="${orgCode}" type="text" readonly="true" required="true"> 17 </div> 18 </div> 19 <div class="form-group"> 20 <label class="col-sm-3 control-label">员工姓名:</label> 21 <div class="col-sm-8"> 22 <select id="staffName" name="staffName" class="form-control" type="text" required="true"> 23 <option> </option> 24 </select> 25 <div class="error-msg"></div> 26 </div> 27 </div> 28 <div class="form-group"> 29 <label class="col-sm-3 control-label">开始日期:</label> 30 <div class="col-sm-8"> 31 <input id="beginDay" name="beginDay" class="form-control" type="date"> 32 </div> 33 </div> 34 <div class="form-group"> 35 <label class="col-sm-3 control-label">结束日期:</label> 36 <div class="col-sm-8"> 37 <input id="endDay" name="endDay" class="form-control" type="date"> 38 </div> 39 </div> 40 <div class="form-group"> 41 <label class="col-sm-3 control-label">工作时间:</label> 42 <div class="col-sm-2" style="position: relative; float: left; padding-left: 19px;" 43 align="left"> 44 <div class="input-group monday"> 45 <input type="time" id="beginTime" name="beginTime" 46 class="form-control timepicker timepicker-default startTime" autocomplete="off"> 47 </div> 48 </div> 49 <div style="width: 3px; position: relative; float: left;" align="center"> 50 <p>-</p> 51 </div> 52 <div class="col-sm-2" style="position: relative; float: left;" align="left"> 53 <div class="input-group monday"> 54 <input type="time" id="endTime" name="endTime" 55 class="form-control timepicker timepicker-default endTime" autocomplete="off"> 56 </div> 57 </div> 58 </div> 59 <div class="form-group"> 60 <label class="col-sm-3 control-label">备注:</label> 61 <div class="col-sm-8"> 62 <input id="remark" name="remark" class="form-control" type="text" maxlength="100"> 63 </div> 64 </div> 65 <div class="form-group"> 66 <div class="col-sm-8 col-sm-offset-3"> 67 <button type="submit" class="btn btn-primary">提交</button> 68 </div> 69 </div> 70 </form> 71 </div> 72 </div> 73 </div> 74 </div> 75 </div> 76 <div th:include="include::footer"></div> 77 <script type="text/javascript" th:src="@{/js/appjs/centerInfo/perSchedul/add.js}"> 78 </script> 79 </body> 80 </html>
六、add.js 代码展示
1 $().ready(function() { 2 validateRule(); 3 $("#staffName").select2({ 4 data:getStaffName(), 5 placeholder:"请选择", 6 allowClear:true, 7 language:"zh-CN" 8 }).val(null).trigger("change"); 9 }); 10 11 $.validator.setDefaults({ 12 submitHandler : function() { 13 save(); 14 } 15 }); 16 function save() { 17 $.ajax({ 18 cache : true, 19 type : "POST", 20 url : "/dms/centerInfo/personSchedul/save", 21 data : $('#signupForm').serialize(),// 你的formid 22 async : false, 23 error : function(request) { 24 parent.layer.alert("Connection error"); 25 }, 26 success : function(data) { 27 if (data.code == 0) { 28 parent.layer.msg("操作成功"); 29 parent.reloadCalendar(); 30 var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引 31 parent.layer.close(index); 32 33 } else { 34 parent.layer.alert(data.msg) 35 } 36 37 } 38 }); 39 40 } 41 42 /** 43 * 在页面加载此js文件 44 * 使用例:new Date().format("yyyy-MM-dd hh:mm:ss") 45 */ 46 Date.prototype.format = function (fmt) { 47 var o = { 48 "M+": this.getMonth() + 1, //月份 49 "d+": this.getDate(), //日 50 "h+": this.getHours(), //小时 51 "m+": this.getMinutes(), //分 52 "s+": this.getSeconds(), //秒 53 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 54 "S": this.getMilliseconds() //毫秒 55 }; 56 if (/(y+)/.test(fmt)) { 57 fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 58 } 59 for (var k in o) { 60 if (new RegExp("(" + k + ")").test(fmt)) { 61 fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 62 } 63 } 64 return fmt; 65 } 66 67 function validateRule() { 68 var icon = "<i class='fa fa-times-circle'></i> "; 69 $("#signupForm").validate({ 70 rules : { 71 name : { 72 required : true 73 } 74 }, 75 messages : { 76 name : { 77 required : icon + "请输入姓名" 78 } 79 } 80 }) 81 //如果点击页面时,就根据页面点击的日期为准 82 var weekTime 83 if($('#currDate').val() != null && $('#currDate').val() != "" && $('#currDate').val() !="undefined"){ 84 weekTime = new Date($('#currDate').val()); 85 $("#beginDay").val(new Date($('#currDate').val()).format('yyyy-MM-dd')); 86 }else{ 87 $("#beginDay").val(new Date().format('yyyy-MM-dd')); 88 weekTime = new Date(); 89 } 90 weekTime.setDate(weekTime.getDate() + 7); 91 $("#endDay").val(weekTime.format('yyyy-MM-dd')); 92 $('#beginTime').val("09:00"); 93 $('#endTime').val("17:00"); 94 } 95 96 function getStaffName() { 97 $.ajax({ 98 type: "POST", 99 url: "/dms/centerInfo/personSchedul/getUserInfo", 100 data: '', 101 async: false, 102 dataType: "json", 103 // contentType : "application/json", 104 success: function (data) { 105 if (data) { 106 types = data; 107 } 108 } 109 }) 110 return types; 111 }
七、edit.js 代码展示:删除功能也在该页面完成
1 var prefix = "/dms/centerInfo/personSchedul" 2 3 $().ready(function() { 4 validateRule(); 5 $("#staffName").select2({ 6 data:getStaffName(), 7 placeholder:"请选择", 8 allowClear:true, 9 language:"zh-CN" 10 }).val($("#staffName2").val()).trigger("change"); 11 }); 12 13 $.validator.setDefaults({ 14 submitHandler : function() { 15 update(); 16 } 17 }); 18 function update() { 19 $.ajax({ 20 cache : true, 21 type : "POST", 22 url : "/dms/centerInfo/personSchedul/update", 23 data : $('#signupForm').serialize(),// 你的formid 24 async : false, 25 error : function(request) { 26 parent.layer.alert("Connection error"); 27 }, 28 success : function(data) { 29 if (data.code == 0) { 30 parent.layer.msg("操作成功"); 31 parent.reloadCalendar(); 32 var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引 33 parent.layer.close(index); 34 35 } else { 36 parent.layer.alert(data.msg) 37 } 38 39 } 40 }); 41 42 } 43 function validateRule() { 44 var icon = "<i class='fa fa-times-circle'></i> "; 45 $("#signupForm").validate({ 46 rules : { 47 name : { 48 required : true 49 } 50 }, 51 messages : { 52 name : { 53 required : icon + "请输入名字" 54 } 55 } 56 }) 57 } 58 59 function getStaffName() { 60 $.ajax({ 61 type: "POST", 62 url: "/dms/centerInfo/personSchedul/getUserInfo", 63 data: '', 64 async: false, 65 dataType: "json", 66 // contentType : "application/json", 67 success: function (data) { 68 if (data) { 69 types = data; 70 } 71 } 72 }) 73 return types; 74 } 75 76 function remove() { 77 layer.confirm('确定要删除选中的记录?', { 78 btn : [ '确定', '取消' ] 79 }, function() { 80 $.ajax({ 81 url : prefix+"/remove", 82 type : "post", 83 data : { 84 'id' : $("#id").val() 85 }, 86 success : function(r) { 87 if (r.code==0) { 88 layer.msg(r.msg); 89 parent.reloadCalendar(); 90 var index = parent.layer.getFrameIndex(window.name); // 获取窗口索引 91 parent.layer.close(index); 92 }else{ 93 parent.layer.msg(r.msg); 94 } 95 } 96 }); 97 }) 98 }