shicf
2024-10-24 04eb3f2f80f195a0135fe31adda7e9a01c19589d
签到打卡
已修改3个文件
247 ■■■■■ 文件已修改
src/main/java/com/product/mobile/core/config/MobileCoreCode.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/mobile/core/controller/SignInController.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/mobile/core/service/SignInService.java 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/mobile/core/config/MobileCoreCode.java
@@ -29,6 +29,9 @@
    GET_FACE_FIELD_FAIL("获取表单字段失败", "008"),
    GET_FACE_CONFIG_FAIL("获取表单配置失败", "009"),
    SIGN_IN_REPEAT_FAIL("考勤打卡失败:重复打卡", "010"),
    SIGN_IN_FAIL("考勤打卡失败", "011"),
    ;
    MobileCoreCode(String text, String code) {
src/main/java/com/product/mobile/core/controller/SignInController.java
@@ -11,8 +11,12 @@
import com.product.core.controller.support.AbstractBaseController;
import com.product.core.entity.FieldSetEntity;
import com.product.core.entity.RequestParameterEntity;
import com.product.core.exception.BaseException;
import com.product.core.spring.context.SpringMVCContextHolder;
import com.product.mobile.core.config.MobileCoreCode;
import com.product.mobile.core.service.SignInService;
import com.product.module.sys.version.ApiVersion;
import com.product.org.admin.config.CmnCode;
/**
 *  手机签到
@@ -41,6 +45,7 @@
            fse = reqp.getFormData();
        }
        //签到时,如果上传了uuid,表示,征对公司规定的考勤点的签到,否则表示不在公司规定的考勤点的签到(任意地点签到。)
        signInService.signIn(fse);
        return this.OK();
    }
@@ -60,7 +65,13 @@
            RequestParameterEntity reqp = (RequestParameterEntity) bean;
            fse = reqp.getFormData();
        }
        return this.OK_List(signInService.signInList());
        try {
            return this.OK_List(signInService.signInList());
        } catch (BaseException e) {
            return this.error(e);
        } catch (Exception e) {
            return this.error(MobileCoreCode.SIGN_IN_FAIL);
        }
    }
    /**
     * 获取公司固定考勤点的信息
@@ -77,7 +88,7 @@
            RequestParameterEntity reqp = (RequestParameterEntity) bean;
            fse = reqp.getFormData();
        }
        return this.OK_List(signInService.signInSites(null));
        //获取当前人的公司
        return this.OK_List(signInService.signInSites(SpringMVCContextHolder.getCurrentUser().getCurrentCompany().getUUID()));
    }
}
src/main/java/com/product/mobile/core/service/SignInService.java
@@ -14,9 +14,12 @@
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;
/**
 * 手机端,获取用户所有应用
@@ -36,106 +39,132 @@
     */
    @Transactional
    public boolean signIn(FieldSetEntity fse) throws BaseException{
        fse.setTableName(MobileCoreConst.TABLE_PUNCH_RECORD);
        SystemUser user=SpringMVCContextHolder.getCurrentUser();
        Date d = new Date();
        //获取当前时间打卡记录
        FieldSetEntity fs_record=signInList();
        //获取当天打卡记录
        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"))){
            //四次打卡保存规则
            if (FieldSetEntity.isEmpty(fs_record)){
                //未查询到打开记录新建打卡记录
                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_BY, user.getUser_id());
                    fse.setValue(MobileCoreConst.CREATED_UTC_DATETIME, d);
                }
                fse.setValue(MobileCoreConst.FIELD_PUNCH_TYPE,1);//手机打卡
                if (!StringUtils.isEmpty(fse.getDate("punch_time_one"))){
                    if (dataCompareTo(fse.getDate("punch_time_one"),fs_time.getDate("morning_work_off"))){
                        fse.setValue("punch_time_one",fse.getDate("punch_time_one"));
                        fse.setValue("punch_range_one",fse.getString("punch_range_one"));
                    }else {
                        fse.setValue("punch_time_three",fse.getDate("punch_time_one"));
                        fse.setValue("punch_range_three",fse.getString("punch_range_one"));
                        fse.setValue("punch_time_one",null);
                        fse.setValue("punch_range_one",null);
                    }
                }
                if (!StringUtils.isEmpty(fse.getDate("punch_time_four"))){
                    if (dataCompareTo(fse.getDate("punch_time_four"),fs_time.getDate("afternoon_work_off"))){
                        fse.setValue("punch_time_two",fse.getDate("punch_time_four"));
                        fse.setValue("punch_range_two",fse.getString("punch_range_four"));
                    }else {
                        fse.setValue("punch_time_two",null);
                        fse.setValue("punch_range_two",null);
                        fse.setValue("punch_time_four",fse.getDate("punch_time_four"));
                        fse.setValue("punch_range_four",fse.getString("punch_range_four"));
                    }
                }
                fse.setTableName(MobileCoreConst.TABLE_PUNCH_RECORD);
                return     baseDao.saveFieldSetEntity(fse);
            }
            else {
                //查询到已有打开记录新建打卡记录
                if (!StringUtils.isEmpty(fse.getDate("punch_time_one"))){
                    //判断上班打卡打卡规则:1、上午上班未打卡 2、未超过上午下班时间 3、上午未打下班卡 则为上午上班卡否则为下午上班卡
                    if(dataCompareTo(fse.getDate("punch_time_one"),fs_time.getDate("morning_work_off"))
                            &&StringUtils.isEmpty(fs_record.getString("punch_time_one"))
                            &&StringUtils.isEmpty(fs_record.getString("punch_time_two"))){
                        fs_record.setValue("punch_time_one", fse.getDate("punch_time_one"));
                        fs_record.setValue("punch_range_one", fse.getString("punch_range_one"));
                    }else {
                        fs_record.setValue("punch_time_three", fse.getDate("punch_time_one"));
                        fs_record.setValue("punch_range_three", fse.getString("punch_range_one"));
                    }
                }
                //判断下班打卡班打卡规则:1、上午下班未打卡 2、未超过上午下班时间 3、下午午未打上班卡 则为上午下班卡否则为下午下班卡
                if (!StringUtils.isEmpty(fse.getDate("punch_time_four"))){
                    if(dataCompareTo(fse.getDate("punch_time_four"),fs_time.getDate("afternoon_work_off"))
                            &&StringUtils.isEmpty(fs_record.getDate("punch_time_two"))
                            &&StringUtils.isEmpty(fs_record.getDate("punch_time_three"))){
                        fs_record.setValue("punch_time_two", fse.getDate("punch_time_four"));
                        fs_record.setValue("punch_range_two", fse.getString("punch_range_four"));
                    }else {
                        fs_record.setValue("punch_time_four", fse.getDate("punch_time_four"));
                        fs_record.setValue("punch_range_four", fse.getString("punch_range_four"));
                    }
                }
                return baseDao.saveFieldSetEntity(fs_record);
            }
            //两次打卡保存规则
            signTime(fs_time,fs_record,fse,4);
        }else {
            //两次打卡保存规则
            if (FieldSetEntity.isEmpty(fs_record)){
                //未查询到打开记录新建打卡记录
                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.CREATED_BY, user.getUser_id());
                }
                fse.setValue(MobileCoreConst.FIELD_PUNCH_TYPE,1);//手机打卡
                fse.setTableName(MobileCoreConst.TABLE_PUNCH_RECORD);
                return baseDao.saveFieldSetEntity(fse);
            }else {
                //查询到已有打开记录新建打卡记录
                if (!StringUtils.isEmpty(fse.getString("punch_time_one"))){
                    fs_record.setValue("punch_time_one",fse.getDate("punch_time_one"));
                    fs_record.setValue("punch_range_one",fse.getString("punch_range_one"));
                }
                if (!StringUtils.isEmpty(fse.getString("punch_time_four"))){
                    fs_record.setValue("punch_time_four",fse.getDate("punch_time_four"));
                    fs_record.setValue("punch_range_four",fse.getString("punch_range_four"));
                }
                return baseDao.saveFieldSetEntity(fs_record);
            }
            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;
    }
    /**
@@ -159,11 +188,11 @@
     * @return
     * @throws BaseException
     */
    public FieldSetEntity signInList() throws BaseException{
    public DataTableEntity signInList() throws BaseException{
        SystemUser user=SpringMVCContextHolder.getCurrentUser();
        Date d = new Date();
        String str = sdf.format(d); //将日期转换为字符串且格式按照之前制定的
        FieldSetEntity fs = baseDao.getFieldSetByFilter(MobileCoreConst.TABLE_PUNCH_RECORD, "created_by=?  and DATE_FORMAT(created_utc_datetime,'%Y-%m-%d')=?", new Object[]{user.getUser_id(), str}, false);
        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;
    }
    /**
@@ -172,11 +201,11 @@
     * @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});
    }
}