请假单流程开发

在开发中,有时,会遇到,求两个日期,相减求天数的需求,这个小例子是项目中遇到的,项目需要要为某部开发一个请假流程(不要jbpm,activity)

选择日期起止日期后,求请假天数

<script type="text/javascript">
var startDate;
var endDate;
    loadCallBack = function() {
        $("#addLeaveAloneForm").validate({
            meta : 'validate'
        });
        startDate = 0;
        endDate = 0;
           $('#proxyPerson').on('change',function(id, text){
                   $('#proxyPosition').val('');
                   $('#proxyPhone').val('');
                   if(text){
                        $.ajax({
                        url : basePath + '/soft617/leaveAlone/getUserInfo.json',
                        type : 'POST',
                        data : {
                            userId : text 
                        },
                        success : function(msg) {
                            if(msg){
                                var result = msg.split("#@");
                                if("null"!=result[0]){
                                    $('#proxyPosition').val(result[0]);
                                }
                                if("null"!=result[1]){
                                    $('#proxyPhone').val(result[1]);
                                }
                                //$("#leaveSubject").focus();
                                
                            }
                        },
                        error : function() {
                            $.sywDialog.warn("提示", "操作过程中出现错误。");   
                        }
                    });
                   }
           
            });
         
            $("#leaveStart").on("focus", function(event, value, text) {
                startDate = 0;
                $('#totalDay').val(0);
                startDate =$('#leaveStart').val();
                if (endDate != "" && endDate != null && endDate != 0) {
                    var countDay = getMct(startDate, endDate);
                    if(isNaN(countDay) ){
                        $('#totalDay').val('');
                       }else{
                           $('#totalDay').val(countDay);
                       }
                    
                }
            });
            //focus
            $("#leaveEnd").on("focus", function(event, value, text) {
                endDate = 0;
                $('#totalDay').val(0);
                endDate =$('#leaveEnd').val();
                if (startDate != "" && startDate != null
                        && startDate != 0) {
                    var countDay = getMct(startDate, endDate);
                    //$('#totalDays').html(countDay);
                    if(isNaN(countDay) ){
                        $('#totalDay').val('');
                       }else{
                           $('#totalDay').val(countDay);
                       }
                }
            });

    }
    
    function getMct(strDateStart, strDateEnd) {
        var strSeparator="-" ;
        var oDate1;
        var oDate2;
        var iDays;
        oDate1=strDateStart.split(strSeparator);
        oDate2=strDateEnd.split(strSeparator);
        var strDateS=new Date(oDate1[0],oDate1[1]-1,oDate1[2]);
        var strDateE=new Date(oDate2[0],oDate2[1]-1,oDate2[2]);
        iDays=parseInt(Math.abs(strDateS-strDateE)/1000/60/60/24);
        if (iDays <0) {
         alert( "结束时间必须大于开始时间!");
        }
        return iDays+1;
    }


</script>

 开发这个请假单流程,得到用户的认可,我和伙伴都感到很有成就感,因为这个里面用到了好多算法,其中有一个就是数据库算法:

