SignInServiceImpl.java 9.63 KB
package com.ruoyi.in.service.impl;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.SignInEnum;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.Seq;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.driver.domain.Driver;
import com.ruoyi.pojo.response.ResponseScheduling;
import com.ruoyi.service.ThreadJobService;
import com.ruoyi.utils.ConstDateUtil;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.in.mapper.SignInMapper;
import com.ruoyi.in.domain.SignIn;
import com.ruoyi.in.service.ISignInService;

import javax.annotation.Resource;

import static com.ruoyi.common.ErrorTypeProperties.*;
import static com.ruoyi.common.SignInEnum.*;
import static com.ruoyi.common.redispre.GlobalRedisPreName.REDIS_SIGN_IN;

/**
 * 签到Service业务层处理
 *
 * @author guzijian
 * @date 2023-07-05
 */
@Service
public class SignInServiceImpl implements ISignInService {
    @Autowired
    private SignInMapper signInMapper;

    @Autowired
    private RedisCache redisCache;

    @Resource
    private ThreadJobService threadJobConfig;

    /**
     * 查询签到
     *
     * @param id 签到主键
     * @return 签到
     */
    @Override
    public SignIn selectSignInById(Long id) {
        return signInMapper.selectSignInById(id);
    }

    /**
     * 查询签到列表
     *
     * @param signIn 签到
     * @return 签到
     */
    @Override
    public List<SignIn> selectSignInList(SignIn signIn) {
        return signInMapper.selectSignInList(signIn);
    }

    /**
     * 新增签到
     *
     * @param signIn 签到
     * @return 结果
     */
    @Override
    public int insertSignIn(SignIn signIn) {
        signIn.setIp(IpUtils.getIpAddr());
        signIn.setCreateTime(DateUtils.getNowDate());
        if (signIn.getType() == null) {
            signIn.setType(SignInEnum.SIGN_IN);
        }
        if (ALCOHOL_FLAG_YES.equals(signIn.getAlcoholFlag())){
            signIn.setStatus(signIn.getAlcoholIntake().compareTo(new BigDecimal(20)) < 0 ? SIGN_IN_SUCCESS : SIGN_IN_FAIL);
            signIn.setRemark(signIn.getStatus().equals(SIGN_IN_FAIL)? "酒精测试不通过超标:" + signIn.getAlcoholIntake().floatValue() + "%" : "");
        }
        return signInMapper.insertSignIn(signIn);
    }

    /**
     * 修改签到
     *
     * @param signIn 签到
     * @return 结果
     */
    @Override
    public int updateSignIn(SignIn signIn) {
        signIn.setUpdateTime(DateUtils.getNowDate());
        return signInMapper.updateSignIn(signIn);
    }

    /**
     * 批量删除签到
     *
     * @param ids 需要删除的签到主键
     * @return 结果
     */
    @Override
    public int deleteSignInByIds(Long[] ids) {
        return signInMapper.deleteSignInByIds(ids);
    }

    /**
     * 删除签到信息
     *
     * @param id 签到主键
     * @return 结果
     */
    @Override
    public int deleteSignInById(Long id) {
        return signInMapper.deleteSignInById(id);
    }

    @Override
    public AjaxResult addSignIn(SignIn signIn) throws  IOException {
        // 签到检查
        checkSignIn(signIn);
        // base64转图片
        signIn.setCreateTime(new Date());
        signIn.setIp(IpUtils.getIpAddr());
        uploadImage(signIn);
        signInMapper.insertSignIn(signIn);
        // TODO 驾驶人员二次签到酒精测试异常
        if (true){
            Integer count = redisCache.getCacheMapValue(ConstDateUtil.formatDate("yyyyMMdd") + REDIS_SIGN_IN, signIn.getJobCode());
            if (Objects.isNull(count)){
                redisCache.setCacheMapValue(ConstDateUtil.formatDate("yyyyMMdd") + REDIS_SIGN_IN, signIn.getJobCode(),0);
            }
            count = redisCache.increment(ConstDateUtil.formatDate("yyyyMMdd") + REDIS_SIGN_IN, signIn.getJobCode(), 1);
            if (count.equals(2) || count.compareTo(2) == 1){

            }
        }


        return SIGN_IN_SUCCESS.equals(signIn.getStatus()) ? AjaxResult.success(SIGN_IN_SUCCESS_STRING): AjaxResult.error(SIGN_IN_ERROR + signIn.getRemark());
    }

