Selaa lähdekoodia

评估项目归档 与开票后的数据同步问题调整

徐滕 2 viikkoa sitten
vanhempi
commit
229d5c71bd
13 muutettua tiedostoa jossa 317 lisäystä ja 3 poistoa
  1. 8 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/mapper/FinanceInvoiceDetailMapper.java
  2. 19 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/mapper/xml/FinanceInvoiceDetailMapper.xml
  3. 47 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/service/FinanceInvoiceService.java
  4. 4 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/service/OMS/OMSDisposeService.java
  5. 12 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/domain/ProgramProjectListInfo.java
  6. 10 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/mapper/ProgramArchiveMapper.java
  7. 10 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/mapper/xml/ProgramArchiveMapper.xml
  8. 47 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/service/ProjectListService.java
  9. 127 1
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/controller/WorkContractController.java
  10. 6 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/domain/WorkContractInfo.java
  11. 6 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/mapper/WorkContractInfoMapper.java
  12. 12 2
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/mapper/xml/WorkContractInfoMapper.xml
  13. 9 0
      jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/service/WorkContractService.java

+ 8 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/mapper/FinanceInvoiceDetailMapper.java

@@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * @Entity generator.domain.FinanceInvoiceDetail
@@ -27,6 +28,13 @@ public interface FinanceInvoiceDetailMapper extends BaseMapper<FinanceInvoiceDet
      * @return
      */
     List<FinanceInvoiceDetailDTO> getInvoiceDetailByNumber(@Param("list") List<String> numberList);
+
+    /**
+     * 根据项目ID集合批量查询关联的发票号和发票ID
+     * @param programIds 项目ID集合
+     * @return 每条记录包含 programId, number(发票号), invoiceId(发票ID)
+     */
+    List<Map<String, String>> selectInvoiceInfoByProgramIds(@Param("programIds") List<String> programIds);
 }
 
 

+ 19 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/mapper/xml/FinanceInvoiceDetailMapper.xml

@@ -62,4 +62,23 @@
         </where>
     </select>
 
+    <!-- 根据项目ID集合批量查询关联的发票号和发票ID -->
+    <select id="selectInvoiceInfoByProgramIds" resultType="java.util.HashMap">
+        SELECT DISTINCT
+            fib.program_id AS programId,
+            fid.number AS number,
+            fid.invoice_id AS invoiceId
+        FROM finance_invoice_base fib
+        INNER JOIN finance_invoice fi ON fi.id = fib.invoice_id AND fi.del_flag = '0'
+        INNER JOIN finance_invoice_detail fid ON fid.invoice_id = fi.id AND fid.del_flag = 0
+        WHERE fib.del_flag = 0
+        AND fid.number IS NOT NULL AND fid.number != ''
+        <if test="programIds != null and programIds.size() > 0">
+            AND fib.program_id IN
+            <foreach collection="programIds" item="pid" open="(" separator="," close=")">
+                #{pid}
+            </foreach>
+        </if>
+    </select>
+
 </mapper>

+ 47 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/service/FinanceInvoiceService.java

@@ -17,6 +17,7 @@ import com.jeeplus.assess.invoice.thread.ApprovalThread;
 import com.jeeplus.assess.invoice.thread.RedApprovalThread;
 import com.jeeplus.assess.invoice.utils.DingTalkUtil;
 import com.jeeplus.assess.invoice.utils.OMS.FileHandlingUtil;
+import com.jeeplus.assess.program.configuration.projectList.mapper.ProgramArchiveMapper;
 import com.jeeplus.common.TokenProvider;
 import com.jeeplus.core.query.QueryWrapperGenerator;
 import com.jeeplus.flowable.feign.IFlowableApi;
@@ -78,6 +79,9 @@ public class FinanceInvoiceService extends ServiceImpl<FinanceInvoiceMapper, Fin
     @Resource
     private IFlowableApi flowTaskService;
 