比如:审批状态的一个查询,可以多选(审批中,已审批,未销假,已销假,驳回),这个时候,sql 如何拼写,这里就用到了一个算法

    // 拼接查询参数
        if (param.get("appleStatusSerch") != null
                && !"".equals(param.get("appleStatusSerch"))) {
            String statusSerch = param.get("appleStatusSerch").toString();
            String[] strs = statusSerch.split(",");
            if (strs.length == 1) {
                if (strs[0].equals("1")) {
                    sbSql.append("  and t.APPROVAL_STATUS =1 ");
                }
                if (strs[0].equals("2")) {
                    //sbSql.append("  and t.APPROVAL_STATUS =2 and t.SICK_TIME is null ");
                    sbSql.append("  and t.APPROVAL_STATUS =2  ");
                }
                if (strs[0].equals("3")) {
                    //sbSql.append("  and t.APPROVAL_STATUS =2 and t.SICK_TIME is not null ");
                    sbSql.append("  and t.APPROVAL_STATUS =4");
                }
                if (strs[0].equals("4")) {
                    sbSql.append("  and t.APPROVAL_STATUS =3 ");
                }
            } else if (strs.length == 4) {
                sbSql.append("   and  t.APPROVAL_STATUS in (1,2,3,4) ");

            } else if (strs.length > 1) {
                sbSql.append("  and ( ");
                for (int i = 0; i < strs.length; i++) {

                    if (i > 0) {
                        sbSql.append("   or ");
                    }

                    if (strs[i].equals("1")) {
                        sbSql.append("    t.APPROVAL_STATUS =1 ");
                    }
                    if (strs[i].equals("2")) {
                        //sbSql.append("   (t.APPROVAL_STATUS =2 and t.SICK_TIME is null)");
                        sbSql.append("   (t.APPROVAL_STATUS =2 )");
                    }
                    if (strs[i].equals("3")) {
                        //sbSql.append("    (t.APPROVAL_STATUS =2 and t.SICK_TIME is  not null)");
                        sbSql.append("    (t.APPROVAL_STATUS =4 )");
                    }
                    if (strs[i].equals("4")) {
                        sbSql.append("   (t.APPROVAL_STATUS =3 )");
                    }

                }
                sbSql.append("  )");
            }

        } else {
            sbSql.append(" and  t.APPROVAL_STATUS not in(1,2,3,4)");
        }

上面的代码是version_1其实优化之后应该这样写,

   if (param.get("appleStatusSerch") != null
                && !"".equals(param.get("appleStatusSerch"))) {
            String statusSerch = param.get("appleStatusSerch").toString();
            String[] strs = statusSerch.split(",");
         if (strs.length > =1) {
                sbSql.append("  and ( ");
                for (int i = 0; i < strs.length; i++) {

                    if (i > 0) {
                        sbSql.append("   or ");
                    }

                    if (strs[i].equals("1")) {
                        sbSql.append("    t.APPROVAL_STATUS =1 ");
                    }
                    if (strs[i].equals("2")) {
                        //sbSql.append("   (t.APPROVAL_STATUS =2 and t.SICK_TIME is null)");
                        sbSql.append("   (t.APPROVAL_STATUS =2 )");
                    }
                    if (strs[i].equals("3")) {
                        //sbSql.append("    (t.APPROVAL_STATUS =2 and t.SICK_TIME is  not null)");
                        sbSql.append("    (t.APPROVAL_STATUS =4 )");
                    }
                    if (strs[i].equals("4")) {
                        sbSql.append("   (t.APPROVAL_STATUS =3 )");
                    }

                }
                sbSql.append("  )");
            }

        } else {
            sbSql.append(" and  t.APPROVAL_STATUS not in(1,2,3,4)");
        }

 其实,至少这个流程是如何实现的,算法也不是很简单:

审批列表是根据当前登录用户的角色,然后跟流程定义的角色比较,查找到对应的审批角色,在请假单的增加页面,自动会把审批列表算出:

 

 流程定义表:是审批角色和使用角色

 

 

 流程定义这里:你看关系是一对多的(其实是多对多的),表结构设置如下:

SOFT617_LEAVE_APPROVAL_PROCESS 流程定义表1,2,3,而下面的子表存的是分割后的id

储存时,审批角色对应的是一个,使用角色存的是

 

SOFT617_LEAVE_USE_ROLE 流程定义子表

 

关键代码:

 

 

前面的准备工作都做好了,现在开始我们的请假单的设计:

审批表 SOFT617_LEAVE_APPROVAL:

请假单从添加时,就启动了一个流程:

关键代码:

// /////////////////////////// 构建审批列表start//////////////////////////
        String sqlString = "select s.role_id_approval,r.role_name, u.user_name,u.user_id\n"
                + " from SOFT617_LEAVE_USE_ROLE t, soft617_leave_approval_process s,sys_role r,sys_user u ,sys_role_user sr\n"
                + "where t.USE_ROLE_ID in ( select t.role_id\n"
                + "             from sys_role t\n"
                + "            where t.role_id in\n"
                + "                  (select t.role_id\n"
                + "                     from sys_role_user t\n"
                + "                    where t.USER_ID =\n"
                + "                          '"
                + userId
                + "'))\n"
                + "and t.LEAVE_APPPROCESS_ID=s.id\n"
                + "and s.role_id_approval=r.role_id\n
                + "and sr.ROLE_ID=s.role_id_approval\n"
                + " and sr.user_id=u.user_id\n" + "order by s.SORT_ORDER";

