| | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | import com.product.core.transfer.Transactional; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | |
| | | import com.product.core.exception.BaseException; |
| | | import com.product.core.service.support.AbstractBaseService; |
| | | import com.product.core.spring.context.SpringMVCContextHolder; |
| | | import com.product.mobile.core.config.MobileCoreCode; |
| | | import com.product.mobile.core.config.MobileCoreConst; |
| | | import com.product.module.sys.entity.SystemUser; |
| | | import com.product.util.BaseUtil; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | |
| | | /** |
| | | * 手机端,获取用户所有应用 |
| | |
| | | public BaseDao baseDao; |
| | | /** |
| | | * 先查出历史打卡记录 |
| | | * @param cpage |
| | | * @param pagesize |
| | | * @return |
| | | * @throws BaseException |
| | | */ |
| | | @Transactional |
| | | public boolean signIn(FieldSetEntity fse) throws BaseException{ |
| | | fse.setTableName(MobileCoreConst.TABLE_PUNCH_RECORD); |
| | | fse.setTableName(MobileCoreConst.TABLE_PUNCH_RECORD); |
| | | |
| | | SystemUser user=SpringMVCContextHolder.getCurrentUser(); |
| | | Date d = new Date(); |
| | | DataTableEntity dt=signInList(fse); |
| | | if(user!=null) { |
| | | fse.setValue(MobileCoreConst.ORG_LEVEL_UUID, user.getOrg_level_uuid()); |
| | | fse.setValue(MobileCoreConst.DEPT_UUID, user.getDept_uuid()); |
| | | fse.setValue(MobileCoreConst.CREATED_UTC_DATETIME, d); |
| | | } |
| | | fse.setValue(MobileCoreConst.FIELD_PUNCH_TYPE,1);//手机打卡 |
| | | |
| | | |
| | | //获取当天打卡记录 |
| | | DataTableEntity fs_record=signInList(); |
| | | |
| | | fse.setValue(MobileCoreConst.ORG_LEVEL_UUID, user.getOrg_level_uuid()); |
| | | fse.setValue(MobileCoreConst.DEPT_UUID, user.getDept_uuid()); |
| | | fse.setValue(MobileCoreConst.CREATED_UTC_DATETIME, d); |
| | | fse.setValue(MobileCoreConst.CREATED_BY, user.getUser_id()); |
| | | |
| | | //获取打卡设置 |
| | | FieldSetEntity fs_time = baseDao.getFieldSetByFilter(MobileCoreConst.TABLE_PUNCH_TIME, "punch_site_uuid=?", new Object[]{fse.getString("punch_congfig_uuid")}, false); |
| | | if (!StringUtils.isEmpty(fs_time.getString("morning_work_off"))&&!StringUtils.isEmpty(fs_time.getString("afternoon_work"))){ |
| | | //两次打卡保存规则 |
| | | signTime(fs_time,fs_record,fse,4); |
| | | }else { |
| | | //两次打卡保存规则 |
| | | signTime(fs_time,fs_record,fse,2); |
| | | } |
| | | return baseDao.saveFieldSetEntity(fse); |
| | | } |
| | | } |
| | | /** |
| | | * 打卡定位 ,下班卡,可以重复打,复盖前面的,以最后一次为准 |
| | | * |
| | | * @param record 当天打卡记录 |
| | | * @param fse 本次打卡信息 |
| | | * @param type 两次卡 或四次卡 |
| | | */ |
| | | private void signTime(FieldSetEntity config,DataTableEntity record,FieldSetEntity fse, int type) { |
| | | int t=5; |
| | | String rule=null; |
| | | if(!StringUtils.isEmpty( fse.getString("punch_congfig_uuid"))) { |
| | | if(type==2) { //对应2次打卡 |
| | | if(fse.getInteger("punch_type")==1) {//下班 |
| | | fse.setValue("punch_type","4"); |
| | | t=4; |
| | | rule=config.getString("afternoon_work_off"); |
| | | }else {//上班 |
| | | if(check(record,"1")) { |
| | | throw new BaseException(MobileCoreCode.SIGN_IN_REPEAT_FAIL); |
| | | } |
| | | fse.setValue("punch_type","1"); |
| | | t=1; |
| | | rule=config.getString("morning_work"); |
| | | } |
| | | }else {//对应4次打卡 |
| | | if(fse.getInteger("punch_type")==1) {//下班 |
| | | //打下班卡,比下午上班时间早,则为上午下班卡,否则 为下午下班卡 |
| | | if(dataCompareTo(fse.getDate("punch_time"),config.getDate("afternoon_work")) ) { |
| | | fse.setValue("punch_type","2"); |
| | | t=2; |
| | | rule=config.getString("morning_work_off"); |
| | | }else { |
| | | fse.setValue("punch_type","4"); |
| | | t=4; |
| | | rule=config.getString("afternoon_work_off"); |
| | | } |
| | | }else {//上班 |
| | | //上班卡,比上午下班早,记上午上班卡 |
| | | if(dataCompareTo(fse.getDate("punch_time"),config.getDate("morning_work_off")) ) { |
| | | if(check(record,"1")) { |
| | | throw new BaseException(MobileCoreCode.SIGN_IN_REPEAT_FAIL); |
| | | } |
| | | fse.setValue("punch_type","1"); |
| | | t=1; |
| | | rule=config.getString("morning_work"); |
| | | }else {//记下午上班卡 |
| | | if(check(record,"3")) { |
| | | throw new BaseException(MobileCoreCode.SIGN_IN_REPEAT_FAIL); |
| | | } |
| | | fse.setValue("punch_type","3"); |
| | | t=3; |
| | | rule=config.getString("afternoon_work"); |
| | | } |
| | | } |
| | | } |
| | | }else { |
| | | fse.setValue("punch_type","5");///灵活打卡 |
| | | } |
| | | if(rule!=null) { |
| | | rule=rule.substring(10); |
| | | rule=DateUtil.formatDate(new Date())+rule; |
| | | } |
| | | long resutl=signinResult(DateUtil.parse(rule),fse.getDate("punch_time"),t); |
| | | if(resutl>0) { |
| | | fse.setValue("sign_in_result", 0);//迟到 |
| | | }else if (resutl<0) { |
| | | fse.setValue("sign_in_result", 1);//早退 |
| | | resutl=resutl*-1; |
| | | }else { |
| | | fse.setValue("sign_in_result", 2);//正常 |
| | | } |
| | | fse.setValue("signin_result_num", resutl); |
| | | } |
| | | //计算考勤结果,小于0 早退,大于0 迟到 ,等于=0 正常 |
| | | /** |
| | | * |
| | | * @param rule 考勤时间 |
| | | * @param punch_time 打卡时间 |
| | | * @return |
| | | */ |
| | | private long signinResult (Date rule,Date punch_time,int type) { |
| | | |
| | | if(type==1 || type==3) { //上班 |
| | | long diffInMilliseconds = punch_time.getTime() - rule.getTime(); |
| | | long diffInMinutes = diffInMilliseconds / (60 * 1000); |
| | | return diffInMinutes>0?diffInMinutes:0; |
| | | }else if(type==2 ||type==4 ) {//下班 |
| | | long diffInMilliseconds = punch_time.getTime() - rule.getTime(); |
| | | long diffInMinutes = diffInMilliseconds / (60 * 1000); |
| | | return diffInMinutes<0?diffInMinutes:0; |
| | | }else { |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | //上班时间不能重复打卡 |
| | | private boolean check(DataTableEntity record,String type) { |
| | | for(int i=0;i<record.getRows();i++) { |
| | | if(type.equals( record.getFieldSetEntity(i).getString("punch_type"))) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 将两个时间得时分秒进行对比true则为前者早 否则就是一样时间或者后者早 |
| | | * @param a |
| | | * @param b |
| | | * @return |
| | | */ |
| | | private boolean dataCompareTo(Date a,Date b){ |
| | | a.setTime(a.getTime() % (24 * 60 * 60 * 1000)); // 设置date2为当天的00:00:00 |
| | | b.setTime(b.getTime() % (24 * 60 * 60 * 1000)); // 设置date2为当天的00:00:00 |
| | | if (a.compareTo(b) < 0) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | /** |
| | | * 查出指定日期打卡记录 |
| | | * @param cpage |
| | |
| | | * @return |
| | | * @throws BaseException |
| | | */ |
| | | public DataTableEntity signInList(FieldSetEntity fse) throws BaseException{ |
| | | public DataTableEntity signInList() throws BaseException{ |
| | | SystemUser user=SpringMVCContextHolder.getCurrentUser(); |
| | | Date d = new Date(); |
| | | String str = sdf.format(d); //将日期转换为字符串且格式按照之前制定的 |
| | | StringBuilder sql=new StringBuilder(); |
| | | sql.append("select * from ").append(MobileCoreConst.TABLE_PUNCH_RECORD) |
| | | .append(" where created_by=? and DATE_FORMAT(created_utc_datetime,'%Y-%m-%d')=? "); |
| | | |
| | | DataTableEntity dt=baseDao.listTable(sql.toString(), new Object[] {user.getUser_id(),str}); |
| | | return dt; |
| | | DataTableEntity fs = baseDao.listTable(MobileCoreConst.TABLE_PUNCH_RECORD, "created_by=? and DATE_FORMAT(created_utc_datetime,'%Y-%m-%d')=?", new Object[]{user.getUser_id(), str}); |
| | | return fs; |
| | | } |
| | | /** |
| | | * 查询公司定义的考勤点 |
| | |
| | | * @return |
| | | */ |
| | | public DataTableEntity signInSites(String org_level_uuid) { |
| | | if(StringUtils.isEmpty(org_level_uuid)) { |
| | | return baseDao.listTable(MobileCoreConst.TABLE_PUNCH_SITE); |
| | | }else { |
| | | return baseDao.listTable(MobileCoreConst.TABLE_PUNCH_SITE,"org_level_uuid=?",new String[] {org_level_uuid}); |
| | | } |
| | | StringBuilder sql=new StringBuilder(); |
| | | sql.append("select * from "); |
| | | sql.append(MobileCoreConst.TABLE_PUNCH_SITE); |
| | | sql.append(" a left join product_oa_punch_time b on b.punch_site_uuid=a.uuid where a.org_level_uuid=?"); |
| | | return baseDao.listTable(sql.toString(), new String[] {org_level_uuid}); |
| | | } |
| | | |
| | | } |