+    @Resource
+    private ProgramArchiveMapper programArchiveMapper;
+
     @Value("${oms.omsEnabled}")
     private Boolean omsEnabled;
 
@@ -886,6 +890,12 @@ public class FinanceInvoiceService extends ServiceImpl<FinanceInvoiceMapper, Fin
                 addDingtalkNotice(dto);
             }
         }
+
+        // 先归档后开票场景:发票审核通过(status='5')且不走OMS时,自动更新关联项目的归档开票信息
+        if ("5".equals(financeInvoice.getStatus()) && "0".equals(isOms)) {
+            updateProjectArchiveByInvoiceId(financeInvoice.getId());
+        }
+
         return financeInvoice.getId();
     }
 
@@ -1516,6 +1526,9 @@ public class FinanceInvoiceService extends ServiceImpl<FinanceInvoiceMapper, Fin
         workInvoiceDetail.setNumber(invoiceInfo.getAllEinVno());
         financeInvoiceDetailMapper.updateNumberById(workInvoiceDetail);
 
+        // 先归档后开票场景:OMS开票完成后,自动更新关联项目的归档开票信息
+        updateProjectArchiveByInvoiceId(workInvoice.getId());
+
         //需要修改流程完成通知
         //审核完成提示框
         List<UserDTO> users = new ArrayList<>();
@@ -1860,4 +1873,38 @@ public class FinanceInvoiceService extends ServiceImpl<FinanceInvoiceMapper, Fin
         }
         return list;
     }
+
+    /**
+     * 根据发票id更新关联项目的归档开票信息
+     * 用于"先归档后开票"场景:发票完成(status='5')时,自动将关联项目的归档记录更新为已开票
+     * @param invoiceId 发票id
+     */
+    public void updateProjectArchiveByInvoiceId(String invoiceId) {
+        try {
+            List<FinanceInvoiceBase> baseList = financeInvoiceBaseMapper.selectList(
+                    new LambdaQueryWrapper<FinanceInvoiceBase>()
+                            .eq(FinanceInvoiceBase::getInvoiceId, invoiceId)
+                            .eq(FinanceInvoiceBase::getDelFlag, "0")
+            );
+            if (CollectionUtils.isEmpty(baseList)) {
+                return;
+            }
+            FinanceInvoice invoice = financeInvoiceMapper.selectById(invoiceId);
+            if (invoice == null || invoice.getBillingDate() == null) {
+                return;
+            }
+            Date billingDate = invoice.getBillingDate();
+            Set<String> processedProgramIds = new HashSet<>();
+            for (FinanceInvoiceBase base : baseList) {
+                String programId = base.getProgramId();
+                if (StringUtils.isNotBlank(programId) && !processedProgramIds.contains(programId)) {
+                    processedProgramIds.add(programId);
+                    programArchiveMapper.updateInvoiceInfoByProgramId(programId, billingDate);
+                }
+            }
+        } catch (Exception e) {
+            // 更新归档信息失败不影响主流程
+            e.printStackTrace();
+        }
+    }
 }

+ 4 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/invoice/service/OMS/OMSDisposeService.java

@@ -522,6 +522,10 @@ public class OMSDisposeService {
                 }
                 //修改结果
                 workInvoiceDao.updateAccessTokenErrorById(workInvoice);