执行请假单的保存操作:
String jsonString = request.getParameter("jsonString");
		String userId = identity.getUserId();

		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		String createTime = jsonObject.get("createTime").toString();
		JSONUtils.getMorpherRegistry().registerMorpher(
				new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss",
						"yyyy-MM-dd", "yyyy-MM-dd't'HH:mm:ss" }, new Date()));
		LeaveAlone bean = (LeaveAlone) JSONObject.toBean(jsonObject,
				LeaveAlone.class);
		SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		bean.setCreateTime(sdfs.parse(createTime));

		// /////////////////发送消息start////////////////
		Message message = new Message();
		message.setTitle(bean.getUserName() + "请假," + "委托您代理假期工作");
		// message.setContent(bean.getUserName() + "请假" + bean.getTotalDay() +
		// "天"
		// + bean.getLeaveSubject());
		SimpleDateFormat sdff = new SimpleDateFormat("yyyy-MM-dd");
		message.setContent("请假时间:" + sdff.format(bean.getLeaveStart()) + "至"
				+ sdff.format(bean.getLeaveEnd()));

		message.setMessageImportance(MessageImportance.Unimportant);
		message.setType(MessageType.Human);
		message.setReceviers(bean.getProxyPerson().split(","));

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("messageIsBack", MessageConstants.MESSAGE_IS_BACK_NOT);
		message.setOtherInfo(map);
		message.setAttachments("".split(","));
		message.setReceiveRule("");
		message.setSender(bean.getUserId());
		// 消息服务器发送
		message.send();
		// /////////////////发送消息end ////////////////
		// ///////////////////////////保存审批信息start//////////////////////////
		String sqlString = "select s.role_id_approval,r.role_name, u.user_name,u.user_id\n"
				+ " from SOFT617_LEAVE_USE_ROLE t, soft617_leave_approval_process s,sys_role r,sys_user u ,sys_role_user sr\n"
				+ "where t.USE_ROLE_ID in ( select t.role_id\n"
				+ "             from sys_role t\n"
				+ "            where t.role_id in\n"
				+ "                  (select t.role_id\n"
				+ "                     from sys_role_user t\n"
				+ "                    where t.USER_ID =\n"
				+ "                          '"
				+ userId
				+ "'))\n"
				+ "and t.LEAVE_APPPROCESS_ID=s.id\n"
				+ "and s.role_id_approval=r.role_id\n"
				+ "and sr.ROLE_ID=s.role_id_approval\n"
				+ " and sr.user_id=u.user_id\n" + "order by s.SORT_ORDER";

		List<Map<String, Object>> list = JDBCBaseDaoImpl.getJDBCTemplate()
				.queryForList(sqlString);

		try {
			String leaveAloneId = leaveAloneService.save(bean);
			//添加日志
			logger.log(""+bean.getLeaveSubject()+"", "请假单", AuditLogLevel.level3, AuditLogResult.success, "新增", false);

			int j = 0;
			for (int i = 0; i < list.size(); i++) {
				j = j + 1;
				Map<String, Object> tempMap = list.get(i);
				// 审批跟踪表
				LeaveApproval leaveApproval = new LeaveApproval();
				leaveApproval.setId(StringUtil.getGuid());
				leaveApproval.setSortOrder(j);
				leaveApproval.setApprovalUserId(tempMap.get("USER_ID")
						.toString());
				leaveApproval.setApprovalUserName(tempMap.get("USER_NAME")
						.toString());
				leaveApproval.setApprovalRoleId(tempMap.get("ROLE_ID_APPROVAL")
						.toString());
				leaveApproval.setApprovalRoleName(tempMap.get("ROLE_NAME")
						.toString());
				leaveApproval.setApprovalStatus("5");// 未审批;
				leaveApproval.setApprovalOpinin("");
				leaveApproval.setCreateTime(new Date());
				leaveApproval.setCreator(userId);
				leaveApproval.setLeaveAloneId(leaveAloneId);
				if (j == 1) {
					leaveApproval.setEffectyive("0");
					//给审批人发送信息
					// /////////////////发送消息start////////////////
					Message messageApp = new Message();
					messageApp.setTitle(bean.getUserName()+"的请假申请,请您审批!");
					
					messageApp.setContent(bean.getUserName() + "请假," + "【<a href='javascript:void(0)' onclick=\"viewApproval('"+ leaveAloneId+ "','"+ leaveApproval.getSortOrder()+ "'); return false\"><font style='color: #5374B1;'>"+  "</font>请您审批</a>】。");

					messageApp.setMessageImportance(MessageImportance.Unimportant);
					messageApp.setType(MessageType.Human);
					messageApp.setReceviers(tempMap.get("USER_ID").toString().split(","));

					Map<String, Object> mapApp = new HashMap<String, Object>();
					mapApp.put("messageIsBack", MessageConstants.MESSAGE_IS_BACK_NOT);
					messageApp.setOtherInfo(mapApp);
					messageApp.setAttachments("".split(","));
					messageApp.setReceiveRule("");
					messageApp.setSender(bean.getUserId());
					// 消息服务器发送
					messageApp.send();
					// /////////////////发送消息end ////////////////
					
				} else {
					leaveApproval.setEffectyive("1");
				}
				leaveAloneService.saveLeaveApproval(leaveApproval);
			

			}
			SyswarePageWrite.writeTOPage(response, "请假单添加成功!");
		} catch (Exception e) {
			SyswarePageWrite.writeTOPage(response, "请假单添加失败!");
		}

 



 

