gaoluyang
7 小时以前 03965438c47dc6620bf5bf9ebb7ae97e805b4aae
fix(crm,mes): 客户转化统计漏行、归档台账分页与排序

- CRM 转化统计:receivable.deleted = 0 从 WHERE 挪到 LEFT JOIN 的 ON 条件,避免 LEFT JOIN 退化成 INNER JOIN、丢掉没有回款记录的合同
- MES 归档台账:Controller 签名里多余的 Page 参数会被 Spring 单独绑定成默认 1/10,前端 pageNo/pageSize 失效、翻页不动,改为按 pageReqVO 构造
- MES 归档台账:列表排序由 update_time DESC 改为 archive_time ASC, id ASC
- MES 归档详情:资料文件改从 system 模块附件中间表回填 attachmentList

Co-Authored-By: Claude Code <noreply@anthropic.com>
已修改4个文件
27 ■■■■■ 文件已修改
yudao-module-crm/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/archive/MesPdArchiveController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/archive/MesPdArchiveServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/resources/mapper/pd/archive/MesPdArchiveMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-crm/src/main/resources/mapper/statistics/CrmStatisticsCustomerMapper.xml
@@ -179,8 +179,10 @@
               IFNULL(receivable.price, 0) AS receivable_price
          FROM crm_customer AS customer
                INNER JOIN crm_contract AS contract ON customer.id = contract.customer_id
                LEFT JOIN crm_receivable AS receivable ON contract.id = receivable.contract_id
         WHERE customer.deleted = 0 AND contract.deleted = 0 AND receivable.deleted = 0
                <!-- receivable.deleted = 0 必须写在 ON 里:写到 WHERE 里会让 LEFT JOIN 退化成 INNER JOIN,
                     没有回款记录的合同会被整行丢掉(成交 6 个客户、转化表只出现 4 个) -->
                LEFT JOIN crm_receivable AS receivable ON contract.id = receivable.contract_id AND receivable.deleted = 0
         WHERE customer.deleted = 0 AND contract.deleted = 0
           AND contract.audit_status = ${@cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum@APPROVE.status}
           AND customer.owner_user_id IN
                <foreach collection="userIds" item="userId" open="(" close=")" separator=",">
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/archive/MesPdArchiveController.java
@@ -83,8 +83,10 @@
    @GetMapping("/page")
    @Operation(summary = "获得归档台账分页(按项目/产品聚合)")
    @PreAuthorize("@ss.hasPermission('mes:pd-archive:query')")
    public CommonResult<PageResult<MesPdArchiveRespVO>> getArchivePage(@Valid MesPdArchivePageReqVO pageReqVO,
                                                                        Page<MesPdArchiveGroupRespVO> page) {
    public CommonResult<PageResult<MesPdArchiveRespVO>> getArchivePage(@Valid MesPdArchivePageReqVO pageReqVO) {
        // 分页参数只能从 pageReqVO 取:签名里再放一个 Page 参数会被 Spring 单独按 current/size 绑定成默认的 1/10,
        // 前端传的 pageNo/pageSize 全被丢掉,台账就永远只返回前 10 条、翻页也不动(列表看不出从 9/17 往后的日期)。
        Page<MesPdArchiveGroupRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        IPage<MesPdArchiveGroupRespVO> archivePage = archiveService.getArchivePageGroupByProject(pageReqVO, page);
        return CommonResult.success(new PageResult<>(
                buildArchiveRespVOList(archivePage.getRecords()), archivePage.getTotal()));
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/archive/MesPdArchiveServiceImpl.java
@@ -13,6 +13,7 @@
import cn.iocoder.yudao.module.mes.dal.mysql.pd.archive.MesPdArchiveMapper;
import cn.iocoder.yudao.module.mes.service.pd.document.MesPdDocumentService;
import cn.iocoder.yudao.module.mes.service.pd.project.MesPdProjectService;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -52,6 +53,10 @@
    @Resource
    @Lazy
    private AdminUserApi adminUserApi;
    @Resource
    @Lazy
    private StorageAttachmentApi storageAttachmentApi;
    @Override
    public Long createArchive(MesPdArchiveSaveReqVO createReqVO) {
@@ -146,8 +151,12 @@
                Map<Long, AdminUserRespDTO> uploadUserMap = adminUserApi.getUserMap(
                        cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet(documents, MesPdDocumentDO::getUploadUserId));
                List<MesPdArchiveDetailRespVO.DocumentInfo> documentInfos = BeanUtils.toBean(documents, MesPdArchiveDetailRespVO.DocumentInfo.class,
                        info -> MapUtils.findAndThen(uploadUserMap, info.getUploadUserId(),
                                user -> info.setUploadUserNickname(user.getNickname())));
                        info -> {
                            MapUtils.findAndThen(uploadUserMap, info.getUploadUserId(),
                                    user -> info.setUploadUserNickname(user.getNickname()));
                            // 资料文件走 system 模块的附件中间表,业务表不存文件地址,这里回填才算能预览/下载
                            info.setAttachmentList(storageAttachmentApi.listAttachments("mes_pd_document", info.getId()));
                        });
                respVO.setDocuments(documentInfos);
            }
            mesPdArchiveDetailRespVOS.add(respVO);
yudao-module-mes/src/main/resources/mapper/pd/archive/MesPdArchiveMapper.xml
@@ -43,7 +43,7 @@
                AND a.archive_code LIKE CONCAT('%', #{req.archiveCode}, '%')
            </if>
        </where>
        ORDER BY a.update_time DESC
        ORDER BY a.archive_time ASC, a.id ASC
    </select>
</mapper>