# Project Upload Page Light Redesign Frontend Implementation Plan

> **For agentic workers:** REQUIRED: Use superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** 将项目详情“上传数据”页调整为极简工作台布局，移除上传流水卡片，把“上传流水”作为右上角唯一主按钮，并保持现有上传弹窗与列表链路不变。

**Architecture:** 仅改 `UploadData.vue` 的模板结构、局部状态清理和样式表达，不改接口调用、不改业务判断、不改弹窗链路。先更新前端源码契约测试锁定目标布局，再做组件实现，最后补实施记录并完成回归验证。

**Tech Stack:** Vue 2, Element UI, SCSS, Node.js 源码契约测试

---

## 文件结构与职责

**修改文件**

- `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
  移除上传卡片结构，把上传流水入口并入头部按钮组，清理仅服务于卡片展示的状态与方法，重写头部和表格工作区样式。
- `ruoyi-ui/tests/unit/upload-data-header-import-button.test.js`
  将头部按钮顺序和主次样式的源码契约改为新布局目标。
- `ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js`
  将“卡片禁用”契约调整为“头部上传按钮禁用 + 卡片逻辑已清理”的新契约。
- `docs/reports/implementation/2026-03-25-project-upload-page-light-redesign-frontend-record.md`
  记录本次前端实施内容、验证命令和结果。

**参考文件**

- `docs/superpowers/specs/2026-03-25-project-upload-page-light-redesign-design.md`
- `ruoyi-ui/tests/unit/upload-data-batch-upload.test.js`
- `ruoyi-ui/tests/unit/upload-data-file-list-table.test.js`
- `ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js`

## Task 1: 先把源码契约改成目标布局

**Files:**
- Modify: `ruoyi-ui/tests/unit/upload-data-header-import-button.test.js`
- Modify: `ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js`
- Test: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`

- [ ] **Step 1: 改写头部按钮顺序测试为新目标**

在 `ruoyi-ui/tests/unit/upload-data-header-import-button.test.js` 中，把原有“查看报告优先、保留上传卡片”的断言改为以下目标：

```javascript
assert(
  /<div class="header-actions">[\s\S]*?@click="handleOpenBatchUploadDialog"[\s\S]*?>\s*上传流水\s*<\/el-button>[\s\S]*?@click="handleViewReport"[\s\S]*?>\s*查看报告\s*<\/el-button>[\s\S]*?@click="handleFetchBankInfo"[\s\S]*?>\s*拉取本行信息\s*<\/el-button>[\s\S]*?@click="handleGoCreditInfoPage"[\s\S]*?>\s*征信导入\s*<\/el-button>/.test(
    source
  ),
  "页面右上角按钮顺序应为上传流水、查看报告、拉取本行信息、征信导入"
);

assert(
  /<el-button[\s\S]*?type="primary"[\s\S]*?@click="handleOpenBatchUploadDialog"[\s\S]*?>\s*上传流水\s*<\/el-button>/.test(
    source
  ),
  "上传流水按钮应为头部唯一主按钮"
);

assert(
  !/uploadCards:/.test(source) && !/class="upload-cards"/.test(source),
  "上传卡片数据和模板应已清理"
);
```

- [ ] **Step 2: 改写禁用态测试到头部主按钮**

把 `ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js` 的断言改为校验：

```javascript
assert(
  /<el-button[\s\S]*?:disabled="isProjectTagging \|\| isProjectArchived"[\s\S]*?@click="handleOpenBatchUploadDialog"[\s\S]*?>\s*上传流水\s*<\/el-button>/.test(
    source
  ),
  "头部上传流水按钮应在项目打标中或已归档时禁用"
);

[
  "uploadCards:",
  "syncUploadCardDisabledState()",
  "handleUploadClick(key)",
  "class=\"upload-section\"",
].forEach((token) => {
  assert(!source.includes(token), `旧上传卡片逻辑未清理: ${token}`);
});
```

- [ ] **Step 3: 运行测试确认当前实现尚未满足**

Run:

```bash
node ruoyi-ui/tests/unit/upload-data-header-import-button.test.js
node ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js
```

Expected:

- FAIL，证明当前页面仍保留旧上传卡片结构，尚未完成轻改版。

## Task 2: 实现头部主按钮和页面结构收束

**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
- Test: `ruoyi-ui/tests/unit/upload-data-header-import-button.test.js`
- Test: `ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js`

- [ ] **Step 1: 在头部按钮组最前加入上传流水主按钮**

在 `header-actions` 中新增并前置按钮：

```vue
<el-button
  size="small"
  type="primary"
  icon="el-icon-upload2"
  :disabled="isProjectTagging || isProjectArchived"
  @click="handleOpenBatchUploadDialog"
>
  上传流水
</el-button>
```

保持其余按钮顺序为“查看报告 / 拉取本行信息 / 征信导入”。