    private void checkSignIn(SignIn signIn) {
        // TODO 更具工号获取人员信息
        Driver driver = getDriverInfoByJobCode(signIn.getJobCode());
        if (Objects.isNull(driver)){
            signIn.setStatus(SIGN_IN_SUCCESS);
            return;
        }
        // TODO 排班校验 非司售未作
        checkWorkDay(signIn,driver.getPersonnelType());

        // 酒精测试校验 TODO 判断人员类型
        if (ALCOHOL_FLAG_YES.equals(signIn.getAlcoholFlag())){
            signIn.setStatus(signIn.getAlcoholIntake().compareTo(new BigDecimal(20)) < 0 ? SIGN_IN_SUCCESS : SIGN_IN_FAIL);
            signIn.setRemark(signIn.getStatus().equals(SIGN_IN_FAIL) ? ALCOHOL_SIGN_IN_ERROR : "");
        }
    }

    private Driver getDriverInfoByJobCode(String jobCode) {
        return null;
    }

    private void checkWorkDay(SignIn signIn, String personnelType) {
        List<ResponseScheduling> jobs = null;
        switch (personnelType){
            case "0":
                // 查询工号对应的排班 司售人员
                jobs = redisCache.getCacheMapValue(ConstDateUtil.formatDate("yyyyMMdd"),signIn.getJobCode());
                if (Objects.isNull(jobs)|| jobs.size() == 0){
                    signIn.setStatus(SIGN_IN_FAIL);
                    signIn.setRemark(WORK_DAY_ERROR);
                }
                break;
            case "1":
                // 查询工号对应的排班 非司售人员
                // 查询数据库
                break;
        }

        // 超时校验司售人员
        checkTimeOut(signIn,jobs);
        // TODO 非司售人员

    }

    private void checkTimeOut(SignIn signIn, List<ResponseScheduling> driver) {
        // 那发车时间和到站时间作为开始上班的时间
        LocalDateTime startTime = ConstDateUtil.getLocalDateTimeByLongTime(driver.get(0).getFcsjT());
        LocalDateTime endTime = ConstDateUtil.getLocalDateTimeByLongTime(driver.get(0).getZdsjT());
        LocalDateTime signTime = ConstDateUtil.getLocalDateTimeByLongTime(signIn.getCreateTime().getTime());
        long morningBetween = ChronoUnit.MINUTES.between(startTime, signTime);
        long afternoonBetween = ChronoUnit.MINUTES.between(endTime, signTime);
        if (Math.abs(morningBetween) <= 60 || Math.abs(afternoonBetween) <= 60) {
            signIn.setStatus(SIGN_IN_SUCCESS);
        } else {
            signIn.setStatus(SIGN_IN_FAIL);
            signIn.setRemark(SIGN_IN_TIMEOUT);
        }

    }

    private void uploadImage(SignIn signIn) throws IOException {
        String base64 = signIn.getImage();
        // 图片路径
        String filePath = RuoYiConfig.getUploadPath();
        // 固定jpg文件
        String fileName = "";
        // 看是否带有base64前缀 有就判断文件类型 没有默认jpg
        fileName = checkImageBase64Format(signIn.getImage());
        fileName = extractFilename(fileName);
        // 获取相对路径
        String absPath = getAbsoluteFile(filePath, fileName).getAbsolutePath();

        // 获取文件上传路径
        String pathFileName = getPathFileName(filePath, fileName);
        signIn.setImage(pathFileName);
        // 异步上传文件
        threadJobConfig.startUpload(absPath,base64);
    }

    /**
     * 获取相对路径名
     *
     * @param uploadDir
     * @param fileName
     * @return
     * @throws IOException
     */
    public File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
        File desc = new File(uploadDir + File.separator + fileName);

        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                desc.getParentFile().mkdirs();
            }
        }
        return desc;
    }

    /**
     * 获取扩展文件名
     *
     * @param extendFileName
     * @return
     */
    public String extractFilename(String extendFileName) {
        return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
                FilenameUtils.getBaseName(UUID.randomUUID().toString().replace("-", "")), Seq.getId(Seq.uploadSeqType), extendFileName);
    }

    /**
     * @param uploadDir
     * @param fileName
     * @return
     * @throws IOException
     */
    public String getPathFileName(String uploadDir, String fileName) throws IOException {
        int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
        String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
        return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
    }

    /**
     * 检查文件类型
     *
     * @param base64ImgData
     * @return
     */
    public static String checkImageBase64Format(String base64ImgData) {
        byte[] b = Base64.getDecoder().decode(base64ImgData);
        String type = "";
        if (0x424D == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
            type = "bmp";
        } else if (0x8950 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
            type = "png";
        } else {
            type = "jpg";
        }
//        else if (0xFFD8 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {
//            type = "jpg";
//        }
        return type;
    }
}