package com.tykj.dev.union;

import com.tykj.dev.config.Log;
import com.tykj.dev.config.LogType;
import com.tykj.dev.config.Param;
import com.tykj.dev.device.allot.service.AllotBackBillService;
import com.tykj.dev.device.allot.service.AllotBillService;
import com.tykj.dev.device.allot.subject.domin.AllotBackBill;
import com.tykj.dev.device.allot.subject.domin.AllotBill;
import com.tykj.dev.device.apply.service.DeviceApplyBillService;
import com.tykj.dev.device.apply.subject.domin.DeviceApplyBill;
import com.tykj.dev.device.confirmcheck.repository.DeviceCheckBillDao;
import com.tykj.dev.device.confirmcheck.repository.DeviceCheckDetailDao;
import com.tykj.dev.device.confirmcheck.repository.DeviceCheckStatDao;
import com.tykj.dev.device.file.service.FilesUtil;
import com.tykj.dev.device.library.subject.vo.FileVo;
import com.tykj.dev.device.matching.service.MatchingDeviceBillService;
import com.tykj.dev.device.matching.subject.domin.MatchingDeviceBill;
import com.tykj.dev.device.packing.service.PackingLibraryService;
import com.tykj.dev.device.repair.repository.RepairBackBillDao;
import com.tykj.dev.device.repair.repository.RepairSendBillDao;
import com.tykj.dev.device.repair.service.RepairBillService;
import com.tykj.dev.device.repair.subject.domin.RepairBackBill;
import com.tykj.dev.device.repair.subject.domin.RepairBill;
import com.tykj.dev.device.repair.subject.domin.RepairSendBill;
import com.tykj.dev.device.retired.service.DeviceRetiredBillService;
import com.tykj.dev.device.selfcheck.service.SelfCheckBillService;
import com.tykj.dev.device.selfcheck.subject.domin.SelfCheckBill;
import com.tykj.dev.device.storage.service.StorageBillService;
import com.tykj.dev.device.storage.subject.domin.StorageBill;
import com.tykj.dev.device.task.service.TaskLogService;
import com.tykj.dev.device.task.subject.bto.TaskBto;
import com.tykj.dev.device.task.subject.bto.TaskLogBto;
import com.tykj.dev.device.train.dao.TrainThemeDao;
import com.tykj.dev.device.train.dao.WorkHandoverDao;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.base.BeanHelper;
import com.tykj.dev.misc.base.StatusEnum;
import com.tykj.dev.misc.utils.SpringUtils;
import com.tykj.dev.rfid.service.RfidChangeBillService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 业务操作日志aop
 *
 * @author dengdiyi
 */
@Slf4j
@Aspect
@Component
public class LogAspect {

    @Autowired
    private TaskLogService taskLogService;

    @Autowired
    private UserUtils userUtils;

    /**
     * 所有参数
     */
    private Object[] args;

    /**
     * 输入参数Task
     */
    private TaskBto inputTask = new TaskBto();

    /**
     * 输出参数Task
     */
    private TaskBto outPutTask;

    /**
     * 日志操作描述
     */
    private String opreation;

    /**
     * 参数类
     */
    private Param params;

    /**
     * 业务类型
     */
    private Integer businessType;

    /**
     * 日志附件信息
     */
    private List<FileVo> fileVos = new ArrayList<>();

    /**
     * 业务旧状态
     */
    private Integer oldStatus;

    /**
     * 业务新状态
     */
    private Integer newStatus;

    /**
     * 业务账单中的所有参数名
     */
    private List<String> paramNames = new ArrayList<>();

    /**
     * 业务操作日志定义切入点
     */
    @Pointcut("@annotation(com.tykj.dev.config.Log)")
    public void operationLog() {
    }

    /**
     * 方法执行前触发
     */
    @Before(value = "operationLog()")
    public void doBefore(JoinPoint point) {
        //获取旧Task状态
        this.args = point.getArgs();
        //找到输入的taskBto
        for (Object o : this.args) {
            if ("TaskBto".equals(o.getClass().getSimpleName())) {
                ModelMapper modelMapper = BeanHelper.getUserMapper();
                modelMapper.map(o, this.inputTask);
                this.oldStatus = this.inputTask.getBillStatus();
                break;
            }
        }
    }