各自审批人登录系统进行审批:

 关键代码:

    public void upddateLeaveApproval(Map<String, Object> map) {
        /**
         * map.put("radioVal", radioVal); map.put("approvalOpinin",
         * approvalOpinin); map.put("userId", userId); map.put("leaveId",
         * leaveId);
         */
        String passVal = map.get("radioVal").toString();
        String leaveId = map.get("leaveId").toString();
        String userId = map.get("userId").toString();
        String approvalOpinin = map.get("approvalOpinin").toString();
        Integer maxNumber;
        Integer curentNumber;
        String leaveApprovalId = "";
        if ("PASS".equals(passVal)) {
            // 查出最大的号
            String sqlMaxNumber = " select max(sort_order) sort_order from  SOFT617_LEAVE_APPROVAL s where s.leave_alone_id='"
                    + leaveId + "'";
            maxNumber = Integer.parseInt(JDBCBaseDaoImpl.getJDBCTemplate()
                    .queryForList(sqlMaxNumber).get(0).get("SORT_ORDER")
                    .toString());
            // 查出当前审批人的号码
            String sqlCurrentNumber = " select id, sort_order  from  SOFT617_LEAVE_APPROVAL s where s.leave_alone_id='"
                    + leaveId + "' and s.approval_user_id='" + userId + "'";
            curentNumber = Integer.parseInt(JDBCBaseDaoImpl.getJDBCTemplate()
                    .queryForList(sqlCurrentNumber).get(0).get("SORT_ORDER")
                    .toString());
            leaveApprovalId = JDBCBaseDaoImpl.getJDBCTemplate()
                    .queryForList(sqlCurrentNumber).get(0).get("ID").toString();
            if (maxNumber == curentNumber) {
                // 如果当前审批人的号码序最大的号码一样说明是最后一个节点
                // 更新请假表的状态
                LeaveAlone leaveAlone = baseDao.getEntityById(LeaveAlone.class,
                        leaveId);
                leaveAlone.setApprovalStatus("2");// 已审批
                // 更新审批表信息
                LeaveApproval leaveApproval = this
                        .loadByLeaveApproval(leaveApprovalId);
                leaveApproval.setApprovalOpinin(approvalOpinin);
                leaveApproval.setApprovalStatus("1");
                leaveApproval.setEffectyive("1");
                this.updateLeaveApproval(leaveApproval);
            } else {
                // 不是最大号的情况下(更新当前审批信息,更新下一条审批审批信息为有效)
                String sqlString = "update SOFT617_LEAVE_APPROVAL s set s.approval_status = '1',\n"
                        + "s.approval_opinin = '"
                        + approvalOpinin
                        + "',s.effectyive='1'\n"
                        + "where s.id = (select id\n"
                        + "                from SOFT617_LEAVE_APPROVAL t\n"
                        + "               where t.leave_alone_id = '"
                        + leaveId
                        + "'\n"
                        + "                 and t.APPROVAL_USER_ID = '"
                        + userId + "')";
                JDBCBaseDaoImpl.getJDBCTemplate().execute(sqlString);
                Integer nextNumberInteger = curentNumber + 1;
                String sqlString2 = "update SOFT617_LEAVE_APPROVAL s set s.effectyive= '0' where s.leave_alone_id='"
                        + leaveId
                        + "' and s.sort_order='"
                        + nextNumberInteger
                        + "'";
                //向下一个人发送信息1、先查询下一个审批人是谁
                String sqlSerchString="select t.APPROVAL_USER_ID, s.CREATOR  from SOFT617_LEAVE_APPROVAL t ,SOFT617_LEAVE_ALONE s  where t.leave_alone_id='"+leaveId+"' and t.sort_order='"+nextNumberInteger+"'  and s.id=t.leave_alone_id " ;
                String nextuserId=JDBCBaseDaoImpl.getJDBCTemplate().queryForList(sqlSerchString).get(0).get("APPROVAL_USER_ID").toString();
                String createUserId=JDBCBaseDaoImpl.getJDBCTemplate().queryForList(sqlSerchString).get(0).get("CREATOR").toString();
                //根据用户id查询名字
                String userNameSql="select t.USER_NAME  from sys_user t where t.user_id='"+createUserId+"'" ;
                String user_name=JDBCBaseDaoImpl.getJDBCTemplate().queryForList(userNameSql).get(0).get("USER_NAME").toString();
                //给审批人发送信息
                // /////////////////发送消息start////////////////
                Message messageApp = new Message();
                messageApp.setTitle(user_name+"的请假申请,请您审批!");
                
            //    messageApp.setContent(user_name + "请假," + "【'<a href='javascript:void(0)' onclick=\"viewApproval('"
            //                            + leaveId
            //                            + "'); return false\"><font style='color: #5374B1;'>"
            //                            +  "</font>请您审批</a>】。");
                messageApp.setContent(user_name+ "请假," + "【<a href='javascript:void(0)' onclick=\"viewApproval('"+ leaveId+ "','"+ nextNumberInteger+ "'); return false\"><font style='color: #5374B1;'>"+  "</font>请您审批</a>】。");


                messageApp.setMessageImportance(MessageImportance.Unimportant);
                messageApp.setType(MessageType.Human);
                messageApp.setReceviers(nextuserId.split(","));

                Map<String, Object> mapApp = new HashMap<String, Object>();
                mapApp.put("messageIsBack", MessageConstants.MESSAGE_IS_BACK_NOT);
                messageApp.setOtherInfo(mapApp);
                messageApp.setAttachments("".split(","));
                messageApp.setReceiveRule("");
                messageApp.setSender(nextuserId);
                // 消息服务器发送
                messageApp.send();
                // /////////////////发送消息end ////////////////
                
                
                JDBCBaseDaoImpl.getJDBCTemplate().execute(sqlString2);
            }
        } else {
            // 不同意的情况处理1、更新请假表的状态为驳回,并且更新审批表为无效标示
            LeaveAlone leaveAlone= this.loadById(leaveId);
            leaveAlone.setApprovalStatus("3");
            baseDao.update(leaveAlone);
            //更新审批表信息
            String sqlString="update SOFT617_LEAVE_APPROVAL s set s.effectyive= '1', s.approval_status = '2',s.approval_opinin='"+approvalOpinin+"' where s.leave_alone_id='"+leaveId+"'and s.APPROVAL_USER_ID='"+userId+"'" ;
            JDBCBaseDaoImpl.getJDBCTemplate().execute(sqlString);
            
        }

    }

接着说,普通表格的上移,下移,这其实也是个算法:

 

以上,就是整个请假单流程的开发,说简单,也不简单,说难,也不算,其实,我们还开发了,其它流程的开发,比如;任务的审批流程等,其实,现在回过头来,再看,感觉这个还挺不错,现在忙里偷闲,记录下自己的成长点滴。

 

posted @ 2016-09-01 10:32  赤子之心_timefast  阅读(1216)  评论(0编辑  收藏  举报