+                // 先归档后开票场景:OMS返回"已开过票"时,自动更新关联项目的归档开票信息
+                if ("5".equals(workInvoice.getStatus())) {
+                    workInvoiceService.updateProjectArchiveByInvoiceId(workInvoiceId);
+                }
                 if (!"12".equals(workInvoice.getStatus())) {
                     //通知发起人或者开票管理员
                     workInvoiceService.handleInvoiceRetryAllFail(workInvoice, errorMessage, informType);

+ 12 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/domain/ProgramProjectListInfo.java

@@ -188,6 +188,18 @@ public class ProgramProjectListInfo extends BaseEntity {
     private String isInvoice;
 
     /**
+     * 关联发票号(逗号分隔,用于列表展示)
+     */
+    @TableField(exist = false)
+    private String invoiceNumbers;
+
+    /**
+     * 关联发票ID(逗号分隔,与invoiceNumbers一一对应,用于点击查看发票详情)
+     */
+    @TableField(exist = false)
+    private String invoiceIds;
+
+    /**
      * 项目报告号
      */
     @TableField(exist = false)

+ 10 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/mapper/ProgramArchiveMapper.java

@@ -5,6 +5,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.jeeplus.assess.program.configuration.projectList.domain.ProgramArchive;
 import com.jeeplus.assess.program.configuration.projectList.service.dto.ProgramArchiveDto;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
 
 /**
  * @Entity com.jeeplus.test.program.configuration.projectList.domain.ProgramArchive
@@ -28,6 +31,13 @@ public interface ProgramArchiveMapper extends BaseMapper<ProgramArchive> {
      * @return
      */
     ProgramArchiveDto findByProgramIdArchive(String id);
+
+    /**
+     * 根据项目id更新开票信息(先归档后开票场景)
+     * @param programId 项目id
+     * @param invoiceDate 开票日期
+     */
+    void updateInvoiceInfoByProgramId(@Param("programId") String programId, @Param("invoiceDate") Date invoiceDate);
 }
 
 

+ 10 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/mapper/xml/ProgramArchiveMapper.xml

@@ -195,4 +195,14 @@
         left join program_report_no prn on prn.program_id = pa.program_id and prn.del_flag = '0'
         where pa.del_flag = '0' and pa.program_id = #{id}
     </select>
+
+    <update id="updateInvoiceInfoByProgramId">
+        UPDATE program_archive
+        SET is_invoice = '1',
+            invoice_date = #{invoiceDate},
+            update_time = NOW()
+        WHERE program_id = #{programId}
+          AND del_flag = '0'
+          AND (is_invoice IS NULL OR is_invoice = '' OR is_invoice = '0')
+    </update>
 </mapper>

+ 47 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/program/configuration/projectList/service/ProjectListService.java

@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.assess.invoice.mapper.FinanceInvoiceDetailMapper;
 import com.jeeplus.assess.program.configuration.projectList.domain.*;
 import com.jeeplus.assess.program.configuration.projectList.mapper.*;
 import com.jeeplus.assess.program.configuration.projectList.service.dto.*;
@@ -105,6 +106,9 @@ public class ProjectListService {
 
     @Autowired
     private ProgramReportCancellationMapper reportCancellationMapper;
+
+    @Autowired
+    private FinanceInvoiceDetailMapper financeInvoiceDetailMapper;
 //    @Autowired
 //    private UserService userService;
 
@@ -961,6 +965,49 @@ public class ProjectListService {
             archiveStatusFlag = "1";
         }
         IPage<ProgramProjectListInfo> pageList = projectListMapper.findPageList(page, wrapper,userId,archiveStatusFlag);
+
+        // 批量查询项目关联的发票号和发票ID(一次SQL查询代替逐行查询,提升性能)
+        List<String> programIds = new ArrayList<>();
+        for (ProgramProjectListInfo item : pageList.getRecords()) {
+            programIds.add(item.getId());
+        }
+        Map<String, List<String[]>> invoiceInfoMap = new LinkedHashMap<>();
+        if (!programIds.isEmpty()) {
+            List<Map<String, String>> invoiceInfoList = financeInvoiceDetailMapper.selectInvoiceInfoByProgramIds(programIds);
+            for (Map<String, String> invInfo : invoiceInfoList) {
+                String pid = invInfo.get("programId");
+                String num = invInfo.get("number");
+                String invId = invInfo.get("invoiceId");
+                if (StringUtils.isNotBlank(pid) && StringUtils.isNotBlank(num)) {
+                    invoiceInfoMap.computeIfAbsent(pid, k -> new ArrayList<>()).add(new String[]{num, invId});
+                }
+            }
+        }
+        for (ProgramProjectListInfo item : pageList.getRecords()) {
+            List<String[]> invList = invoiceInfoMap.get(item.getId());
+            if (invList != null && !invList.isEmpty()) {
+                // 按发票ID分组,将同一发票下的所有发票号合并,确保number与invoiceId一一对应
+                Map<String, List<String>> invoiceNumberMap = new LinkedHashMap<>();
+                for (String[] pair : invList) {
+                    String number = pair[0];
+                    String invoiceId = pair[1];
+                    if (StringUtils.isNotBlank(invoiceId) && StringUtils.isNotBlank(number)) {
+                        invoiceNumberMap.computeIfAbsent(invoiceId, k -> new ArrayList<>()).add(number);
+                    }
+                }
+                List<String> numberList = new ArrayList<>();
+                List<String> idList = new ArrayList<>();
+                for (Map.Entry<String, List<String>> entry : invoiceNumberMap.entrySet()) {
+                    for (String num : entry.getValue()) {
+                        numberList.add(num);
+                        idList.add(entry.getKey());
+                    }
+                }
+                item.setInvoiceNumbers(String.join(",", numberList));
+                item.setInvoiceIds(String.join(",", idList));
+            }
+        }
+
         pageList.getRecords().stream().forEach(item ->{
             // 查询关联发票的开票状态
             if (StringUtils.isNotBlank(info.getShowInvoiceFlag()) && "1".equals(info.getShowInvoiceFlag())) {

+ 127 - 1
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/controller/WorkContractController.java

@@ -2,6 +2,9 @@ package com.jeeplus.assess.workContract.controller;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -13,17 +16,28 @@ import com.jeeplus.core.query.QueryWrapperGenerator;
 import com.jeeplus.assess.program.configuration.projectList.domain.ProgramProjectListInfo;
 import com.jeeplus.assess.workContract.domain.WorkContractInfo;
 import com.jeeplus.assess.workContract.service.WorkContractService;
+import com.jeeplus.assess.workContract.service.dto.WorkContractExportDTO;
 import com.jeeplus.assess.workContract.service.dto.WorkContractInfoDto;
+import com.jeeplus.assess.projectRecords.Utils.EasyPoiUtil;
+import com.jeeplus.common.excel.ExcelOptions;
+import com.jeeplus.common.excel.ExportMode;
+import com.jeeplus.sys.feign.IDictApi;
 import com.jeeplus.logging.annotation.ApiLog;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Api(tags ="合同登记")
@@ -58,6 +72,106 @@ public class WorkContractController {
     }
 
     /**
+     * 导出合同登记列表
+     * 复用列表查询条件,支持 全部(all)/当前页(current)/选中(selected) 三种导出模式
+     */
+    @ApiLog(value = "导出合同数据")
+    @ApiOperation(value = "导出合同数据")
+    @GetMapping(value = "export")
+    public void export(WorkContractInfo workClientInfo, Page<WorkContractInfo> page, ExcelOptions options, HttpServletResponse response) throws Exception {
+        String fileName = options.getFilename();
+        String sheetName = options.getSheetName();
+        // 构建与列表查询相同的过滤条件
+        String clientName = workClientInfo.getClientName();
+        String[] contractDates = workClientInfo.getContractDates();
+        String[] contractAmounts = workClientInfo.getContractAmounts();
+        String statusList = workClientInfo.getStatusList();
+        String status = workClientInfo.getStatus();
+        String contractType = workClientInfo.getContractType();
+        QueryWrapper<WorkContractInfo> queryWrapper = QueryWrapperGenerator.buildQueryCondition(workClientInfo, WorkContractInfo.class);
+        if (ObjectUtil.isNotEmpty(workClientInfo) && StringUtils.isNotBlank(workClientInfo.getCreateById())) {
+            queryWrapper.eq("a.create_by_id", workClientInfo.getCreateById()).or().like("c.name", workClientInfo.getCreateById());
+        }
+        if (StringUtils.isNotBlank(workClientInfo.getCancelStatus())) {
+            queryWrapper.eq("wcc.status", workClientInfo.getCancelStatus());
+        }
+        // 全部导出时取消分页
+        if (ExportMode.all.equals(options.getMode())) {
+            page.setSize(-1);
+            page.setCurrent(0);
+        }
+        List<WorkContractInfo> records = workContractService.list(page, queryWrapper, clientName, contractDates, contractAmounts, statusList, status, contractType, workClientInfo.getReportNo()).getRecords();
+        // 选中导出时按选中id过滤
+        if (ExportMode.selected.equals(options.getMode())) {
+            records = records.stream().filter(item -> options.getSelectIds().contains(item.getId())).collect(Collectors.toList());
+        }
+        // 加载状态字典,用于把状态码翻译为中文(含审批中/驳回/撤回等进行中状态)
+        Map<String, String> statusDict = loadDictMap("approval_type");
+        Map<String, String> filedDict = loadDictMap("filed_type");
+        Map<String, String> cancelDict = loadDictMap("contract_cancel");
+        // 转换为导出DTO
+        List<WorkContractExportDTO> result = new ArrayList<>();
+        for (WorkContractInfo info : records) {
+            WorkContractExportDTO dto = new WorkContractExportDTO();
+            BeanUtils.copyProperties(info, dto);
+            // 状态翻译:未发起的归档/作废给出默认文案,进行中/已完成按字典翻译
+            dto.setStatus(translateDict(statusDict, info.getStatus(), null));
+            dto.setFiledType(translateDict(filedDict, info.getFiledType(), "未归档"));
+            dto.setCancelStatus(translateDict(cancelDict, info.getCancelStatus(), "未作废"));
+            // 合同金额格式归一化:去掉千分位逗号,统一保留两位小数
+            dto.setContractAmount(formatAmount(info.getContractAmount()));
+            result.add(dto);
+        }
+        EasyPoiUtil.exportExcel(result, sheetName, sheetName, WorkContractExportDTO.class, fileName, response);
+    }
+
+    /**
+     * 加载字典 value->label 映射
+     * 使用 getDictListMapByDict(服务端直接返回 value->label 的Map JSON),
+     * 与报销模块导出的字典加载方式一致;getDictMap 返回的是带循环引用的对象列表JSON,解析不可靠
+     */
+    private Map<String, String> loadDictMap(String dict) {
+        Map<String, String> map = new HashMap<>();
+        String datas = SpringUtil.getBean(IDictApi.class).getDictListMapByDict(dict);
+        Map<String, Object> dictMap = JSON.parseObject(datas, new TypeReference<Map<String, Object>>() {});
+        if (dictMap != null) {
+            for (Map.Entry<String, Object> entry : dictMap.entrySet()) {
+                map.put(entry.getKey(), entry.getValue() == null ? null : String.valueOf(entry.getValue()));
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 状态码翻译为中文label;code为空时返回默认文案
+     */
+    private String translateDict(Map<String, String> dict, String code, String defaultLabel) {
+        if (StringUtils.isBlank(code)) {
+            return defaultLabel == null ? "" : defaultLabel;
+        }
+        String label = dict.get(code);
+        return StringUtils.isNotBlank(label) ? label : code;
+    }
+
+    /**
+     * 金额格式归一化:去掉千分位逗号,统一保留两位小数;空值返回空串
+     */
+    private String formatAmount(String amount) {
+        if (StringUtils.isBlank(amount)) {
+            return "";
+        }
+        try {
+            // 去掉千分位逗号
+            String clean = amount.replace(",", "");
+            java.math.BigDecimal bd = new java.math.BigDecimal(clean);
+            return bd.setScale(2, java.math.RoundingMode.HALF_UP).toPlainString();
+        } catch (Exception e) {
+            // 解析失败返回原值
+            return amount;
+        }
+    }
+
+    /**
      * 合同登记新增/修改
      */
     @ApiOperation(value = "合同登记新增/修改")
@@ -142,4 +256,16 @@ public class WorkContractController {
         workContractService.getThreeMonthsUnarchivedContracts();
     }
 
-}
+    /**
+     * 根据报告号查询项目ID
+     * @param reportNo 报告号
+     * @return 项目ID
+     */
+    @ApiOperation(value = "根据报告号查询项目ID")
+    @GetMapping("/getProjectIdByReportNo")
+    public ResponseEntity<String> getProjectIdByReportNo(@RequestParam("reportNo") String reportNo) {
+        String projectId = workContractService.getProjectIdByReportNo(reportNo);
+        return ResponseEntity.ok(projectId);
+    }
+
+}

+ 6 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/domain/WorkContractInfo.java

@@ -246,4 +246,10 @@ public class WorkContractInfo extends BaseEntity {
     @TableField(exist = false)
     private String reportNos;
 
+    /**
+     * 合同关联的项目名称(多个以逗号拼接)
+     */
+    @TableField(exist = false)
+    private String programNames;
+
 }

+ 6 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/mapper/WorkContractInfoMapper.java

@@ -82,5 +82,11 @@ public interface WorkContractInfoMapper extends BaseMapper<WorkContractInfo> {
      */
     List<WorkContractInfoDto> getThreeMonthsUnarchivedContracts();
 
+    /**
+     * 根据报告号查询项目ID
+     * @param reportNo 报告号
+     * @return 项目ID
+     */
+    String getProjectIdByReportNo(@Param("reportNo") String reportNo);
 
 }

+ 12 - 2
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/mapper/xml/WorkContractInfoMapper.xml

@@ -46,7 +46,9 @@
 			e.ID_ as task_filed_id,
 			g.ID_ as task_borrow_id,
 			-- 核心:拼接所有报告号,自动去重+逗号分隔
-			GROUP_CONCAT(DISTINCT prn.report_no SEPARATOR ',') AS reportNos
+			GROUP_CONCAT(DISTINCT prn.report_no SEPARATOR ',') AS reportNos,
+			-- 拼接报告号对应的项目名称,自动去重+逗号分隔
+			GROUP_CONCAT(DISTINCT IF(prn.report_no IS NOT NULL, ppli.name, NULL) SEPARATOR ',') AS programNames
 		FROM
 			work_contract_info a
 				LEFT JOIN sys_user c ON a.create_by_id = c.id
@@ -432,7 +434,15 @@
         AND wcc.status != '6'
         OR wcc.status IS NULL
     	)
-    	AND a.create_time &lt; DATE_SUB(NOW(), INTERVAL 3 MONTH)
+	    AND a.create_time &lt; DATE_SUB(NOW(), INTERVAL 3 MONTH)
 		</select>
 
+	<select id="getProjectIdByReportNo" resultType="string">
+		SELECT ppli.id
+		FROM program_report_no prn
+		LEFT JOIN program_project_list_info ppli ON prn.program_id = ppli.id AND ppli.del_flag = 0
+		WHERE prn.report_no = #{reportNo} AND prn.del_flag = 0
+		LIMIT 1
+	</select>
+
 </mapper>

+ 9 - 0
jeeplus-modules/jeeplus-assess/src/main/java/com/jeeplus/assess/workContract/service/WorkContractService.java

@@ -617,4 +617,13 @@ public class WorkContractService {
         SpringUtil.getBean ( IFlowableApi.class ).add(map);
     }
 
+    /**
+     * 根据报告号查询项目ID
+     * @param reportNo 报告号
+     * @return 项目ID
+     */
+    public String getProjectIdByReportNo(String reportNo) {
+        return workContractInfoMapper.getProjectIdByReportNo(reportNo);
+    }
+
 }