- [ ] **Step 2: 删除上传流水卡片模板区**

移除以下模板块，不保留任何卡片容器：

```vue
<div class="upload-section">
  <div class="upload-cards">
    ...
  </div>
</div>
```

页面首屏在锁定提示之后直接进入记录表格区。

- [ ] **Step 3: 清理仅服务于上传卡片的状态与方法**

从 `UploadData.vue` 中删除或收敛以下内容：

```javascript
uploadStatusList: [],
uploadCards: [...],
metrics: [...],
```

```javascript
loadInitialData() {}
updateUploadCards() {}
syncUploadCardDisabledState() {}
updateQualityMetrics() {}
handleUploadClick(key) {}
```

同步清理不再使用的 `getUploadStatus` import、相关 watcher、created/mounted 中仅服务于卡片逻辑的调用。

- [ ] **Step 4: 用最小方法承接批量上传弹窗打开**

新增专用方法，复用现有弹窗状态：

```javascript
handleOpenBatchUploadDialog() {
  if (this.isProjectTagging || this.isProjectArchived) {
    return;
  }
  this.batchUploadDialogVisible = true;
  this.selectedFiles = [];
}
```

不要改动 `handleBatchUpload()`、文件校验、轮询与列表刷新链路。

- [ ] **Step 5: 重写头部和记录区样式，但不新增说明条**

在 `scoped` 样式中完成以下调整：

- 强化 `.content-header` 的整体感，让标题区与按钮区形成统一首屏
- 删除 `.upload-section`、`.upload-cards`、`.upload-card` 相关样式
- 提升 `.file-list-section` 的边框、圆角、留白和表格工作区完整度
- 保持锁定提示为独立信息条，但控制视觉重量
- 更新移动端布局，让按钮组换行后仍保持“上传流水”优先可见

- [ ] **Step 6: 运行契约测试确认通过**

Run:

```bash
node ruoyi-ui/tests/unit/upload-data-header-import-button.test.js
node ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js
```

Expected:

- PASS

## Task 3: 做定向回归，确保弹窗与表格不回归

**Files:**
- Test: `ruoyi-ui/tests/unit/upload-data-batch-upload.test.js`
- Test: `ruoyi-ui/tests/unit/upload-data-file-list-table.test.js`
- Test: `ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js`

- [ ] **Step 1: 回归批量上传弹窗结构**

Run:

```bash
node ruoyi-ui/tests/unit/upload-data-batch-upload.test.js
```

Expected:

- PASS，证明批量上传弹窗结构和限制文案未被破坏。

- [ ] **Step 2: 回归上传记录表格结构**

Run:

```bash
node ruoyi-ui/tests/unit/upload-data-file-list-table.test.js
```

Expected:

- PASS，证明文件列表主要列和表格结构保持不变。

- [ ] **Step 3: 回归征信导入入口仍为跳页**

Run:

```bash
node ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
```

Expected:

- PASS，证明本次调整没有把“征信导入”入口改回本地弹窗。

- [ ] **Step 4: 用源码检视确认旧卡片已彻底移除**

Run:

```bash
rg -n "uploadCards|handleUploadClick|upload-section|upload-cards|upload-card" ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
```

Expected:

- 无结果，或仅保留与本次新布局无关的注释清理提示；不应再残留旧卡片逻辑。

## Task 4: 补前端实施记录并提交

**Files:**
- Create: `docs/reports/implementation/2026-03-25-project-upload-page-light-redesign-frontend-record.md`

- [ ] **Step 1: 新增前端实施记录**

记录以下内容：

```markdown
# 上传数据页轻改版前端实施记录

## 本次改动
- 移除上传数据页中的上传流水卡片
- 将上传流水提升为右上角唯一主按钮
- 统一头部、锁定提示和文件记录区视觉

## 影响文件
- ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue
- ruoyi-ui/tests/unit/upload-data-header-import-button.test.js
- ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js

## 验证
- node ruoyi-ui/tests/unit/upload-data-header-import-button.test.js
- node ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js
- node ruoyi-ui/tests/unit/upload-data-batch-upload.test.js
- node ruoyi-ui/tests/unit/upload-data-file-list-table.test.js
- node ruoyi-ui/tests/unit/project-upload-credit-entry-jump.test.js
```

- [ ] **Step 2: 复核暂存区只包含本次前端相关文件**

Run:

```bash
git status --short
```

Expected:

- 仅暂存本次前端轻改版相关文件；若出现无关文件，先移出暂存区。

- [ ] **Step 3: 提交前端改动**

Run:

```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue \
  ruoyi-ui/tests/unit/upload-data-header-import-button.test.js \
  ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js \
  docs/reports/implementation/2026-03-25-project-upload-page-light-redesign-frontend-record.md
git commit -m "调整上传数据页轻改版前端实现"
```

Expected:

- PASS，提交信息为中文且仅包含本次前端改动。
