# 项目列表按产品分组：后端待确认事项与接口诉求

2026-06-10 · 前端发起 · 涉及模块：project/project（项目）、system/dict（字典）

## 0. 背景

项目列表页将从"平铺分页"改为"按所属产品聚合展示"：同一产品下的项目（基线/合同/技术支持等类型）需要聚拢在一起查看，不能被分页切散。现有 `GET /project/project/page` 平铺分页无法支撑该口径，需要后端补充以下能力。

前端已按本文档第 2~4 节的契约先行开发（过渡期用现有平铺接口在前端聚合模拟），后端接口就绪后联调切换，不阻塞后端排期，但请反馈预计时间点。

## 1. 待查询确认：rdms_project_type 字典数据 请尽快回复，阻塞前端一处常量

请提供字典 `rdms_project_type`（项目类型）的完整字典数据清单（每项的 value / label / 启用状态），特别是：

- "基线"类型对应的字典 value 是什么（前端需写入常量，用于"建立基线"入口预填与缺基线判定）；
- 除 基线 / 合同 / 技术支持 外是否还有其他在用类型值。

补充确认（口头已确认，烦请最终对齐）："基线项目每产品唯一"由后端在创建/更新项目时做唯一性校验兜底，前端仅做体验层提示。

## 2. 接口诉求一：项目按产品分组分页查询（新增） 核心依赖

### 2.1 建议路径

`GET /project/project/group-page`（路径可由后端按规范调整，前端只在 service 层适配一处）

数据权限口径与现有 `/project/project/page` 一致：只返回当前用户可见的项目，按其归属产品聚合。

### 2.2 入参

参数 | 类型 | 必填 | 说明
--- | --- | --- | ---
`pageNo` / `pageSize` | int | 是 | 产品组维度分页：一页返回 pageSize 个产品组（含组内项目），不是项目行分页。前端当前 pageSize=10。
`keyword` | string | 否 | 项目编码 / 名称模糊匹配（口径同现有 page 接口）。
`productId` | string | 否 | 限定单个产品。
`projectType` | string | 否 | 项目类型字典 value。
`statusCode` | string | 否 | 单状态过滤。不传 = "全部"口径：pending / active / paused / completed 四种状态，不含 cancelled / archived。
`orphanOnly` | boolean | 否 | true = 仅返回"游离组"（productId 为空的项目聚合为一个特殊组）。
`topN` | int | 否 | 每组返回的项目条数上限，建议默认 5（前端当前固定取 5）。

### 2.3 返回结构（示例）

    {
      "total": 12,            // 当前筛选口径下产品组总数（分页 total，含游离组）
      "projectTotal": 47,     // 当前筛选口径下项目总数
      "directionCount": 3,    // 可见产品去重后的方向（directionCode）数
      "orphanTotal": 3,       // 游离项目数（productId 为空）
      "list": [
        {
          "productId": "1923456789012345678",   // 字符串！见 4.1
          "productName": "智能网关",
          "productCode": "RDMS-P-001",
          "directionCode": "platform",
          "managerUserId": "1001",
          "managerUserNickname": "张三",
          "projectTotal": 6,                    // 当前筛选口径下该组项目总数
          "projects": [ /* 前 topN 条，字段同现有 page 接口的项目行 */ ],
          "typeCounts": { "baseline值": 1, "合同值": 3, "技术支持值": 2 },
          "hasBaseline": true,
          "orphan": false
        },
        {
          "productId": null,                    // 游离组：未挂产品的项目聚合
          "productName": "游离项目",
          "productCode": null,
          "directionCode": "",
          "managerUserId": null,
          "managerUserNickname": null,
          "projectTotal": 3,
          "projects": [ /* ... */ ],
          "typeCounts": { "合同值": 2, "技术支持值": 1 },
          "hasBaseline": false,
          "orphan": true
        }
      ]
    }

### 2.4 口径约定（关键，请逐条确认）

# | 约定 | 说明
--- | --- | ---
1 | 组内项目排序 | 按 `updateTime` 倒序，返回前 topN 条；`projectTotal` 为该口径下组内全量计数。
2 | 无命中组不返回 | 传了 `statusCode` / `keyword` / `projectType` 任一筛选时，组内无命中项目的产品组不返回。
3 | 零项目产品组 | "全部"口径（statusCode 缺省）且无 keyword / projectType 筛选时，返回当前用户可见、状态为 active / paused 的零项目产品组（projectTotal=0、projects=[]），用于"该产品暂无项目"占位与新增引导。
4 | typeCounts / hasBaseline 统计口径 | 这两个字段是"产品属性"，恒按"全部"口径（四种状态）统计，不随 statusCode 入参变化——避免"基线项目已完成时被误判为缺基线"。
5 | 游离组位置 | 游离组（productId 为空）作为列表中最后一个组返回；状态筛选下同样适用约定 2（无命中则不返回该组）。
6 | 组的排序 | 同方向（directionCode）的产品组相邻返回（方向间顺序、方向内产品顺序由后端按现有产品列表默认排序即可）。

### 2.5 组内"展开剩余"的数据来源

不需要新接口：前端用现有 `GET /project/project/page` 按 `productId + statusCode` 拉取该组剩余项目。前提是该接口的排序与本接口组内排序一致（updateTime 倒序）——若现有 page 接口默认排序不是 updateTime 倒序，请告知或支持排序参数。

## 3. 接口诉求二、三：存量接口小改 两处补充

### 3.1 平铺分页支持"未挂产品"筛选

`GET /project/project/page` 需要能表达 productId 为空的筛选语义（如新增 `orphanOnly=true` 参数，或约定 productId 传特殊值），用于查询"游离项目"（未关联任何产品的项目）。具体参数形式由后端定，前端适配。

### 3.2 概览统计补游离计数

`GET /project/project/overview-summary` 返回体增加：

    {
      "statusCounts": { "active": 10, "pending": 2, ... },  // 现有
      "orphanCount": 3                                       // 新增：未挂产品的项目数（按"全部"口径：四种状态）
    }

## 4. 公共约定

# | 约定 | 说明
--- | --- | ---
4.1 | ID 一律字符串 必须 | 所有 Long / 雪花 ID（productId、managerUserId、项目 id 等）在 JSON 中按字符串返回。Long 直接作为 JSON 数字返回会在前端丢精度。
4.2 | "全部"状态集合 | pending / active / paused / completed；cancelled / archived 仅在显式传对应 statusCode 时返回。
4.3 | 项目行字段 | 分组接口 `projects[]` 内的项目对象字段与现有 `/project/project/page` 返回行保持一致（含 productId / productName / managerUserNickname / progressRate / statusCode / updateTime 等），避免前端双口径。

## 5. 需要后端反馈的清单

1. 第 1 节：`rdms_project_type` 字典数据清单 + "基线"的 value（最优先，一条查询即可，阻塞前端一处常量）。
2. 第 2 节：分组分页接口的可行性确认 + 2.4 六条口径逐条确认（有异议请直接批注替代方案）+ 排期。
3. 第 3 节：page 接口游离筛选的参数形式 + overview-summary 补 orphanCount 的排期。
4. 第 2.5 节：现有 page 接口的默认排序是什么；是否支持/计划支持按 updateTime 倒序。