yxh
3 天以前 68b49efb4da346edb42a5d8ebb39af47207402bd
ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceReimbursementServiceImpl.java
@@ -17,6 +17,8 @@
import com.ruoyi.common.utils.HttpClientKit;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.DtoConversionUtils;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.project.common.FundNotifyMessageBuilder;
import com.ruoyi.project.common.IdGeneratorUtils;
import com.ruoyi.project.domain.*;
import com.ruoyi.project.domain.dto.ServiceReimbursementDto;
@@ -27,6 +29,7 @@
import com.ruoyi.project.service.*;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
@@ -116,6 +119,35 @@
    @Value("${spring.profiles.active}")
    private String active;
    @Autowired
    private ISysConfigService sysConfigService;
    /**
     * 审批单是否上传医院协友(致远)系统:0=不上传(测试环境),1=上传(正式环境)。
     *
     * <p>2026-10-09 新增:原来用 {@code spring.profiles.active == druid} 来判断是否推送,
     * 导致测试环境与正式环境无法通过参数区分。改为系统参数控制,环境各自配置。
     */
    private static final String CFG_UPLOAD_OA = "sys.approval.upload.oa";
    /** 参数缺省值:上传(保持正式环境原有行为) */
    private static final boolean DEFAULT_UPLOAD_OA = true;
    /** 审批单是否需要上传医院协友(致远)系统 */
    private boolean isUploadOaEnabled() {
        String value = null;
        try {
            value = sysConfigService.selectConfigByKey(CFG_UPLOAD_OA);
        } catch (Exception e) {
            log.warn("读取参数 {} 失败,按默认值 {} 处理", CFG_UPLOAD_OA, DEFAULT_UPLOAD_OA, e);
        }
        if (value == null || value.trim().isEmpty()) {
            return DEFAULT_UPLOAD_OA;
        }
        String v = value.trim();
        return "1".equals(v) || "true".equalsIgnoreCase(v) || "y".equalsIgnoreCase(v) || "on".equalsIgnoreCase(v);
    }
    /**
@@ -259,7 +291,7 @@
            log.info("上传OA文件方法的入参:{}", serviceReimbursementdetailShareds.get(i));
            try {
                //如果是本地环境,就不调这个了
                if (!active.equals("druid")) uploadOAFileAndUpdateDb(serviceReimbursementdetailShareds.get(i));
                if (isUploadOaEnabled()) uploadOAFileAndUpdateDb(serviceReimbursementdetailShareds.get(i));
            } catch (Exception e) {
                log.error("Exception中reimShare的入参id为:{}", serviceReimbursementShared.getId());
                if (serviceReimbursementShared.getId() != null) {
@@ -333,6 +365,7 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, String> checkFund(LoginUser loginUser, CheckFundVO checkFundVO) {
        Map<String, String> allMap = new HashMap<>();
@@ -397,8 +430,9 @@
                    if (newSwitch == 1) {
                        aBoolean1 = sendData(serviceReimbursement);
                        if (!aBoolean1) {
                            allMap.put("500", "发送失败");
                            return allMap;
                            // 推送医院协友系统失败:整个审批不生效(事务回滚),允许下次重新审批
                            log.error("差旅审批单上传医院协友系统失败,审批不生效,id={},请重新审批", serviceReimbursement.getId());
                            throw new ServiceException("医院协友系统接收失败,本次审批未生效,请稍后重新审批");
                        }
                    }
                    //保存审批流程表
@@ -443,22 +477,25 @@
                    }
                }
                SysUser sysUser = sysUserService.selectUserByUserName(serviceReimbursement.getUserno());
                ArrayList<ConcurrentHashMap<String, Object>> contentList = new ArrayList<>();
                ConcurrentHashMap map = new ConcurrentHashMap();
                map.put("审批人:", loginUser.getUser().getUserName());
                map.put("审批时间:", new Date());
                map.put("意见:", "不通过");
                if (StringUtils.isNotBlank(checkFundVO.getFlowcontent()))
                    map.put("意见:", checkFundVO.getFlowcontent());
                contentList.add(map);
                //审批未通过:单据信息 + 出差信息 + 审批人/审批时间/意见(意见 = "审批未通过。" + 驳回意见)
                List<ConcurrentHashMap<String, Object>> contentList = FundNotifyMessageBuilder.newRows();
                FundNotifyMessageBuilder.addBillInfo(contentList, "0", serviceReimbursement.getUsername(),
                        serviceReimbursement.getAmountrequested(), null,
                        FundNotifyMessageBuilder.billNo(serviceReimbursement.getBh(),
                                serviceReimbursement.getId()));
                FundNotifyMessageBuilder.addTravelInfo(contentList, serviceReimbursement.getTravelers(),
                        serviceReimbursement.getReason());
                FundNotifyMessageBuilder.addAuditResult(contentList, loginUser.getUser().getNickName(), new Date(),
                        FundNotifyMessageBuilder.opinion(FundNotifyMessageBuilder.CONCLUSION_REJECT,
                                checkFundVO.getFlowcontent()));
                try {
                    DingTalkReqVo dingTalkReqVo = new DingTalkReqVo();
                    dingTalkReqVo.setTitle("财务系统驳回信息");
                    dingTalkReqVo.setTitle(FundNotifyMessageBuilder.TITLE);
                    dingTalkReqVo.setNumber(sysUser.getPhonenumber());
                    dingTalkReqVo.setContents(contentList);
                    dingTalkService.sendNotification(dingTalkReqVo);
                }catch (Exception e){
                    log.error("差旅---财务系统驳回信息报错了", e);
                    log.error("差旅---审批未通过钉钉通知失败,id={}", serviceReimbursement.getId(), e);
                }
            }
@@ -515,8 +552,9 @@
                    log.info("差旅newSwitch返回的值为:{}", newSwitch);
                    aBoolean1 = sendData(serviceReimbursement);
                    if (!aBoolean1) {
                        allMap.put("500", "发送失败");
                        return allMap;
                        // 推送医院协友系统失败:整个审批不生效(事务回滚),允许下次重新审批
                        log.error("差旅审批单上传医院协友系统失败,审批不生效,id={},请重新审批", serviceReimbursement.getId());
                        throw new ServiceException("医院协友系统接收失败,本次审批未生效,请稍后重新审批");
                    }
                }
            }
@@ -585,7 +623,30 @@
        return "未找到审批记录";
    }
    /**
     * 审批单上传医院协友(致远)系统。
     *
     * <p>2026-10-09:外层包一层兜底,保证**任何异常都不会向外抛**(原来 strRes 为 null 时
     * 会在 parseObject 后取 code 触发 NPE,把整个审批请求打成 500)。
     * 返回 false 表示推送失败,调用方按"审批不生效、允许下次重新审批"处理。
     */
    public Boolean sendData(ServiceReimbursement serviceReimbursement) {
        if (!isUploadOaEnabled()) {
            // 上传开关关闭(如测试环境):跳过上传并视为成功,绝不能因此阻断审批
            log.info("审批单上传医院协友系统已关闭(sys.approval.upload.oa != 1),跳过上传并视为成功,id={}",
                    serviceReimbursement == null ? null : serviceReimbursement.getId());
            return true;
        }
        try {
            return doSendData(serviceReimbursement);
        } catch (Throwable t) {
            log.error("差旅审批单上传医院协友系统异常,审批不生效,id={}",
                    serviceReimbursement == null ? null : serviceReimbursement.getId(), t);
            return false;
        }
    }
    private Boolean doSendData(ServiceReimbursement serviceReimbursement) {
        // fund和funddetail的数据获取
        addSharedData(serviceReimbursement.getId());
        List<ServiceReimbursementShared> serviceReimbursementSharedList = sharedService.getRemShareInfoByRemId(serviceReimbursement.getId());
@@ -631,7 +692,7 @@
        data.put("summaryId", serviceReimbursement1.getSummaryId() == null ? "" : serviceReimbursement1.getSummaryId());
        map.put("data", data);
        String strRes = null;
        if (!active.equals("druid")) {
        if (isUploadOaEnabled()) {
            //如果是本地环境,就不调这个了
            String token = getToken();
            JSONObject json1 = JSONObject.parseObject(token);
@@ -662,9 +723,28 @@
            }
        }
        log.error("-----Reimbursement-------------strRes的值为:{}", strRes);
        JSONObject jsonObject = JSONObject.parseObject(strRes);
        if (strRes == null || strRes.trim().isEmpty()) {
            // 医院协友系统无返回(超时/异常/未配置):推送失败,由调用方回滚整个审批
            log.error("差旅审批单上传医院协友系统失败:接口无返回内容,id={}", serviceReimbursement.getId());
            return false;
        }
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(strRes);
        } catch (Exception e) {
            log.error("差旅审批单上传医院协友系统失败:返回内容无法解析,id={},strRes={}",
                    serviceReimbursement.getId(), strRes, e);
            return false;
        }
        if (jsonObject == null) {
            log.error("差旅审批单上传医院协友系统失败:返回内容为空,id={},strRes={}",
                    serviceReimbursement.getId(), strRes);
            return false;
        }
        String code = jsonObject.getString("code");
        if (!code.equals("0")) {
        if (code == null || !"0".equals(code)) {
            log.error("差旅审批单上传医院协友系统失败:code={},id={},strRes={}",
                    code, serviceReimbursement.getId(), strRes);
            return false;
        }
@@ -876,7 +956,7 @@
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userName", "opo");
        map.put("password", "4126407a-9821-4874-be41-6568abd6dbe5");
        map.put("loginName", "OPO系统");
        map.put("loginName", "OPO系统审批");
        JSONObject jsonObj = new JSONObject(map);