    /**
     * 新增结果返回后触发
     */
    @AfterReturning(returning = "returnValue", pointcut = "operationLog() && @annotation(log1)")
    public void doAfterReturning(JoinPoint point, Object returnValue, Log log1) {
        try {
            //输出的taskBto
            this.outPutTask = (TaskBto) returnValue;
            this.businessType = this.outPutTask.getBusinessType();
            this.newStatus = this.outPutTask.getBillStatus();

            if (this.inputTask.getId() != null) {
                for (LogType l : LogType.values()) {
                    if (l.oldStatus.equals(oldStatus) && l.newStatus.equals(newStatus) &&l.businessType.equals(outPutTask.getBusinessType())) {
                        this.opreation = l.getOperation();
                        break;
                    }
                }
            } else {
                this.oldStatus = 0;
                for (LogType l : LogType.values()) {
                    if (l.oldStatus == 0 && l.newStatus.equals(newStatus)&&l.businessType.equals(outPutTask.getBusinessType())) {
                        this.opreation = l.getOperation();
                        break;
                    }
                }
            }
            params = new Param();
            //获取账单的所有属性名称
            this.getBillParam();
            if (opreation != null && !opreation.isEmpty()) {
                // 将模板中的参数全部替换掉
                opreation = this.replaceParam(opreation);
            }

            if (this.opreation == null) {
                log.warn("[业务操作日志]存储失败:找不到业务类型为+"+outPutTask.getBusinessType()+",旧状态为" + this.oldStatus + ",新状态为" + this.newStatus + "的日志模板");
            }
//            else if (!confirmUser(this.outPutTask)){
//                log.info("当前任务不是当前登入用户的代办任务-任务id：{},用户id：{},指向下标{}",this.outPutTask.getId(),userUtils.getCurrentUserId(),this.outPutTask.getCurrentPoint());
//            }
            else {
                TaskLogBto taskLogBto = new TaskLogBto(this.outPutTask.getId(), this.opreation, this.fileVos);
                taskLogBto.setOldStatus(this.oldStatus);
                taskLogService.addLog(taskLogBto);
                this.fileVos = new ArrayList<>();
                this.opreation = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    @Autowired
//    private UserCache userCache;
//
//    public boolean confirmUser(TaskBto taskBto){
//        Integer userId = userUtils.getCurrentUserId();
//        List<Integer> userIds = taskBto.getInvolveUserIdList();
//        List<Integer> ids = new ArrayList<>();
//        if (userIds.size() > 0 && taskBto.getCurrentPoint() < userIds.size()) {
//            Integer userId3 = userIds.get(taskBto.getCurrentPoint());
//            //当前指针userId大于0，待办人即当前id
//            if (userId3 > 0) {
//                ids.add(userId3);
//            }
//            //当前指针userId等于0，待办人为所属单位下所有用户
//            else if (userId3 == 0 && taskBto.getOwnUnit() != null) {
//                List<User> users = userCache.findAll();
//                users.stream().filter(user -> user.getUnitsId().equals(taskBto.getOwnUnit())).forEach(user -> {
//                    ids.add(user.getUserId());
//                });
//            }
//        }
//        if (ids.contains(userId)){
//           return true;
//        }else {
//            return false;
//        }
//    }

    /**
     * 将模板中的预留字段全部替换为拦截到的参数
     */
    private String replaceParam(String template) {
        // 将模板中的需要替换的参数转化成map
        Map<String, String> paramsMap = this.convertToMap(template);
        for (String key : paramsMap.keySet()) {
            template = template.replace("%" + key, paramsMap.get(key)).replace("(", "").replace(")", "");
        }
        return template;
    }

    /**
     * 将模板中的参数转换成map的key-value形式
     */
    private Map<String, String> convertToMap(String template) {
        Map<String, String> map = new HashMap<>();
        String[] arr = template.split("\\(");
        for (String s : arr) {
            if (s.contains("%")) {
                String key = s.substring(s.indexOf("%"), s.indexOf(")")).replace("%", "").replace(")", "").replace("-", "").replace("]", "");
                String value = this.getParam(this.params, key);
                map.put(key, "null".equals(value) ? "(空)" : value);
            }
        }
        return map;
    }

    /**
     * 通过反射获取传入的类中对应key的值
     */
    private <T> String getParam(T targetClass, String key) {
        String value = "";
        try {
            Method targetClassParamGetMethod = targetClass.getClass().getMethod("get" + this.setFirstLetterUpperCase(key));
            value = String.valueOf(targetClassParamGetMethod.invoke(targetClass));
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return value;
    }

    /**
     * 将字符串的首字母大写
     */
    private String setFirstLetterUpperCase(String str) {
        if (str == null) {
            return null;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
     * 获取业务对应账单的参数
     */
    private void getBillParam() {
        //获取账单
        switch (this.businessType) {
            case 1:
                PackingLibraryService packingLibraryService = SpringUtils.getBean("packingLibraryServiceImpl");
                if (packingLibraryService != null) {
                    getFieldsParam(packingLibraryService.getOne(outPutTask.getBillId()));
                }
                break;
            case 2:
                StorageBillService storageBillService = SpringUtils.getBean("storageBillServiceImpl");
                if (storageBillService != null) {
                    StorageBill storageBill = storageBillService.getOne(outPutTask.getBillId());
                    getFieldsParam(storageBill);
                    if (this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.END.id)
                            ||this.oldStatus.equals(StatusEnum.WAIT_STORAGE.id) && this.newStatus.equals(StatusEnum.END.id)) {
                        FilesUtil.stringFileToList(storageBill.getAllotFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("配发单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
//                        if (storageBill.getFileName()!=null&&storageBill.getFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("配发单", storageBill.getFileName(), storageBill.getFileUrl()));
//                        }
//                        this.fileVos.add(new FileVo("入库确认单", storageBill.getReceiveFileName(), storageBill.getReceiveFileUrl()));
                    }
                }
                break;
            case 3:
                AllotBillService allotBillService = SpringUtils.getBean("allotBillServiceImpl");
                if (allotBillService != null) {
                    AllotBill allotBill = allotBillService.getOne(outPutTask.getBillId());
                    getFieldsParam(allotBill);
//                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.ALLOTING.id))
//                            || (this.oldStatus.equals(StatusEnum.WAIT_ALLOT.id) && this.newStatus.equals(StatusEnum.ALLOTING.id))
//                            || (this.oldStatus.equals(StatusEnum.ALLOT_DRAFT.id) && this.newStatus.equals(StatusEnum.ALLOTING.id))) {
//                        this.fileVos.add(new FileVo("出库确认单", allotBill.getFileName(), allotBill.getFileUrl()));
//                    }
                    if ((this.oldStatus.equals(StatusEnum.ALLOTING.id) && this.newStatus.equals(StatusEnum.END.id))
                    || (this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_ALLOT_RECEIVE_FILE.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        if (allotBill.getBillFileName()!=null&&allotBill.getBillFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("配发单", allotBill.getBillFileName(), allotBill.getBillFileUrl()));
//                        }
                        FilesUtil.stringFileToList(allotBill.getReceiveFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("配发单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
//                        this.fileVos.add(new FileVo("入库确认单", allotBill.getReceiveFileName(), allotBill.getReceiveFileUrl()));
                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_ALLOT_FILE.id) && this.newStatus.equals(StatusEnum.END.id))
                    || this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_CROSS_FILE.id) && this.newStatus.equals(StatusEnum.END.id)) {
                        FilesUtil.stringFileToList(allotBill.getSendFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("配发单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                }
                break;
            case 22:
                AllotBackBillService allotBackBillService = SpringUtils.getBean("allotBackBillServiceImpl");
                if (allotBackBillService != null && outPutTask.getBillId() > 0) {
                    AllotBackBill allotBackBill = allotBackBillService.getOne(outPutTask.getBillId());
                    getFieldsParam(allotBackBill);
//                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.ALLOT_BACKING.id))) {
//                        this.fileVos.add(new FileVo("出库确认单", allotBackBill.getFileName(), allotBackBill.getFileUrl()));
//                    }
                    if ((this.oldStatus.equals(StatusEnum.ALLOT_BACKING.id) && this.newStatus.equals(StatusEnum.END.id))
                       ||this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_ALLOT_BACK_FILE.id) && this.newStatus.equals(StatusEnum.END.id)) {
//                        if (allotBackBill.getBillFileName()!=null&&allotBackBill.getBillFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("退回单", allotBackBill.getBillFileName(), allotBackBill.getBillFileUrl()));
//                        }
                        FilesUtil.stringFileToList(allotBackBill.getReceiveFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("退回单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
//                        this.fileVos.add(new FileVo("入库确认单", allotBackBill.getReceiveFileName(), allotBackBill.getReceiveFileUrl()));
                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_BACK_FILE_2.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        FilesUtil.stringFileToList(allotBackBill.getSendFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("退回单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                }
                break;
            case 4:
                SelfCheckBillService selfCheckBillService = SpringUtils.getBean("selfCheckBillServiceImpl");
                if (selfCheckBillService != null && outPutTask.getBillId() > 0) {
                    SelfCheckBill selfCheckBill = selfCheckBillService.getOne(outPutTask.getBillId());
                    getFieldsParam(selfCheckBill);
                    if ((this.oldStatus.equals(StatusEnum.SELF_CHECK_CONFIRM.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        FilesUtil.stringFileToList(selfCheckBill.getCheckFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("自查单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        if (selfCheckBill.getCheckFiles()!=null) {
                            FilesUtil.stringFileToList(selfCheckBill.getCheckFiles()).forEach(fileRet -> {
                                this.fileVos.add(new FileVo("自查单", fileRet.getName(), fileRet.getPreviewPath()));
                            });
                        }
                    }
                }
                break;
            case 5:
                RepairBillService repairBillService = SpringUtils.getBean("repairBillServiceImpl");
                RepairSendBillDao repairSendBillDao = SpringUtils.getBean("repairSendBillDao");
                if (repairBillService != null && repairSendBillDao != null) {
                    RepairBill repairBill = repairBillService.getOne(outPutTask.getBillId());
                    RepairSendBill repairSendBill = repairSendBillDao.findByDeviceRepairBillId(repairBill.getId());
                    getFieldsParam(repairBillService.getOne(outPutTask.getBillId()));
//                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.WAIT_RECEIVE.id))
//                    ||(this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        this.fileVos.add(new FileVo("出库确认单", repairSendBill.getFileName(), repairSendBill.getFileUrl()));
//                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_RECEIVE.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        if (repairSendBill.getBillFileName()!=null&&repairSendBill.getBillFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("维修单", repairSendBill.getBillFileName(), repairSendBill.getBillFileUrl()));
//                        }
                        FilesUtil.stringFileToList(repairSendBill.getReceiveFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("维修单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
//                        this.fileVos.add(new FileVo("入库确认单", repairSendBill.getReceiveFileName(), repairSendBill.getReceiveFileUrl()));
                    }
//                    if ((this.oldStatus.equals(StatusEnum.WAIT_RECEIVE.id) && this.newStatus.equals(StatusEnum.WAIT_UPLOAD_FILE.id))) {
//                        this.fileVos.add(new FileVo("入库确认单", repairSendBill.getReceiveFileName(), repairSendBill.getReceiveFileUrl()));
//                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_FILE.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        if (repairSendBill.getBillFileName()!=null&&repairSendBill.getBillFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("维修单", repairSendBill.getBillFileName(), repairSendBill.getBillFileUrl()));
//                        }
                        FilesUtil.stringFileToList(repairSendBill.getReceiveFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("维修单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_SEND_FILE.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        FilesUtil.stringFileToList(repairSendBill.getSendFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("维修单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                }
                break;
            case 6:
                DeviceCheckBillDao deviceCheckBillDao = SpringUtils.getBean("deviceCheckBillDao");
                if (deviceCheckBillDao != null) {
                    getFieldsParam(deviceCheckBillDao.getOne(outPutTask.getBillId()));
                }
                break;
            case 7:
                DeviceCheckStatDao deviceCheckStatDao = SpringUtils.getBean("deviceCheckStatDao");
                if (deviceCheckStatDao != null) {
                    getFieldsParam(deviceCheckStatDao.getOne(outPutTask.getBillId()));
                }
                break;
            case 8:
                DeviceCheckDetailDao deviceCheckDetailDao = SpringUtils.getBean("deviceCheckDetailDao");
                if (deviceCheckDetailDao != null) {
                    getFieldsParam(deviceCheckDetailDao.getOne(outPutTask.getBillId()));
                }
                break;
            case 9:
                DeviceApplyBillService deviceApplyBillService = SpringUtils.getBean("deviceApplyBillServiceImpl");
                if (deviceApplyBillService != null) {
                    DeviceApplyBill deviceApplyBill = deviceApplyBillService.getOne(outPutTask.getBillId());
                    getFieldsParam(deviceApplyBillService.getOne(outPutTask.getBillId()));
                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        FilesUtil.stringFileToList(deviceApplyBill.getApplyFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("申请单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                }
                break;
            case 10:
                RepairBackBillDao repairBackBillDao = SpringUtils.getBean("repairBackBillDao");
                if (repairBackBillDao != null) {
                    RepairBackBill repairBackBill = repairBackBillDao.getOne(outPutTask.getBillId());
                    getFieldsParam(repairBackBill);
//                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.WAIT_BACK_RECEIVE.id))) {
//                        this.fileVos.add(new FileVo("出库确认单", repairBackBill.getFileName(), repairBackBill.getFileUrl()));
//                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_BACK_RECEIVE.id) && this.newStatus.equals(StatusEnum.END.id))||
                            (this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        if (repairBackBill.getReceiveFileName()!=null&&repairBackBill.getReceiveFileUrl()!=null) {
                            this.fileVos.add(new FileVo("签收单", repairBackBill.getReceiveFileName(), repairBackBill.getReceiveFileUrl()));
                        }
//                        this.fileVos.add(new FileVo("入库确认单", repairBackBill.getReceiveFileName(), repairBackBill.getReceiveFileUrl()));
                    }
//                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.WAIT_UPLOAD_BACK_FILE.id))
//                        ||(this.oldStatus.equals(StatusEnum.WAIT_BACK_RECEIVE.id) && this.newStatus.equals(StatusEnum.WAIT_UPLOAD_BACK_FILE.id))) {
//                        this.fileVos.add(new FileVo("出库确认单", repairBackBill.getFileName(), repairBackBill.getFileUrl()));
//                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_BACK_FILE.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        if (repairBackBill.getBillFileName()!=null&&repairBackBill.getBillFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("领取单", repairBackBill.getBillFileName(), repairBackBill.getBillFileUrl()));
//                        }
                        FilesUtil.stringFileToList(repairBackBill.getReceiveFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("领取单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_BACK_SEND_FILE.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        FilesUtil.stringFileToList(repairBackBill.getSendFiles()).forEach(fileRet -> {
                            this.fileVos.add(new FileVo("领取单", fileRet.getName(), fileRet.getPreviewPath()));
                        });
                    }
                }
                break;
            case 13:
                TrainThemeDao trainThemeDao = SpringUtils.getBean("trainThemeDao");
                if (trainThemeDao != null) {
                    getFieldsParam(trainThemeDao.getOne(outPutTask.getBillId()));
                }
                break;
            case 14:
//                DeviceDestroyBillService deviceDestroyBillService = SpringUtils.getBean("deviceDestroyBillServiceImpl");
//                if (deviceDestroyBillService != null) {
//                    DeviceDestroyBill deviceDestroyBill = deviceDestroyBillService.getOne(outPutTask.getBillId());
//                    getFieldsParam(deviceDestroyBill);
////                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.WAIT_UPLOAD_BILL_FILE.id))) {
////                        this.fileVos.add(new FileVo("出库确认单", deviceDestroyBill.getFileName(), deviceDestroyBill.getFileUrl()));
////                    }
//                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_BILL_FILE.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        if (deviceDestroyBill.getDestroyFileName()!=null&&deviceDestroyBill.getDestroyFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("销毁单", deviceDestroyBill.getDestroyFileName(), deviceDestroyBill.getDestroyFileUrl()));
//                        }
//                    }
//                }
                break;
            case 15:
                DeviceRetiredBillService deviceRetiredBillService = SpringUtils.getBean("deviceRetiredBillServiceImpl");
                if (deviceRetiredBillService != null) {
                    getFieldsParam(deviceRetiredBillService.getOne(outPutTask.getBillId()));
                }
                break;
            case 16:
//                SendBackBillDao sendBackBillDao = SpringUtils.getBean("sendBackBillDao");
//                SendBackBillDetailDao sendBackBillDetailDao = SpringUtils.getBean("sendBackBillDetailDao");
//                if (sendBackBillDao != null && sendBackBillDetailDao != null) {
//                    SendBackBill sendBackBill = sendBackBillDao.getOne(outPutTask.getBillId());
//                    SendBackBillDetail sendBackBillDetail = sendBackBillDetailDao.findSendBackBillDetailById(sendBackBill.getFormId());
//                    getFieldsParam(sendBackBillDetail);
////                    if ((this.oldStatus.equals(StatusEnum.SEND_BACK_1203.id) && this.newStatus.equals(StatusEnum.SEND_BACK_1206.id))) {
////                        this.fileVos.add(new FileVo("出库确认单", sendBackBillDetail.getFileName(), sendBackBillDetail.getFileUrl()));
////                    }
//                    if ((this.oldStatus.equals(StatusEnum.SEND_BACK_1206.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        if (sendBackBillDetail.getBillFileName()!=null&&sendBackBillDetail.getBillFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("清退单", sendBackBillDetail.getBillFileName(), sendBackBillDetail.getBillFileUrl()));
//                        }
//                    }
//                }
                break;
            case 19:
                MatchingDeviceBillService matchingDeviceBillService = SpringUtils.getBean("matchingDeviceBillServiceImpl");
                if (matchingDeviceBillService != null) {
                    MatchingDeviceBill matchingDeviceBill = matchingDeviceBillService.getOne(outPutTask.getBillId());
                    getFieldsParam(matchingDeviceBill);
                    if ((this.oldStatus.equals(StatusEnum.ORIGIN_STATUS.id) && this.newStatus.equals(StatusEnum.END.id))) {
                        if (matchingDeviceBill.getFileName()!=null&&matchingDeviceBill.getFileUrl()!=null) {
                            this.fileVos.add(new FileVo("新增确认单", matchingDeviceBill.getFileName(), matchingDeviceBill.getFileUrl()));
                        }
                    }
                }
                break;
            case 20:
                RfidChangeBillService rfidChangeBillService = SpringUtils.getBean("rfidChangeBillServiceImpl");
                if (rfidChangeBillService != null) {
                    getFieldsParam(rfidChangeBillService.getOne(outPutTask.getBillId()));
                }
                break;
            case 21:
                WorkHandoverDao workHandoverDao = SpringUtils.getBean("workHandoverDao");
                if (workHandoverDao != null) {
                    getFieldsParam(workHandoverDao.getOne(outPutTask.getBillId()));
                }
                break;
            case 23:
//                ScrapBillService scrapBillService = SpringUtils.getBean("scrapBillServiceImpl");
//                if (scrapBillService != null) {
//                    ScrapBill scrapBill = scrapBillService.getOne(outPutTask.getBillId());
//                    getFieldsParam(scrapBill);
//                    if ((this.oldStatus.equals(StatusEnum.WAIT_UPLOAD_SCRAP_FILE.id) && this.newStatus.equals(StatusEnum.END.id))) {
//                        if (scrapBill.getFileName()!=null&&scrapBill.getFileUrl()!=null) {
//                            this.fileVos.add(new FileVo("报废单", scrapBill.getFileName(), scrapBill.getFileUrl()));
//                        }
//                    }
//                }
                break;
            default:
                break;
        }
    }

    /**
     * 遍历账单实体类名称并添加到paramNames
     */
    private <T> void getFieldsParam(T target) {
        Field[] fields = target.getClass().getDeclaredFields();
        for (Field field : fields) {
            paramNames.add(field.getName());
            String paramName = field.getName();
            if (this.isExist(paramName)) {
                String value = this.getParam(target, paramName);
                this.setParam(this.params, paramName, value);
            }
        }
    }

    /**
     * 判断该参数在参数类中是否存在（是否是需要记录的参数）
     */
    private <T> Boolean isExist(String name) {
        boolean exist = true;
        try {
            String key = this.setFirstLetterUpperCase(name);
            Method targetClassGetMethod = this.params.getClass().getMethod("get" + key);
        } catch (Exception e) {
            exist = false;
        }
        return exist;
    }

    /**
     * 将数据写入参数类的实例中
     */
    private <T> void setParam(T targetClass, String key, String value) {
        try {
            Method targetClassParamSetMethod = targetClass.getClass().getMethod("set" + this.setFirstLetterUpperCase(key), String.class);
            targetClassParamSetMethod.invoke(targetClass, value);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
